blob: 8d8af522f68deefbf02bf01cfefee4d1f2605de4 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080019#include <stdlib.h>
20#include <stdint.h>
21#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080022#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080023
Mathias Agopiana67932f2011-04-20 14:20:59 -070024#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070025#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070026#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080027
28#include <utils/Errors.h>
29#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080030#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080031#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080032#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080033
Mathias Agopian3330b202009-10-05 17:07:12 -070034#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080035#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080036
Dan Stoza6b9454d2014-11-07 16:00:59 -080037#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080038#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039
40#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020041#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070042#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070044#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046
Mathias Agopian1b031492012-06-20 17:51:20 -070047#include "DisplayHardware/HWComposer.h"
48
Mathias Agopian875d8e12013-06-07 15:35:48 -070049#include "RenderEngine/RenderEngine.h"
50
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051#define DEBUG_RESIZE 0
52
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053namespace android {
54
55// ---------------------------------------------------------------------------
56
Mathias Agopian13127d82013-03-05 17:47:11 -080057int32_t Layer::sSequence = 1;
58
Mathias Agopian4d9b8222013-03-12 17:11:48 -070059Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
60 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080061 : contentDirty(false),
62 sequence(uint32_t(android_atomic_inc(&sSequence))),
63 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070064 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080065 mPremultipliedAlpha(true),
66 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070069 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080070 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070072 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070073 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080074 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080075 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080076 mFiltering(false),
77 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070078 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070079 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080080 mProtectedByApp(false),
81 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070082 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070083 mPotentialCursor(false),
84 mQueueItemLock(),
85 mQueueItemCondition(),
86 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070087 mLastFrameNumberReceived(0),
88 mUpdateTexImageFailed(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080089{
Mathias Agopiana67932f2011-04-20 14:20:59 -070090 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070091 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070092 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070093
94 uint32_t layerFlags = 0;
95 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080096 layerFlags |= layer_state_t::eLayerHidden;
97 if (flags & ISurfaceComposerClient::eOpaque)
98 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070099
100 if (flags & ISurfaceComposerClient::eNonPremultiplied)
101 mPremultipliedAlpha = false;
102
103 mName = name;
104
105 mCurrentState.active.w = w;
106 mCurrentState.active.h = h;
107 mCurrentState.active.crop.makeInvalid();
108 mCurrentState.z = 0;
109 mCurrentState.alpha = 0xFF;
110 mCurrentState.layerStack = 0;
111 mCurrentState.flags = layerFlags;
112 mCurrentState.sequence = 0;
113 mCurrentState.transform.set(0, 0);
114 mCurrentState.requested = mCurrentState.active;
115
116 // drawing state & current state are identical
117 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700118
119 nsecs_t displayPeriod =
120 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
121 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800122}
123
Mathias Agopian3f844832013-08-07 21:24:32 -0700124void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800125 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700126 sp<IGraphicBufferProducer> producer;
127 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700128 BufferQueue::createBufferQueue(&producer, &consumer);
129 mProducer = new MonitoredProducer(producer, mFlinger);
130 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800131 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800132 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700133 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800134
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700135#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
136#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800137 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700138#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800139 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800140#endif
Andy McFadden69052052012-09-14 16:10:11 -0700141
Mathias Agopian84300952012-11-21 16:02:13 -0800142 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
143 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700144}
145
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700146Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800147 sp<Client> c(mClientRef.promote());
148 if (c != 0) {
149 c->detachLayer(this);
150 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700151 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700152 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700153}
154
Mathias Agopian13127d82013-03-05 17:47:11 -0800155// ---------------------------------------------------------------------------
156// callbacks
157// ---------------------------------------------------------------------------
158
Dan Stozac7014012014-02-14 15:03:43 -0800159void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800160 HWComposer::HWCLayerInterface* layer) {
161 if (layer) {
162 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700163 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800164 }
165}
166
Dan Stoza6b9454d2014-11-07 16:00:59 -0800167void Layer::onFrameAvailable(const BufferItem& item) {
168 // Add this buffer from our internal queue tracker
169 { // Autolock scope
170 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700171
172 // Reset the frame number tracker when we receive the first buffer after
173 // a frame number reset
174 if (item.mFrameNumber == 1) {
175 mLastFrameNumberReceived = 0;
176 }
177
178 // Ensure that callbacks are handled in order
179 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
180 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
181 ms2ns(500));
182 if (result != NO_ERROR) {
183 ALOGE("[%s] Timed out waiting on callback", mName.string());
184 }
185 }
186
Dan Stoza6b9454d2014-11-07 16:00:59 -0800187 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700188 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700189
190 // Wake up any pending callbacks
191 mLastFrameNumberReceived = item.mFrameNumber;
192 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800193 }
194
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800195 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700196}
197
Dan Stoza6b9454d2014-11-07 16:00:59 -0800198void Layer::onFrameReplaced(const BufferItem& item) {
199 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700200
201 // Ensure that callbacks are handled in order
202 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
203 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
204 ms2ns(500));
205 if (result != NO_ERROR) {
206 ALOGE("[%s] Timed out waiting on callback", mName.string());
207 }
208 }
209
Dan Stoza6b9454d2014-11-07 16:00:59 -0800210 if (mQueueItems.empty()) {
211 ALOGE("Can't replace a frame on an empty queue");
212 return;
213 }
214 mQueueItems.editItemAt(0) = item;
Dan Stozaa4650a52015-05-12 12:56:16 -0700215
216 // Wake up any pending callbacks
217 mLastFrameNumberReceived = item.mFrameNumber;
218 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800219}
220
Jesse Hall399184a2014-03-03 15:42:54 -0800221void Layer::onSidebandStreamChanged() {
222 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
223 // mSidebandStreamChanged was false
224 mFlinger->signalLayerUpdate();
225 }
226}
227
Mathias Agopian67106042013-03-14 19:18:13 -0700228// called with SurfaceFlinger::mStateLock from the drawing thread after
229// the layer has been remove from the current state list (and just before
230// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800231void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800232 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700233}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700234
Mathias Agopian13127d82013-03-05 17:47:11 -0800235// ---------------------------------------------------------------------------
236// set-up
237// ---------------------------------------------------------------------------
238
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700239const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800240 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800241}
242
Mathias Agopianf9d93272009-06-19 17:00:27 -0700243status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800244 PixelFormat format, uint32_t flags)
245{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700246 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700247 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700248
249 // never allow a surface larger than what our underlying GL implementation
250 // can handle.
251 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800252 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700253 return BAD_VALUE;
254 }
255
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700256 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700257
Riley Andrews03414a12014-07-01 14:22:59 -0700258 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700259 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
260 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700261 mCurrentOpacity = getOpacityForFormat(format);
262
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800263 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
264 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
265 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700266
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800267 return NO_ERROR;
268}
269
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700270sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800271 Mutex::Autolock _l(mLock);
272
273 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700274 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800275
276 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700277
278 /*
279 * The layer handle is just a BBinder object passed to the client
280 * (remote process) -- we don't keep any reference on our side such that
281 * the dtor is called when the remote side let go of its reference.
282 *
283 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
284 * this layer when the handle is destroyed.
285 */
286
287 class Handle : public BBinder, public LayerCleaner {
288 wp<const Layer> mOwner;
289 public:
290 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
291 : LayerCleaner(flinger, layer), mOwner(layer) {
292 }
293 };
294
295 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800296}
297
Dan Stozab9b08832014-03-13 11:55:57 -0700298sp<IGraphicBufferProducer> Layer::getProducer() const {
299 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700300}
301
Mathias Agopian13127d82013-03-05 17:47:11 -0800302// ---------------------------------------------------------------------------
303// h/w composer set-up
304// ---------------------------------------------------------------------------
305
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800306Rect Layer::getContentCrop() const {
307 // this is the crop rectangle that applies to the buffer
308 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700309 Rect crop;
310 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800311 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700312 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800313 } else if (mActiveBuffer != NULL) {
314 // otherwise we use the whole buffer
315 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700316 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800317 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700318 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700319 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700320 return crop;
321}
322
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700323static Rect reduce(const Rect& win, const Region& exclude) {
324 if (CC_LIKELY(exclude.isEmpty())) {
325 return win;
326 }
327 if (exclude.isRect()) {
328 return win.reduce(exclude.getBounds());
329 }
330 return Region(win).subtract(exclude).getBounds();
331}
332
Mathias Agopian13127d82013-03-05 17:47:11 -0800333Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700334 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700335 return computeBounds(s.activeTransparentRegion);
336}
337
338Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
339 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800340 Rect win(s.active.w, s.active.h);
341 if (!s.active.crop.isEmpty()) {
342 win.intersect(s.active.crop, &win);
343 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700344 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700345 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800346}
347
Mathias Agopian6b442672013-07-09 21:24:52 -0700348FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800349 // the content crop is the area of the content that gets scaled to the
350 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700351 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800352
353 // the active.crop is the area of the window that gets cropped, but not
354 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700355 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800356
357 // apply the projection's clipping to the window crop in
358 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700359 // if there are no window scaling involved, this operation will map to full
360 // pixels in the buffer.
361 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
362 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700363
364 Rect activeCrop(s.active.w, s.active.h);
365 if (!s.active.crop.isEmpty()) {
366 activeCrop = s.active.crop;
367 }
368
369 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800370 activeCrop.intersect(hw->getViewport(), &activeCrop);
371 activeCrop = s.transform.inverse().transform(activeCrop);
372
Michael Lentine28ea2172014-11-19 18:32:37 -0800373 // This needs to be here as transform.transform(Rect) computes the
374 // transformed rect and then takes the bounding box of the result before
375 // returning. This means
376 // transform.inverse().transform(transform.transform(Rect)) != Rect
377 // in which case we need to make sure the final rect is clipped to the
378 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800379 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
380
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700381 // subtract the transparent region and snap to the bounds
382 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
383
Mathias Agopian13127d82013-03-05 17:47:11 -0800384 if (!activeCrop.isEmpty()) {
385 // Transform the window crop to match the buffer coordinate system,
386 // which means using the inverse of the current transform set on the
387 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700388 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700389 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
390 /*
391 * the code below applies the display's inverse transform to the buffer
392 */
393 uint32_t invTransformOrient = hw->getOrientationTransform();
394 // calculate the inverse transform
395 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
396 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
397 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700398 // If the transform has been rotated the axis of flip has been swapped
399 // so we need to swap which flip operations we are performing
400 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
401 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
402 if (is_h_flipped != is_v_flipped) {
403 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
404 NATIVE_WINDOW_TRANSFORM_FLIP_H;
405 }
Michael Lentinef7551402014-08-18 16:35:43 -0700406 }
407 // and apply to the current transform
408 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
409 }
410
Mathias Agopian13127d82013-03-05 17:47:11 -0800411 int winWidth = s.active.w;
412 int winHeight = s.active.h;
413 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700414 // If the activeCrop has been rotate the ends are rotated but not
415 // the space itself so when transforming ends back we can't rely on
416 // a modification of the axes of rotation. To account for this we
417 // need to reorient the inverse rotation in terms of the current
418 // axes of rotation.
419 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
420 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
421 if (is_h_flipped == is_v_flipped) {
422 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
423 NATIVE_WINDOW_TRANSFORM_FLIP_H;
424 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800425 winWidth = s.active.h;
426 winHeight = s.active.w;
427 }
428 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700429 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800430
Mathias Agopian6b442672013-07-09 21:24:52 -0700431 // below, crop is intersected with winCrop expressed in crop's coordinate space
432 float xScale = crop.getWidth() / float(winWidth);
433 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800434
Michael Lentinef7551402014-08-18 16:35:43 -0700435 float insetL = winCrop.left * xScale;
436 float insetT = winCrop.top * yScale;
437 float insetR = (winWidth - winCrop.right ) * xScale;
438 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800439
440 crop.left += insetL;
441 crop.top += insetT;
442 crop.right -= insetR;
443 crop.bottom -= insetB;
444 }
445 return crop;
446}
447
Mathias Agopian4fec8732012-06-29 14:12:52 -0700448void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700449 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700450 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700451{
Mathias Agopian13127d82013-03-05 17:47:11 -0800452 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700453
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700454 // enable this layer
455 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700456
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700457 if (isSecure() && !hw->isSecure()) {
458 layer.setSkip(true);
459 }
460
Mathias Agopian13127d82013-03-05 17:47:11 -0800461 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700462 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800463 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800464 layer.setBlending(mPremultipliedAlpha ?
465 HWC_BLENDING_PREMULT :
466 HWC_BLENDING_COVERAGE);
467 }
468
469 // apply the layer's transform, followed by the display's global transform
470 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700471 Region activeTransparentRegion(s.activeTransparentRegion);
472 if (!s.active.crop.isEmpty()) {
473 Rect activeCrop(s.active.crop);
474 activeCrop = s.transform.transform(activeCrop);
475 activeCrop.intersect(hw->getViewport(), &activeCrop);
476 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800477 // This needs to be here as transform.transform(Rect) computes the
478 // transformed rect and then takes the bounding box of the result before
479 // returning. This means
480 // transform.inverse().transform(transform.transform(Rect)) != Rect
481 // in which case we need to make sure the final rect is clipped to the
482 // display bounds.
483 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700484 // mark regions outside the crop as transparent
485 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
486 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
487 s.active.w, s.active.h));
488 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
489 activeCrop.left, activeCrop.bottom));
490 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
491 s.active.w, activeCrop.bottom));
492 }
493 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800494 frame.intersect(hw->getViewport(), &frame);
495 const Transform& tr(hw->getTransform());
496 layer.setFrame(tr.transform(frame));
497 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800498 layer.setPlaneAlpha(s.alpha);
499
Mathias Agopian29a367b2011-07-12 14:51:45 -0700500 /*
501 * Transformations are applied in this order:
502 * 1) buffer orientation/flip/mirror
503 * 2) state transformation (window manager)
504 * 3) layer orientation (screen orientation)
505 * (NOTE: the matrices are multiplied in reverse order)
506 */
507
508 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700509 Transform transform(tr * s.transform * bufferOrientation);
510
511 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
512 /*
513 * the code below applies the display's inverse transform to the buffer
514 */
515 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700516 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700517 // calculate the inverse transform
518 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
519 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
520 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700521 // If the transform has been rotated the axis of flip has been swapped
522 // so we need to swap which flip operations we are performing
523 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
524 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
525 if (is_h_flipped != is_v_flipped) {
526 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
527 NATIVE_WINDOW_TRANSFORM_FLIP_H;
528 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700529 }
530 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700531 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700532 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700533
534 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800535 const uint32_t orientation = transform.getOrientation();
536 if (orientation & Transform::ROT_INVALID) {
537 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700538 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700539 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800540 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700541 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700542}
543
Mathias Agopian42977342012-08-05 00:40:46 -0700544void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700545 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800546 // we have to set the visible region on every frame because
547 // we currently free it during onLayerDisplayed(), which is called
548 // after HWComposer::commit() -- every frame.
549 // Apply this display's projection's viewport to the visible region
550 // before giving it to the HWC HAL.
551 const Transform& tr = hw->getTransform();
552 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
553 layer.setVisibleRegionScreen(visible);
554
Dan Stozaee44edd2015-03-23 15:50:23 -0700555 // Pass full-surface damage down untouched
556 if (surfaceDamageRegion.isRect() &&
557 surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
558 layer.setSurfaceDamage(surfaceDamageRegion);
559 } else {
560 Region surfaceDamage =
561 tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
562 layer.setSurfaceDamage(surfaceDamage);
563 }
564
Jesse Hall399184a2014-03-03 15:42:54 -0800565 if (mSidebandStream.get()) {
566 layer.setSidebandStream(mSidebandStream);
567 } else {
568 // NOTE: buffer can be NULL if the client never drew into this
569 // layer yet, or if we ran out of memory
570 layer.setBuffer(mActiveBuffer);
571 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700572}
Jesse Halldc5b4852012-06-29 15:21:18 -0700573
Dan Stozac7014012014-02-14 15:03:43 -0800574void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700575 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700576 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700577
578 // TODO: there is a possible optimization here: we only need to set the
579 // acquire fence the first time a new buffer is acquired on EACH display.
580
Riley Andrews03414a12014-07-01 14:22:59 -0700581 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800582 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800583 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700584 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700585 if (fenceFd == -1) {
586 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
587 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700588 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700589 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700590 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700591}
592
Riley Andrews03414a12014-07-01 14:22:59 -0700593Rect Layer::getPosition(
594 const sp<const DisplayDevice>& hw)
595{
596 // this gives us only the "orientation" component of the transform
597 const State& s(getCurrentState());
598
599 // apply the layer's transform, followed by the display's global transform
600 // here we're guaranteed that the layer's transform preserves rects
601 Rect win(s.active.w, s.active.h);
602 if (!s.active.crop.isEmpty()) {
603 win.intersect(s.active.crop, &win);
604 }
605 // subtract the transparent region and snap to the bounds
606 Rect bounds = reduce(win, s.activeTransparentRegion);
607 Rect frame(s.transform.transform(bounds));
608 frame.intersect(hw->getViewport(), &frame);
609 const Transform& tr(hw->getTransform());
610 return Rect(tr.transform(frame));
611}
612
Mathias Agopian13127d82013-03-05 17:47:11 -0800613// ---------------------------------------------------------------------------
614// drawing...
615// ---------------------------------------------------------------------------
616
617void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800618 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800619}
620
Dan Stozac7014012014-02-14 15:03:43 -0800621void Layer::draw(const sp<const DisplayDevice>& hw,
622 bool useIdentityTransform) const {
623 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800624}
625
Dan Stozac7014012014-02-14 15:03:43 -0800626void Layer::draw(const sp<const DisplayDevice>& hw) const {
627 onDraw(hw, Region(hw->bounds()), false);
628}
629
630void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
631 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800632{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800633 ATRACE_CALL();
634
Mathias Agopiana67932f2011-04-20 14:20:59 -0700635 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800636 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700637 // in fact never been drawn into. This happens frequently with
638 // SurfaceView because the WindowManager can't know when the client
639 // has drawn the first time.
640
641 // If there is nothing under us, we paint the screen in black, otherwise
642 // we just skip this update.
643
644 // figure out if there is something below us
645 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700646 const SurfaceFlinger::LayerVector& drawingLayers(
647 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700648 const size_t count = drawingLayers.size();
649 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800650 const sp<Layer>& layer(drawingLayers[i]);
651 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700652 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700653 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700654 }
655 // if not everything below us is covered, we plug the holes!
656 Region holes(clip.subtract(under));
657 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700658 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700659 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800660 return;
661 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700662
Andy McFadden97eba892012-12-11 15:21:45 -0800663 // Bind the current buffer to the GL texture, and wait for it to be
664 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800665 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
666 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800667 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700668 // Go ahead and draw the buffer anyway; no matter what we do the screen
669 // is probably going to have something visibly wrong.
670 }
671
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700672 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
673
Mathias Agopian875d8e12013-06-07 15:35:48 -0700674 RenderEngine& engine(mFlinger->getRenderEngine());
675
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700676 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700677 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700678 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700679
680 // Query the texture matrix given our current filtering mode.
681 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800682 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
683 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700684
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700685 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
686
687 /*
688 * the code below applies the display's inverse transform to the texture transform
689 */
690
691 // create a 4x4 transform matrix from the display transform flags
692 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
693 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
694 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
695
696 mat4 tr;
697 uint32_t transform = hw->getOrientationTransform();
698 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
699 tr = tr * rot90;
700 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
701 tr = tr * flipH;
702 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
703 tr = tr * flipV;
704
705 // calculate the inverse
706 tr = inverse(tr);
707
708 // and finally apply it to the original texture matrix
709 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
710 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
711 }
712
Jamie Genniscbb1a952012-05-08 17:05:52 -0700713 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700714 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
715 mTexture.setFiltering(useFiltering);
716 mTexture.setMatrix(textureMatrix);
717
718 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700719 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700720 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700721 }
Dan Stozac7014012014-02-14 15:03:43 -0800722 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700723 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800724}
725
Mathias Agopian13127d82013-03-05 17:47:11 -0800726
Dan Stozac7014012014-02-14 15:03:43 -0800727void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
728 const Region& /* clip */, float red, float green, float blue,
729 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800730{
Mathias Agopian19733a32013-08-28 18:13:56 -0700731 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800732 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700733 engine.setupFillWithColor(red, green, blue, alpha);
734 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800735}
736
737void Layer::clearWithOpenGL(
738 const sp<const DisplayDevice>& hw, const Region& clip) const {
739 clearWithOpenGL(hw, clip, 0,0,0,0);
740}
741
Dan Stozac7014012014-02-14 15:03:43 -0800742void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
743 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700744 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800745
Dan Stozac7014012014-02-14 15:03:43 -0800746 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800747
Mathias Agopian13127d82013-03-05 17:47:11 -0800748 /*
749 * NOTE: the way we compute the texture coordinates here produces
750 * different results than when we take the HWC path -- in the later case
751 * the "source crop" is rounded to texel boundaries.
752 * This can produce significantly different results when the texture
753 * is scaled by a large amount.
754 *
755 * The GL code below is more logical (imho), and the difference with
756 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700757 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800758 * GL composition when a buffer scaling is applied (maybe with some
759 * minimal value)? Or, we could make GL behave like HWC -- but this feel
760 * like more of a hack.
761 */
762 const Rect win(computeBounds());
763
Mathias Agopian3f844832013-08-07 21:24:32 -0700764 float left = float(win.left) / float(s.active.w);
765 float top = float(win.top) / float(s.active.h);
766 float right = float(win.right) / float(s.active.w);
767 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800768
Mathias Agopian875d8e12013-06-07 15:35:48 -0700769 // TODO: we probably want to generate the texture coords with the mesh
770 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700771 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
772 texCoords[0] = vec2(left, 1.0f - top);
773 texCoords[1] = vec2(left, 1.0f - bottom);
774 texCoords[2] = vec2(right, 1.0f - bottom);
775 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800776
Mathias Agopian875d8e12013-06-07 15:35:48 -0700777 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800778 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700779 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700780 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800781}
782
Ruben Brunk1681d952014-06-27 15:51:55 -0700783uint32_t Layer::getProducerStickyTransform() const {
784 int producerStickyTransform = 0;
785 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
786 if (ret != OK) {
787 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
788 strerror(-ret), ret);
789 return 0;
790 }
791 return static_cast<uint32_t>(producerStickyTransform);
792}
793
Mathias Agopian13127d82013-03-05 17:47:11 -0800794void Layer::setFiltering(bool filtering) {
795 mFiltering = filtering;
796}
797
798bool Layer::getFiltering() const {
799 return mFiltering;
800}
801
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800802// As documented in libhardware header, formats in the range
803// 0x100 - 0x1FF are specific to the HAL implementation, and
804// are known to have no alpha channel
805// TODO: move definition for device-specific range into
806// hardware.h, instead of using hard-coded values here.
807#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
808
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700809bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700810 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
811 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800812 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700813 switch (format) {
814 case HAL_PIXEL_FORMAT_RGBA_8888:
815 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700816 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700817 }
818 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700819 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800820}
821
Mathias Agopian13127d82013-03-05 17:47:11 -0800822// ----------------------------------------------------------------------------
823// local state
824// ----------------------------------------------------------------------------
825
Dan Stozac7014012014-02-14 15:03:43 -0800826void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
827 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800828{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700829 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800830 const Transform tr(useIdentityTransform ?
831 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800832 const uint32_t hw_h = hw->getHeight();
833 Rect win(s.active.w, s.active.h);
834 if (!s.active.crop.isEmpty()) {
835 win.intersect(s.active.crop, &win);
836 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700837 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700838 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700839
Mathias Agopianff2ed702013-09-01 21:36:12 -0700840 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
841 position[0] = tr.transform(win.left, win.top);
842 position[1] = tr.transform(win.left, win.bottom);
843 position[2] = tr.transform(win.right, win.bottom);
844 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700845 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700846 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800847 }
848}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800849
Andy McFadden4125a4f2014-01-29 17:17:11 -0800850bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700851{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700852 // if we don't have a buffer yet, we're translucent regardless of the
853 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700854 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700855 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700856 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700857
858 // if the layer has the opaque flag, then we're always opaque,
859 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800860 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700861}
862
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800863bool Layer::isProtected() const
864{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700865 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800866 return (activeBuffer != 0) &&
867 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
868}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700869
Mathias Agopian13127d82013-03-05 17:47:11 -0800870bool Layer::isFixedSize() const {
871 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
872}
873
874bool Layer::isCropped() const {
875 return !mCurrentCrop.isEmpty();
876}
877
878bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
879 return mNeedsFiltering || hw->needsFiltering();
880}
881
882void Layer::setVisibleRegion(const Region& visibleRegion) {
883 // always called from main thread
884 this->visibleRegion = visibleRegion;
885}
886
887void Layer::setCoveredRegion(const Region& coveredRegion) {
888 // always called from main thread
889 this->coveredRegion = coveredRegion;
890}
891
892void Layer::setVisibleNonTransparentRegion(const Region&
893 setVisibleNonTransparentRegion) {
894 // always called from main thread
895 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
896}
897
898// ----------------------------------------------------------------------------
899// transaction
900// ----------------------------------------------------------------------------
901
902uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800903 ATRACE_CALL();
904
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700905 const Layer::State& s(getDrawingState());
906 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800907
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700908 const bool sizeChanged = (c.requested.w != s.requested.w) ||
909 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700910
911 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700912 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000913 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700914 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700915 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
916 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
917 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
918 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700919 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
920 c.active.w, c.active.h,
921 c.active.crop.left,
922 c.active.crop.top,
923 c.active.crop.right,
924 c.active.crop.bottom,
925 c.active.crop.getWidth(),
926 c.active.crop.getHeight(),
927 c.requested.w, c.requested.h,
928 c.requested.crop.left,
929 c.requested.crop.top,
930 c.requested.crop.right,
931 c.requested.crop.bottom,
932 c.requested.crop.getWidth(),
933 c.requested.crop.getHeight(),
934 s.active.w, s.active.h,
935 s.active.crop.left,
936 s.active.crop.top,
937 s.active.crop.right,
938 s.active.crop.bottom,
939 s.active.crop.getWidth(),
940 s.active.crop.getHeight(),
941 s.requested.w, s.requested.h,
942 s.requested.crop.left,
943 s.requested.crop.top,
944 s.requested.crop.right,
945 s.requested.crop.bottom,
946 s.requested.crop.getWidth(),
947 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800948
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700949 // record the new size, form this point on, when the client request
950 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800951 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700952 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800953 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700954
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700955 if (!isFixedSize()) {
956
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700957 const bool resizePending = (c.requested.w != c.active.w) ||
958 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700959
Dan Stoza9e9b0442015-04-22 14:59:08 -0700960 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800961 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700962 // if we have a pending resize, unless we are in fixed-size mode.
963 // the drawing state will be updated only once we receive a buffer
964 // with the correct size.
965 //
966 // in particular, we want to make sure the clip (which is part
967 // of the geometry state) is latched together with the size but is
968 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -0700969 //
970 // If a sideband stream is attached, however, we want to skip this
971 // optimization so that transactions aren't missed when a buffer
972 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700973
974 flags |= eDontUpdateGeometryState;
975 }
976 }
977
Mathias Agopian13127d82013-03-05 17:47:11 -0800978 // always set active to requested, unless we're asked not to
979 // this is used by Layer, which special cases resizes.
980 if (flags & eDontUpdateGeometryState) {
981 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700982 Layer::State& editCurrentState(getCurrentState());
983 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800984 }
985
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700986 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800987 // invalidate and recompute the visible regions if needed
988 flags |= Layer::eVisibleRegion;
989 }
990
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700991 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800992 // invalidate and recompute the visible regions if needed
993 flags |= eVisibleRegion;
994 this->contentDirty = true;
995
996 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700997 const uint8_t type = c.transform.getType();
998 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800999 (type >= Transform::SCALE));
1000 }
1001
1002 // Commit the transaction
1003 commitTransaction();
1004 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001005}
1006
Mathias Agopian13127d82013-03-05 17:47:11 -08001007void Layer::commitTransaction() {
1008 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001009}
1010
Mathias Agopian13127d82013-03-05 17:47:11 -08001011uint32_t Layer::getTransactionFlags(uint32_t flags) {
1012 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1013}
1014
1015uint32_t Layer::setTransactionFlags(uint32_t flags) {
1016 return android_atomic_or(flags, &mTransactionFlags);
1017}
1018
1019bool Layer::setPosition(float x, float y) {
1020 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1021 return false;
1022 mCurrentState.sequence++;
1023 mCurrentState.transform.set(x, y);
1024 setTransactionFlags(eTransactionNeeded);
1025 return true;
1026}
1027bool Layer::setLayer(uint32_t z) {
1028 if (mCurrentState.z == z)
1029 return false;
1030 mCurrentState.sequence++;
1031 mCurrentState.z = z;
1032 setTransactionFlags(eTransactionNeeded);
1033 return true;
1034}
1035bool Layer::setSize(uint32_t w, uint32_t h) {
1036 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1037 return false;
1038 mCurrentState.requested.w = w;
1039 mCurrentState.requested.h = h;
1040 setTransactionFlags(eTransactionNeeded);
1041 return true;
1042}
1043bool Layer::setAlpha(uint8_t alpha) {
1044 if (mCurrentState.alpha == alpha)
1045 return false;
1046 mCurrentState.sequence++;
1047 mCurrentState.alpha = alpha;
1048 setTransactionFlags(eTransactionNeeded);
1049 return true;
1050}
1051bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1052 mCurrentState.sequence++;
1053 mCurrentState.transform.set(
1054 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1055 setTransactionFlags(eTransactionNeeded);
1056 return true;
1057}
1058bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001059 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001060 setTransactionFlags(eTransactionNeeded);
1061 return true;
1062}
1063bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1064 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1065 if (mCurrentState.flags == newFlags)
1066 return false;
1067 mCurrentState.sequence++;
1068 mCurrentState.flags = newFlags;
1069 setTransactionFlags(eTransactionNeeded);
1070 return true;
1071}
1072bool Layer::setCrop(const Rect& crop) {
1073 if (mCurrentState.requested.crop == crop)
1074 return false;
1075 mCurrentState.sequence++;
1076 mCurrentState.requested.crop = crop;
1077 setTransactionFlags(eTransactionNeeded);
1078 return true;
1079}
1080
1081bool Layer::setLayerStack(uint32_t layerStack) {
1082 if (mCurrentState.layerStack == layerStack)
1083 return false;
1084 mCurrentState.sequence++;
1085 mCurrentState.layerStack = layerStack;
1086 setTransactionFlags(eTransactionNeeded);
1087 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001088}
1089
Dan Stozaee44edd2015-03-23 15:50:23 -07001090void Layer::useSurfaceDamage() {
1091 if (mFlinger->mForceFullDamage) {
1092 surfaceDamageRegion = Region::INVALID_REGION;
1093 } else {
1094 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1095 }
1096}
1097
1098void Layer::useEmptyDamage() {
1099 surfaceDamageRegion.clear();
1100}
1101
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001102// ----------------------------------------------------------------------------
1103// pageflip handling...
1104// ----------------------------------------------------------------------------
1105
Dan Stoza6b9454d2014-11-07 16:00:59 -08001106bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1107 Mutex::Autolock lock(mQueueItemLock);
1108 nsecs_t expectedPresent =
1109 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1110 return mQueueItems.empty() ?
1111 false : mQueueItems[0].mTimestamp < expectedPresent;
1112}
1113
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001114bool Layer::onPreComposition() {
1115 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001116 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001117}
1118
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001119void Layer::onPostComposition() {
1120 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001121 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001122 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1123
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001124 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001125 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001126 mFrameTracker.setFrameReadyFence(frameReadyFence);
1127 } else {
1128 // There was no fence for this frame, so assume that it was ready
1129 // to be presented at the desired present time.
1130 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1131 }
1132
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001133 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001134 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001135 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001136 mFrameTracker.setActualPresentFence(presentFence);
1137 } else {
1138 // The HWC doesn't support present fences, so use the refresh
1139 // timestamp instead.
1140 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1141 mFrameTracker.setActualPresentTime(presentTime);
1142 }
1143
1144 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001145 mFrameLatencyNeeded = false;
1146 }
1147}
1148
Mathias Agopianda27af92012-09-13 18:17:13 -07001149bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001150 const Layer::State& s(mDrawingState);
1151 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001152 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001153}
1154
Mathias Agopian4fec8732012-06-29 14:12:52 -07001155Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001156{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001157 ATRACE_CALL();
1158
Jesse Hall399184a2014-03-03 15:42:54 -08001159 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1160 // mSidebandStreamChanged was true
1161 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001162 if (mSidebandStream != NULL) {
1163 setTransactionFlags(eTransactionNeeded);
1164 mFlinger->setTransactionFlags(eTraversalNeeded);
1165 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001166 recomputeVisibleRegions = true;
1167
1168 const State& s(getDrawingState());
1169 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001170 }
1171
Mathias Agopian4fec8732012-06-29 14:12:52 -07001172 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001173 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001174
1175 // if we've already called updateTexImage() without going through
1176 // a composition step, we have to skip this layer at this point
1177 // because we cannot call updateTeximage() without a corresponding
1178 // compositionComplete() call.
1179 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001180 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001181 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001182 }
1183
Jamie Gennis351a5132011-09-14 18:23:37 -07001184 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001185 const State& s(getDrawingState());
1186 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001187 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001188
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001189 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001190 Layer::State& front;
1191 Layer::State& current;
1192 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001193 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001194 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001195 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001196 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001197 recomputeVisibleRegions(recomputeVisibleRegions),
1198 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001199 }
1200
1201 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001202 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001203 if (buf == NULL) {
1204 return false;
1205 }
1206
1207 uint32_t bufWidth = buf->getWidth();
1208 uint32_t bufHeight = buf->getHeight();
1209
1210 // check that we received a buffer of the right size
1211 // (Take the buffer's orientation into account)
1212 if (item.mTransform & Transform::ROT_90) {
1213 swap(bufWidth, bufHeight);
1214 }
1215
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001216 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1217 if (front.active != front.requested) {
1218
1219 if (isFixedSize ||
1220 (bufWidth == front.requested.w &&
1221 bufHeight == front.requested.h))
1222 {
1223 // Here we pretend the transaction happened by updating the
1224 // current and drawing states. Drawing state is only accessed
1225 // in this thread, no need to have it locked
1226 front.active = front.requested;
1227
1228 // We also need to update the current state so that
1229 // we don't end-up overwriting the drawing state with
1230 // this stale current state during the next transaction
1231 //
1232 // NOTE: We don't need to hold the transaction lock here
1233 // because State::active is only accessed from this thread.
1234 current.active = front.active;
1235
1236 // recompute visible region
1237 recomputeVisibleRegions = true;
1238 }
1239
1240 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001241 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001242 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1243 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001244 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001245 front.active.w, front.active.h,
1246 front.active.crop.left,
1247 front.active.crop.top,
1248 front.active.crop.right,
1249 front.active.crop.bottom,
1250 front.active.crop.getWidth(),
1251 front.active.crop.getHeight(),
1252 front.requested.w, front.requested.h,
1253 front.requested.crop.left,
1254 front.requested.crop.top,
1255 front.requested.crop.right,
1256 front.requested.crop.bottom,
1257 front.requested.crop.getWidth(),
1258 front.requested.crop.getHeight());
1259 }
1260
Ruben Brunk1681d952014-06-27 15:51:55 -07001261 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001262 if (front.active.w != bufWidth ||
1263 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001264 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001265 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1266 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001267 return true;
1268 }
1269 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001270
1271 // if the transparent region has changed (this test is
1272 // conservative, but that's fine, worst case we're doing
1273 // a bit of extra work), we latch the new one and we
1274 // trigger a visible-region recompute.
1275 if (!front.activeTransparentRegion.isTriviallyEqual(
1276 front.requestedTransparentRegion)) {
1277 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001278
1279 // We also need to update the current state so that
1280 // we don't end-up overwriting the drawing state with
1281 // this stale current state during the next transaction
1282 //
1283 // NOTE: We don't need to hold the transaction lock here
1284 // because State::active is only accessed from this thread.
1285 current.activeTransparentRegion = front.activeTransparentRegion;
1286
1287 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001288 recomputeVisibleRegions = true;
1289 }
1290
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001291 return false;
1292 }
1293 };
1294
Ruben Brunk1681d952014-06-27 15:51:55 -07001295 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1296 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001297
Dan Stozaa4650a52015-05-12 12:56:16 -07001298 uint64_t maxFrameNumber = 0;
1299 {
1300 Mutex::Autolock lock(mQueueItemLock);
1301 maxFrameNumber = mLastFrameNumberReceived;
1302 }
1303
Andy McFadden41d67d72014-04-25 16:58:34 -07001304 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Dan Stozaa4650a52015-05-12 12:56:16 -07001305 mFlinger->mPrimaryDispSync, maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001306 if (updateResult == BufferQueue::PRESENT_LATER) {
1307 // Producer doesn't want buffer to be displayed yet. Signal a
1308 // layer update so we check again at the next opportunity.
1309 mFlinger->signalLayerUpdate();
1310 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001311 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1312 // If the buffer has been rejected, remove it from the shadow queue
1313 // and return early
1314 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001315 mQueueItems.removeAt(0);
Dan Stozaecc50402015-04-28 14:42:06 -07001316 android_atomic_dec(&mQueuedFrames);
1317 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001318 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1319 // This can occur if something goes wrong when trying to create the
1320 // EGLImage for this buffer. If this happens, the buffer has already
1321 // been released, so we need to clean up the queue and bug out
1322 // early.
1323 {
1324 Mutex::Autolock lock(mQueueItemLock);
1325 mQueueItems.clear();
1326 android_atomic_and(0, &mQueuedFrames);
1327 }
1328
1329 // Once we have hit this state, the shadow queue may no longer
1330 // correctly reflect the incoming BufferQueue's contents, so even if
1331 // updateTexImage starts working, the only safe course of action is
1332 // to continue to ignore updates.
1333 mUpdateTexImageFailed = true;
1334
1335 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001336 }
1337
Dan Stoza6b9454d2014-11-07 16:00:59 -08001338 { // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001339 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1340
Dan Stoza6b9454d2014-11-07 16:00:59 -08001341 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001342
1343 // Remove any stale buffers that have been dropped during
1344 // updateTexImage
1345 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1346 mQueueItems.removeAt(0);
1347 android_atomic_dec(&mQueuedFrames);
1348 }
1349
Dan Stoza6b9454d2014-11-07 16:00:59 -08001350 mQueueItems.removeAt(0);
1351 }
1352
Dan Stozaecc50402015-04-28 14:42:06 -07001353
Andy McFadden1585c4d2013-06-28 13:52:40 -07001354 // Decrement the queued-frames count. Signal another event if we
1355 // have more frames pending.
1356 if (android_atomic_dec(&mQueuedFrames) > 1) {
1357 mFlinger->signalLayerUpdate();
1358 }
1359
1360 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001361 // something happened!
1362 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001363 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001364 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001365
Jamie Gennis351a5132011-09-14 18:23:37 -07001366 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001367 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001368 if (mActiveBuffer == NULL) {
1369 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001370 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001371 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001372
Mathias Agopian4824d402012-06-04 18:16:30 -07001373 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001374 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001375 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001376 // the first time we receive a buffer, we need to trigger a
1377 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001378 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001379 }
1380
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001381 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1382 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1383 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001384 if ((crop != mCurrentCrop) ||
1385 (transform != mCurrentTransform) ||
1386 (scalingMode != mCurrentScalingMode))
1387 {
1388 mCurrentCrop = crop;
1389 mCurrentTransform = transform;
1390 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001391 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001392 }
1393
1394 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001395 uint32_t bufWidth = mActiveBuffer->getWidth();
1396 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001397 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1398 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001399 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001400 }
1401 }
1402
1403 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001404 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001405 recomputeVisibleRegions = true;
1406 }
1407
Mathias Agopian4fec8732012-06-29 14:12:52 -07001408 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001409 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001410
1411 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001412 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001413 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001414 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001415}
1416
Mathias Agopiana67932f2011-04-20 14:20:59 -07001417uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001418{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001419 // TODO: should we do something special if mSecure is set?
1420 if (mProtectedByApp) {
1421 // need a hardware-protected path to external video sink
1422 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001423 }
Riley Andrews03414a12014-07-01 14:22:59 -07001424 if (mPotentialCursor) {
1425 usage |= GraphicBuffer::USAGE_CURSOR;
1426 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001427 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001428 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001429}
1430
Mathias Agopian84300952012-11-21 16:02:13 -08001431void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001432 uint32_t orientation = 0;
1433 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001434 // The transform hint is used to improve performance, but we can
1435 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001436 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001437 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001438 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001439 if (orientation & Transform::ROT_INVALID) {
1440 orientation = 0;
1441 }
1442 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001443 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001444}
1445
Mathias Agopian13127d82013-03-05 17:47:11 -08001446// ----------------------------------------------------------------------------
1447// debugging
1448// ----------------------------------------------------------------------------
1449
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001450void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001451{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001452 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001453
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001454 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001455 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001456 "+ %s %p (%s)\n",
1457 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001458 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001459
Mathias Agopian2ca79392013-04-02 18:30:32 -07001460 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001461 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001462 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001463 sp<Client> client(mClientRef.promote());
1464
Mathias Agopian74d211a2013-04-22 16:55:35 +02001465 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001466 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1467 "isOpaque=%1d, invalidate=%1d, "
1468 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1469 " client=%p\n",
1470 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1471 s.active.crop.left, s.active.crop.top,
1472 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001473 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001474 s.alpha, s.flags,
1475 s.transform[0][0], s.transform[0][1],
1476 s.transform[1][0], s.transform[1][1],
1477 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001478
1479 sp<const GraphicBuffer> buf0(mActiveBuffer);
1480 uint32_t w0=0, h0=0, s0=0, f0=0;
1481 if (buf0 != 0) {
1482 w0 = buf0->getWidth();
1483 h0 = buf0->getHeight();
1484 s0 = buf0->getStride();
1485 f0 = buf0->format;
1486 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001487 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001488 " "
1489 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1490 " queued-frames=%d, mRefreshPending=%d\n",
1491 mFormat, w0, h0, s0,f0,
1492 mQueuedFrames, mRefreshPending);
1493
Mathias Agopian13127d82013-03-05 17:47:11 -08001494 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001495 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001496 }
1497}
1498
Svetoslavd85084b2014-03-20 10:28:31 -07001499void Layer::dumpFrameStats(String8& result) const {
1500 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001501}
1502
Svetoslavd85084b2014-03-20 10:28:31 -07001503void Layer::clearFrameStats() {
1504 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001505}
1506
Jamie Gennis6547ff42013-07-16 20:12:42 -07001507void Layer::logFrameStats() {
1508 mFrameTracker.logAndResetStats(mName);
1509}
1510
Svetoslavd85084b2014-03-20 10:28:31 -07001511void Layer::getFrameStats(FrameStats* outStats) const {
1512 mFrameTracker.getStats(outStats);
1513}
1514
Mathias Agopian13127d82013-03-05 17:47:11 -08001515// ---------------------------------------------------------------------------
1516
1517Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1518 const sp<Layer>& layer)
1519 : mFlinger(flinger), mLayer(layer) {
1520}
1521
1522Layer::LayerCleaner::~LayerCleaner() {
1523 // destroy client resources
1524 mFlinger->onLayerDestroyed(mLayer);
1525}
1526
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001527// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001528}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001529
1530#if defined(__gl_h_)
1531#error "don't include gl/gl.h in this file"
1532#endif
1533
1534#if defined(__gl2_h_)
1535#error "don't include gl2/gl2.h in this file"
1536#endif