blob: d4847080c651d022bc58ebcf29378fd0b80bb172 [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),
Dan Stoza7dde5992015-05-22 09:51:44 -070069 mPendingStateMutex(),
70 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080072 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070073 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070074 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070075 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080076 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080077 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080078 mFiltering(false),
79 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070080 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080081 mProtectedByApp(false),
82 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070083 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070084 mPotentialCursor(false),
85 mQueueItemLock(),
86 mQueueItemCondition(),
87 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070088 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080089 mUpdateTexImageFailed(false),
90 mSingleBufferMode(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080091{
Mathias Agopiana67932f2011-04-20 14:20:59 -070092 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070093 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070094 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070095
96 uint32_t layerFlags = 0;
97 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080098 layerFlags |= layer_state_t::eLayerHidden;
99 if (flags & ISurfaceComposerClient::eOpaque)
100 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700101 if (flags & ISurfaceComposerClient::eSecure)
102 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700103
104 if (flags & ISurfaceComposerClient::eNonPremultiplied)
105 mPremultipliedAlpha = false;
106
107 mName = name;
108
109 mCurrentState.active.w = w;
110 mCurrentState.active.h = h;
111 mCurrentState.active.crop.makeInvalid();
112 mCurrentState.z = 0;
113 mCurrentState.alpha = 0xFF;
114 mCurrentState.layerStack = 0;
115 mCurrentState.flags = layerFlags;
116 mCurrentState.sequence = 0;
117 mCurrentState.transform.set(0, 0);
118 mCurrentState.requested = mCurrentState.active;
119
120 // drawing state & current state are identical
121 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700122
123 nsecs_t displayPeriod =
124 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
125 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800126}
127
Mathias Agopian3f844832013-08-07 21:24:32 -0700128void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800129 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700130 sp<IGraphicBufferProducer> producer;
131 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700132 BufferQueue::createBufferQueue(&producer, &consumer);
133 mProducer = new MonitoredProducer(producer, mFlinger);
134 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800135 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800136 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700137 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800138
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700139#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
140#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700141#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700142 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800143#endif
Andy McFadden69052052012-09-14 16:10:11 -0700144
Mathias Agopian84300952012-11-21 16:02:13 -0800145 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
146 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700147}
148
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700149Layer::~Layer() {
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700150 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700151 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700152}
153
Mathias Agopian13127d82013-03-05 17:47:11 -0800154// ---------------------------------------------------------------------------
155// callbacks
156// ---------------------------------------------------------------------------
157
Dan Stozac7014012014-02-14 15:03:43 -0800158void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800159 HWComposer::HWCLayerInterface* layer) {
160 if (layer) {
161 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700162 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800163 }
164}
165
Dan Stoza7dde5992015-05-22 09:51:44 -0700166void Layer::markSyncPointsAvailable(const BufferItem& item) {
167 auto pointIter = mLocalSyncPoints.begin();
168 while (pointIter != mLocalSyncPoints.end()) {
169 if ((*pointIter)->getFrameNumber() == item.mFrameNumber) {
170 auto syncPoint = *pointIter;
171 pointIter = mLocalSyncPoints.erase(pointIter);
172 Mutex::Autolock lock(mAvailableFrameMutex);
173 mAvailableFrames.push_back(std::move(syncPoint));
174 } else {
175 ++pointIter;
176 }
177 }
178}
179
Dan Stoza6b9454d2014-11-07 16:00:59 -0800180void Layer::onFrameAvailable(const BufferItem& item) {
181 // Add this buffer from our internal queue tracker
182 { // Autolock scope
183 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700184
185 // Reset the frame number tracker when we receive the first buffer after
186 // a frame number reset
187 if (item.mFrameNumber == 1) {
188 mLastFrameNumberReceived = 0;
189 }
190
191 // Ensure that callbacks are handled in order
192 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
193 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
194 ms2ns(500));
195 if (result != NO_ERROR) {
196 ALOGE("[%s] Timed out waiting on callback", mName.string());
197 }
198 }
199
Dan Stoza6b9454d2014-11-07 16:00:59 -0800200 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700201 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700202
203 // Wake up any pending callbacks
204 mLastFrameNumberReceived = item.mFrameNumber;
205 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800206 }
207
Dan Stoza7dde5992015-05-22 09:51:44 -0700208 markSyncPointsAvailable(item);
209
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800210 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700211}
212
Dan Stoza6b9454d2014-11-07 16:00:59 -0800213void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700214 { // Autolock scope
215 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700216
Dan Stoza7dde5992015-05-22 09:51:44 -0700217 // Ensure that callbacks are handled in order
218 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
219 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
220 ms2ns(500));
221 if (result != NO_ERROR) {
222 ALOGE("[%s] Timed out waiting on callback", mName.string());
223 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700224 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700225
226 if (mQueueItems.empty()) {
227 ALOGE("Can't replace a frame on an empty queue");
228 return;
229 }
230 mQueueItems.editItemAt(0) = item;
231
232 // Wake up any pending callbacks
233 mLastFrameNumberReceived = item.mFrameNumber;
234 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700235 }
236
Dan Stoza7dde5992015-05-22 09:51:44 -0700237 markSyncPointsAvailable(item);
Dan Stoza6b9454d2014-11-07 16:00:59 -0800238}
239
Jesse Hall399184a2014-03-03 15:42:54 -0800240void Layer::onSidebandStreamChanged() {
241 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
242 // mSidebandStreamChanged was false
243 mFlinger->signalLayerUpdate();
244 }
245}
246
Mathias Agopian67106042013-03-14 19:18:13 -0700247// called with SurfaceFlinger::mStateLock from the drawing thread after
248// the layer has been remove from the current state list (and just before
249// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800250void Layer::onRemoved() {
Pablo Ceballose338df12015-12-03 11:44:46 -0800251 sp<Client> c(mClientRef.promote());
252 if (c != 0) {
253 c->detachLayer(this);
254 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800255 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700256}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700257
Mathias Agopian13127d82013-03-05 17:47:11 -0800258// ---------------------------------------------------------------------------
259// set-up
260// ---------------------------------------------------------------------------
261
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700262const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800263 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800264}
265
Mathias Agopianf9d93272009-06-19 17:00:27 -0700266status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800267 PixelFormat format, uint32_t flags)
268{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700269 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700270 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700271
272 // never allow a surface larger than what our underlying GL implementation
273 // can handle.
274 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800275 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700276 return BAD_VALUE;
277 }
278
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700279 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700280
Riley Andrews03414a12014-07-01 14:22:59 -0700281 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700282 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700283 mCurrentOpacity = getOpacityForFormat(format);
284
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800285 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
286 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
287 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700288
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800289 return NO_ERROR;
290}
291
Dan Stoza7dde5992015-05-22 09:51:44 -0700292/*
293 * The layer handle is just a BBinder object passed to the client
294 * (remote process) -- we don't keep any reference on our side such that
295 * the dtor is called when the remote side let go of its reference.
296 *
297 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
298 * this layer when the handle is destroyed.
299 */
300class Layer::Handle : public BBinder, public LayerCleaner {
301 public:
302 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
303 : LayerCleaner(flinger, layer), owner(layer) {}
304
305 wp<Layer> owner;
306};
307
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700308sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800309 Mutex::Autolock _l(mLock);
310
311 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700312 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800313
314 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700315
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700316 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800317}
318
Dan Stozab9b08832014-03-13 11:55:57 -0700319sp<IGraphicBufferProducer> Layer::getProducer() const {
320 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700321}
322
Mathias Agopian13127d82013-03-05 17:47:11 -0800323// ---------------------------------------------------------------------------
324// h/w composer set-up
325// ---------------------------------------------------------------------------
326
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800327Rect Layer::getContentCrop() const {
328 // this is the crop rectangle that applies to the buffer
329 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700330 Rect crop;
331 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800332 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700333 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800334 } else if (mActiveBuffer != NULL) {
335 // otherwise we use the whole buffer
336 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700337 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800338 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700339 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700340 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700341 return crop;
342}
343
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700344static Rect reduce(const Rect& win, const Region& exclude) {
345 if (CC_LIKELY(exclude.isEmpty())) {
346 return win;
347 }
348 if (exclude.isRect()) {
349 return win.reduce(exclude.getBounds());
350 }
351 return Region(win).subtract(exclude).getBounds();
352}
353
Mathias Agopian13127d82013-03-05 17:47:11 -0800354Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700355 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700356 return computeBounds(s.activeTransparentRegion);
357}
358
359Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
360 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800361 Rect win(s.active.w, s.active.h);
362 if (!s.active.crop.isEmpty()) {
363 win.intersect(s.active.crop, &win);
364 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700365 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700366 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800367}
368
Mathias Agopian6b442672013-07-09 21:24:52 -0700369FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800370 // the content crop is the area of the content that gets scaled to the
371 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700372 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800373
374 // the active.crop is the area of the window that gets cropped, but not
375 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700376 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800377
378 // apply the projection's clipping to the window crop in
379 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700380 // if there are no window scaling involved, this operation will map to full
381 // pixels in the buffer.
382 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
383 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700384
385 Rect activeCrop(s.active.w, s.active.h);
386 if (!s.active.crop.isEmpty()) {
387 activeCrop = s.active.crop;
388 }
389
390 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800391 activeCrop.intersect(hw->getViewport(), &activeCrop);
392 activeCrop = s.transform.inverse().transform(activeCrop);
393
Michael Lentine28ea2172014-11-19 18:32:37 -0800394 // This needs to be here as transform.transform(Rect) computes the
395 // transformed rect and then takes the bounding box of the result before
396 // returning. This means
397 // transform.inverse().transform(transform.transform(Rect)) != Rect
398 // in which case we need to make sure the final rect is clipped to the
399 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800400 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
401
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700402 // subtract the transparent region and snap to the bounds
403 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
404
Mathias Agopian13127d82013-03-05 17:47:11 -0800405 if (!activeCrop.isEmpty()) {
406 // Transform the window crop to match the buffer coordinate system,
407 // which means using the inverse of the current transform set on the
408 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700409 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700410 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
411 /*
412 * the code below applies the display's inverse transform to the buffer
413 */
414 uint32_t invTransformOrient = hw->getOrientationTransform();
415 // calculate the inverse transform
416 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
417 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
418 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700419 // If the transform has been rotated the axis of flip has been swapped
420 // so we need to swap which flip operations we are performing
421 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
422 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
423 if (is_h_flipped != is_v_flipped) {
424 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
425 NATIVE_WINDOW_TRANSFORM_FLIP_H;
426 }
Michael Lentinef7551402014-08-18 16:35:43 -0700427 }
428 // and apply to the current transform
429 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
430 }
431
Mathias Agopian13127d82013-03-05 17:47:11 -0800432 int winWidth = s.active.w;
433 int winHeight = s.active.h;
434 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700435 // If the activeCrop has been rotate the ends are rotated but not
436 // the space itself so when transforming ends back we can't rely on
437 // a modification of the axes of rotation. To account for this we
438 // need to reorient the inverse rotation in terms of the current
439 // axes of rotation.
440 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
441 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
442 if (is_h_flipped == is_v_flipped) {
443 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
444 NATIVE_WINDOW_TRANSFORM_FLIP_H;
445 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800446 winWidth = s.active.h;
447 winHeight = s.active.w;
448 }
449 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700450 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800451
Mathias Agopian6b442672013-07-09 21:24:52 -0700452 // below, crop is intersected with winCrop expressed in crop's coordinate space
453 float xScale = crop.getWidth() / float(winWidth);
454 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800455
Michael Lentinef7551402014-08-18 16:35:43 -0700456 float insetL = winCrop.left * xScale;
457 float insetT = winCrop.top * yScale;
458 float insetR = (winWidth - winCrop.right ) * xScale;
459 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800460
461 crop.left += insetL;
462 crop.top += insetT;
463 crop.right -= insetR;
464 crop.bottom -= insetB;
465 }
466 return crop;
467}
468
Mathias Agopian4fec8732012-06-29 14:12:52 -0700469void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700470 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700471 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700472{
Mathias Agopian13127d82013-03-05 17:47:11 -0800473 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700474
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700475 // enable this layer
476 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700477
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700478 if (isSecure() && !hw->isSecure()) {
479 layer.setSkip(true);
480 }
481
Mathias Agopian13127d82013-03-05 17:47:11 -0800482 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700483 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800484 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800485 layer.setBlending(mPremultipliedAlpha ?
486 HWC_BLENDING_PREMULT :
487 HWC_BLENDING_COVERAGE);
488 }
489
490 // apply the layer's transform, followed by the display's global transform
491 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700492 Region activeTransparentRegion(s.activeTransparentRegion);
493 if (!s.active.crop.isEmpty()) {
494 Rect activeCrop(s.active.crop);
495 activeCrop = s.transform.transform(activeCrop);
496 activeCrop.intersect(hw->getViewport(), &activeCrop);
497 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800498 // This needs to be here as transform.transform(Rect) computes the
499 // transformed rect and then takes the bounding box of the result before
500 // returning. This means
501 // transform.inverse().transform(transform.transform(Rect)) != Rect
502 // in which case we need to make sure the final rect is clipped to the
503 // display bounds.
504 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700505 // mark regions outside the crop as transparent
506 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
507 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
508 s.active.w, s.active.h));
509 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
510 activeCrop.left, activeCrop.bottom));
511 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
512 s.active.w, activeCrop.bottom));
513 }
514 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800515 frame.intersect(hw->getViewport(), &frame);
516 const Transform& tr(hw->getTransform());
517 layer.setFrame(tr.transform(frame));
518 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800519 layer.setPlaneAlpha(s.alpha);
520
Mathias Agopian29a367b2011-07-12 14:51:45 -0700521 /*
522 * Transformations are applied in this order:
523 * 1) buffer orientation/flip/mirror
524 * 2) state transformation (window manager)
525 * 3) layer orientation (screen orientation)
526 * (NOTE: the matrices are multiplied in reverse order)
527 */
528
529 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700530 Transform transform(tr * s.transform * bufferOrientation);
531
532 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
533 /*
534 * the code below applies the display's inverse transform to the buffer
535 */
536 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700537 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700538 // calculate the inverse transform
539 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
540 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
541 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700542 // If the transform has been rotated the axis of flip has been swapped
543 // so we need to swap which flip operations we are performing
544 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
545 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
546 if (is_h_flipped != is_v_flipped) {
547 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
548 NATIVE_WINDOW_TRANSFORM_FLIP_H;
549 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700550 }
551 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700552 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700553 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700554
555 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800556 const uint32_t orientation = transform.getOrientation();
557 if (orientation & Transform::ROT_INVALID) {
558 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700559 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700560 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800561 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700562 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700563}
564
Mathias Agopian42977342012-08-05 00:40:46 -0700565void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700566 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800567 // we have to set the visible region on every frame because
568 // we currently free it during onLayerDisplayed(), which is called
569 // after HWComposer::commit() -- every frame.
570 // Apply this display's projection's viewport to the visible region
571 // before giving it to the HWC HAL.
572 const Transform& tr = hw->getTransform();
573 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
574 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700575 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700576
Jesse Hall399184a2014-03-03 15:42:54 -0800577 if (mSidebandStream.get()) {
578 layer.setSidebandStream(mSidebandStream);
579 } else {
580 // NOTE: buffer can be NULL if the client never drew into this
581 // layer yet, or if we ran out of memory
582 layer.setBuffer(mActiveBuffer);
583 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700584}
Jesse Halldc5b4852012-06-29 15:21:18 -0700585
Dan Stozac7014012014-02-14 15:03:43 -0800586void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700587 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700588 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700589
590 // TODO: there is a possible optimization here: we only need to set the
591 // acquire fence the first time a new buffer is acquired on EACH display.
592
Riley Andrews03414a12014-07-01 14:22:59 -0700593 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800594 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800595 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700596 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700597 if (fenceFd == -1) {
598 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
599 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700600 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700601 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700602 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700603}
604
Riley Andrews03414a12014-07-01 14:22:59 -0700605Rect Layer::getPosition(
606 const sp<const DisplayDevice>& hw)
607{
608 // this gives us only the "orientation" component of the transform
609 const State& s(getCurrentState());
610
611 // apply the layer's transform, followed by the display's global transform
612 // here we're guaranteed that the layer's transform preserves rects
613 Rect win(s.active.w, s.active.h);
614 if (!s.active.crop.isEmpty()) {
615 win.intersect(s.active.crop, &win);
616 }
617 // subtract the transparent region and snap to the bounds
618 Rect bounds = reduce(win, s.activeTransparentRegion);
619 Rect frame(s.transform.transform(bounds));
620 frame.intersect(hw->getViewport(), &frame);
621 const Transform& tr(hw->getTransform());
622 return Rect(tr.transform(frame));
623}
624
Mathias Agopian13127d82013-03-05 17:47:11 -0800625// ---------------------------------------------------------------------------
626// drawing...
627// ---------------------------------------------------------------------------
628
629void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800630 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800631}
632
Dan Stozac7014012014-02-14 15:03:43 -0800633void Layer::draw(const sp<const DisplayDevice>& hw,
634 bool useIdentityTransform) const {
635 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800636}
637
Dan Stozac7014012014-02-14 15:03:43 -0800638void Layer::draw(const sp<const DisplayDevice>& hw) const {
639 onDraw(hw, Region(hw->bounds()), false);
640}
641
642void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
643 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800644{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800645 ATRACE_CALL();
646
Mathias Agopiana67932f2011-04-20 14:20:59 -0700647 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800648 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700649 // in fact never been drawn into. This happens frequently with
650 // SurfaceView because the WindowManager can't know when the client
651 // has drawn the first time.
652
653 // If there is nothing under us, we paint the screen in black, otherwise
654 // we just skip this update.
655
656 // figure out if there is something below us
657 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700658 const SurfaceFlinger::LayerVector& drawingLayers(
659 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700660 const size_t count = drawingLayers.size();
661 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800662 const sp<Layer>& layer(drawingLayers[i]);
663 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700664 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700665 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700666 }
667 // if not everything below us is covered, we plug the holes!
668 Region holes(clip.subtract(under));
669 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700670 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700671 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800672 return;
673 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700674
Andy McFadden97eba892012-12-11 15:21:45 -0800675 // Bind the current buffer to the GL texture, and wait for it to be
676 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800677 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
678 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800679 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700680 // Go ahead and draw the buffer anyway; no matter what we do the screen
681 // is probably going to have something visibly wrong.
682 }
683
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700684 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
685
Mathias Agopian875d8e12013-06-07 15:35:48 -0700686 RenderEngine& engine(mFlinger->getRenderEngine());
687
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700688 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700689 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700690 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700691
692 // Query the texture matrix given our current filtering mode.
693 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800694 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
695 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700696
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700697 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
698
699 /*
700 * the code below applies the display's inverse transform to the texture transform
701 */
702
703 // create a 4x4 transform matrix from the display transform flags
704 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
705 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
706 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
707
708 mat4 tr;
709 uint32_t transform = hw->getOrientationTransform();
710 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
711 tr = tr * rot90;
712 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
713 tr = tr * flipH;
714 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
715 tr = tr * flipV;
716
717 // calculate the inverse
718 tr = inverse(tr);
719
720 // and finally apply it to the original texture matrix
721 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
722 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
723 }
724
Jamie Genniscbb1a952012-05-08 17:05:52 -0700725 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700726 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
727 mTexture.setFiltering(useFiltering);
728 mTexture.setMatrix(textureMatrix);
729
730 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700731 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700732 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700733 }
Dan Stozac7014012014-02-14 15:03:43 -0800734 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700735 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800736}
737
Mathias Agopian13127d82013-03-05 17:47:11 -0800738
Dan Stozac7014012014-02-14 15:03:43 -0800739void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
740 const Region& /* clip */, float red, float green, float blue,
741 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800742{
Mathias Agopian19733a32013-08-28 18:13:56 -0700743 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800744 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700745 engine.setupFillWithColor(red, green, blue, alpha);
746 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800747}
748
749void Layer::clearWithOpenGL(
750 const sp<const DisplayDevice>& hw, const Region& clip) const {
751 clearWithOpenGL(hw, clip, 0,0,0,0);
752}
753
Dan Stozac7014012014-02-14 15:03:43 -0800754void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
755 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700756 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800757
Dan Stozac7014012014-02-14 15:03:43 -0800758 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800759
Mathias Agopian13127d82013-03-05 17:47:11 -0800760 /*
761 * NOTE: the way we compute the texture coordinates here produces
762 * different results than when we take the HWC path -- in the later case
763 * the "source crop" is rounded to texel boundaries.
764 * This can produce significantly different results when the texture
765 * is scaled by a large amount.
766 *
767 * The GL code below is more logical (imho), and the difference with
768 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700769 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800770 * GL composition when a buffer scaling is applied (maybe with some
771 * minimal value)? Or, we could make GL behave like HWC -- but this feel
772 * like more of a hack.
773 */
774 const Rect win(computeBounds());
775
Mathias Agopian3f844832013-08-07 21:24:32 -0700776 float left = float(win.left) / float(s.active.w);
777 float top = float(win.top) / float(s.active.h);
778 float right = float(win.right) / float(s.active.w);
779 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800780
Mathias Agopian875d8e12013-06-07 15:35:48 -0700781 // TODO: we probably want to generate the texture coords with the mesh
782 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700783 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
784 texCoords[0] = vec2(left, 1.0f - top);
785 texCoords[1] = vec2(left, 1.0f - bottom);
786 texCoords[2] = vec2(right, 1.0f - bottom);
787 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800788
Mathias Agopian875d8e12013-06-07 15:35:48 -0700789 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800790 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700791 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700792 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800793}
794
Ruben Brunk1681d952014-06-27 15:51:55 -0700795uint32_t Layer::getProducerStickyTransform() const {
796 int producerStickyTransform = 0;
797 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
798 if (ret != OK) {
799 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
800 strerror(-ret), ret);
801 return 0;
802 }
803 return static_cast<uint32_t>(producerStickyTransform);
804}
805
Dan Stoza7dde5992015-05-22 09:51:44 -0700806void Layer::addSyncPoint(std::shared_ptr<SyncPoint> point) {
807 uint64_t headFrameNumber = 0;
808 {
809 Mutex::Autolock lock(mQueueItemLock);
810 if (!mQueueItems.empty()) {
811 headFrameNumber = mQueueItems[0].mFrameNumber;
812 } else {
813 headFrameNumber = mLastFrameNumberReceived;
814 }
815 }
816
817 if (point->getFrameNumber() <= headFrameNumber) {
818 point->setFrameAvailable();
819 } else {
820 mLocalSyncPoints.push_back(std::move(point));
821 }
822}
823
Mathias Agopian13127d82013-03-05 17:47:11 -0800824void Layer::setFiltering(bool filtering) {
825 mFiltering = filtering;
826}
827
828bool Layer::getFiltering() const {
829 return mFiltering;
830}
831
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800832// As documented in libhardware header, formats in the range
833// 0x100 - 0x1FF are specific to the HAL implementation, and
834// are known to have no alpha channel
835// TODO: move definition for device-specific range into
836// hardware.h, instead of using hard-coded values here.
837#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
838
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700839bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700840 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
841 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800842 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700843 switch (format) {
844 case HAL_PIXEL_FORMAT_RGBA_8888:
845 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700846 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700847 }
848 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700849 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800850}
851
Mathias Agopian13127d82013-03-05 17:47:11 -0800852// ----------------------------------------------------------------------------
853// local state
854// ----------------------------------------------------------------------------
855
Dan Stozac7014012014-02-14 15:03:43 -0800856void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
857 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800858{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700859 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800860 const Transform tr(useIdentityTransform ?
861 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800862 const uint32_t hw_h = hw->getHeight();
863 Rect win(s.active.w, s.active.h);
864 if (!s.active.crop.isEmpty()) {
865 win.intersect(s.active.crop, &win);
866 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700867 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700868 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700869
Mathias Agopianff2ed702013-09-01 21:36:12 -0700870 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
871 position[0] = tr.transform(win.left, win.top);
872 position[1] = tr.transform(win.left, win.bottom);
873 position[2] = tr.transform(win.right, win.bottom);
874 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700875 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700876 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800877 }
878}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800879
Andy McFadden4125a4f2014-01-29 17:17:11 -0800880bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700881{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700882 // if we don't have a buffer yet, we're translucent regardless of the
883 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700884 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700885 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700886 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700887
888 // if the layer has the opaque flag, then we're always opaque,
889 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800890 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700891}
892
Dan Stoza23116082015-06-18 14:58:39 -0700893bool Layer::isSecure() const
894{
895 const Layer::State& s(mDrawingState);
896 return (s.flags & layer_state_t::eLayerSecure);
897}
898
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800899bool Layer::isProtected() const
900{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700901 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800902 return (activeBuffer != 0) &&
903 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
904}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700905
Mathias Agopian13127d82013-03-05 17:47:11 -0800906bool Layer::isFixedSize() const {
907 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
908}
909
910bool Layer::isCropped() const {
911 return !mCurrentCrop.isEmpty();
912}
913
914bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
915 return mNeedsFiltering || hw->needsFiltering();
916}
917
918void Layer::setVisibleRegion(const Region& visibleRegion) {
919 // always called from main thread
920 this->visibleRegion = visibleRegion;
921}
922
923void Layer::setCoveredRegion(const Region& coveredRegion) {
924 // always called from main thread
925 this->coveredRegion = coveredRegion;
926}
927
928void Layer::setVisibleNonTransparentRegion(const Region&
929 setVisibleNonTransparentRegion) {
930 // always called from main thread
931 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
932}
933
934// ----------------------------------------------------------------------------
935// transaction
936// ----------------------------------------------------------------------------
937
Dan Stoza7dde5992015-05-22 09:51:44 -0700938void Layer::pushPendingState() {
939 if (!mCurrentState.modified) {
940 return;
941 }
942
943 Mutex::Autolock lock(mPendingStateMutex);
944
945 // If this transaction is waiting on the receipt of a frame, generate a sync
946 // point and send it to the remote layer.
947 if (mCurrentState.handle != nullptr) {
948 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
949 sp<Layer> handleLayer = handle->owner.promote();
950 if (handleLayer == nullptr) {
951 ALOGE("[%s] Unable to promote Layer handle", mName.string());
952 // If we can't promote the layer we are intended to wait on,
953 // then it is expired or otherwise invalid. Allow this transaction
954 // to be applied as per normal (no synchronization).
955 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -0800956 } else {
957 auto syncPoint = std::make_shared<SyncPoint>(
958 mCurrentState.frameNumber);
959 handleLayer->addSyncPoint(syncPoint);
960 mRemoteSyncPoints.push_back(std::move(syncPoint));
Dan Stoza7dde5992015-05-22 09:51:44 -0700961 }
962
Dan Stoza7dde5992015-05-22 09:51:44 -0700963 // Wake us up to check if the frame has been received
964 setTransactionFlags(eTransactionNeeded);
965 }
966 mPendingStates.push_back(mCurrentState);
967}
968
969void Layer::popPendingState() {
970 auto oldFlags = mCurrentState.flags;
971 mCurrentState = mPendingStates[0];
972 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
973 (mCurrentState.flags & mCurrentState.mask);
974
975 mPendingStates.removeAt(0);
976}
977
978bool Layer::applyPendingStates() {
979 Mutex::Autolock lock(mPendingStateMutex);
980
981 bool stateUpdateAvailable = false;
982 while (!mPendingStates.empty()) {
983 if (mPendingStates[0].handle != nullptr) {
984 if (mRemoteSyncPoints.empty()) {
985 // If we don't have a sync point for this, apply it anyway. It
986 // will be visually wrong, but it should keep us from getting
987 // into too much trouble.
988 ALOGE("[%s] No local sync point found", mName.string());
989 popPendingState();
990 stateUpdateAvailable = true;
991 continue;
992 }
993
994 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
995 // Apply the state update
996 popPendingState();
997 stateUpdateAvailable = true;
998
999 // Signal our end of the sync point and then dispose of it
1000 mRemoteSyncPoints.front()->setTransactionApplied();
1001 mRemoteSyncPoints.pop_front();
1002 }
1003 break;
1004 } else {
1005 popPendingState();
1006 stateUpdateAvailable = true;
1007 }
1008 }
1009
1010 // If we still have pending updates, wake SurfaceFlinger back up and point
1011 // it at this layer so we can process them
1012 if (!mPendingStates.empty()) {
1013 setTransactionFlags(eTransactionNeeded);
1014 mFlinger->setTransactionFlags(eTraversalNeeded);
1015 }
1016
1017 mCurrentState.modified = false;
1018 return stateUpdateAvailable;
1019}
1020
1021void Layer::notifyAvailableFrames() {
1022 Mutex::Autolock lock(mAvailableFrameMutex);
1023 for (auto frame : mAvailableFrames) {
1024 frame->setFrameAvailable();
1025 }
1026}
1027
Mathias Agopian13127d82013-03-05 17:47:11 -08001028uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001029 ATRACE_CALL();
1030
Dan Stoza7dde5992015-05-22 09:51:44 -07001031 pushPendingState();
1032 if (!applyPendingStates()) {
1033 return 0;
1034 }
1035
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001036 const Layer::State& s(getDrawingState());
1037 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001038
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001039 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1040 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001041
1042 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001043 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001044 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001045 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001046 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1047 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1048 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1049 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001050 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1051 c.active.w, c.active.h,
1052 c.active.crop.left,
1053 c.active.crop.top,
1054 c.active.crop.right,
1055 c.active.crop.bottom,
1056 c.active.crop.getWidth(),
1057 c.active.crop.getHeight(),
1058 c.requested.w, c.requested.h,
1059 c.requested.crop.left,
1060 c.requested.crop.top,
1061 c.requested.crop.right,
1062 c.requested.crop.bottom,
1063 c.requested.crop.getWidth(),
1064 c.requested.crop.getHeight(),
1065 s.active.w, s.active.h,
1066 s.active.crop.left,
1067 s.active.crop.top,
1068 s.active.crop.right,
1069 s.active.crop.bottom,
1070 s.active.crop.getWidth(),
1071 s.active.crop.getHeight(),
1072 s.requested.w, s.requested.h,
1073 s.requested.crop.left,
1074 s.requested.crop.top,
1075 s.requested.crop.right,
1076 s.requested.crop.bottom,
1077 s.requested.crop.getWidth(),
1078 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001079
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001080 // record the new size, form this point on, when the client request
1081 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001082 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001083 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001084 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001085
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001086 if (!isFixedSize()) {
1087
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001088 const bool resizePending = (c.requested.w != c.active.w) ||
1089 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001090
Dan Stoza9e9b0442015-04-22 14:59:08 -07001091 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001092 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001093 // if we have a pending resize, unless we are in fixed-size mode.
1094 // the drawing state will be updated only once we receive a buffer
1095 // with the correct size.
1096 //
1097 // in particular, we want to make sure the clip (which is part
1098 // of the geometry state) is latched together with the size but is
1099 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001100 //
1101 // If a sideband stream is attached, however, we want to skip this
1102 // optimization so that transactions aren't missed when a buffer
1103 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001104
1105 flags |= eDontUpdateGeometryState;
1106 }
1107 }
1108
Mathias Agopian13127d82013-03-05 17:47:11 -08001109 // always set active to requested, unless we're asked not to
1110 // this is used by Layer, which special cases resizes.
1111 if (flags & eDontUpdateGeometryState) {
1112 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001113 Layer::State& editCurrentState(getCurrentState());
1114 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001115 }
1116
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001117 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001118 // invalidate and recompute the visible regions if needed
1119 flags |= Layer::eVisibleRegion;
1120 }
1121
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001122 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001123 // invalidate and recompute the visible regions if needed
1124 flags |= eVisibleRegion;
1125 this->contentDirty = true;
1126
1127 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001128 const uint8_t type = c.transform.getType();
1129 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001130 (type >= Transform::SCALE));
1131 }
1132
1133 // Commit the transaction
1134 commitTransaction();
1135 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001136}
1137
Mathias Agopian13127d82013-03-05 17:47:11 -08001138void Layer::commitTransaction() {
1139 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001140}
1141
Mathias Agopian13127d82013-03-05 17:47:11 -08001142uint32_t Layer::getTransactionFlags(uint32_t flags) {
1143 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1144}
1145
1146uint32_t Layer::setTransactionFlags(uint32_t flags) {
1147 return android_atomic_or(flags, &mTransactionFlags);
1148}
1149
1150bool Layer::setPosition(float x, float y) {
1151 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1152 return false;
1153 mCurrentState.sequence++;
1154 mCurrentState.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001155 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001156 setTransactionFlags(eTransactionNeeded);
1157 return true;
1158}
1159bool Layer::setLayer(uint32_t z) {
1160 if (mCurrentState.z == z)
1161 return false;
1162 mCurrentState.sequence++;
1163 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001164 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001165 setTransactionFlags(eTransactionNeeded);
1166 return true;
1167}
1168bool Layer::setSize(uint32_t w, uint32_t h) {
1169 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1170 return false;
1171 mCurrentState.requested.w = w;
1172 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001173 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001174 setTransactionFlags(eTransactionNeeded);
1175 return true;
1176}
1177bool Layer::setAlpha(uint8_t alpha) {
1178 if (mCurrentState.alpha == alpha)
1179 return false;
1180 mCurrentState.sequence++;
1181 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001182 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001183 setTransactionFlags(eTransactionNeeded);
1184 return true;
1185}
1186bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1187 mCurrentState.sequence++;
1188 mCurrentState.transform.set(
1189 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001190 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001191 setTransactionFlags(eTransactionNeeded);
1192 return true;
1193}
1194bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001195 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001196 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001197 setTransactionFlags(eTransactionNeeded);
1198 return true;
1199}
1200bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1201 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1202 if (mCurrentState.flags == newFlags)
1203 return false;
1204 mCurrentState.sequence++;
1205 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001206 mCurrentState.mask = mask;
1207 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001208 setTransactionFlags(eTransactionNeeded);
1209 return true;
1210}
1211bool Layer::setCrop(const Rect& crop) {
1212 if (mCurrentState.requested.crop == crop)
1213 return false;
1214 mCurrentState.sequence++;
1215 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001216 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001217 setTransactionFlags(eTransactionNeeded);
1218 return true;
1219}
1220
1221bool Layer::setLayerStack(uint32_t layerStack) {
1222 if (mCurrentState.layerStack == layerStack)
1223 return false;
1224 mCurrentState.sequence++;
1225 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001226 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001227 setTransactionFlags(eTransactionNeeded);
1228 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001229}
1230
Dan Stoza7dde5992015-05-22 09:51:44 -07001231void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1232 uint64_t frameNumber) {
1233 mCurrentState.handle = handle;
1234 mCurrentState.frameNumber = frameNumber;
1235 // We don't set eTransactionNeeded, because just receiving a deferral
1236 // request without any other state updates shouldn't actually induce a delay
1237 mCurrentState.modified = true;
1238 pushPendingState();
1239 mCurrentState.modified = false;
1240}
1241
Dan Stozaee44edd2015-03-23 15:50:23 -07001242void Layer::useSurfaceDamage() {
1243 if (mFlinger->mForceFullDamage) {
1244 surfaceDamageRegion = Region::INVALID_REGION;
1245 } else {
1246 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1247 }
1248}
1249
1250void Layer::useEmptyDamage() {
1251 surfaceDamageRegion.clear();
1252}
1253
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001254// ----------------------------------------------------------------------------
1255// pageflip handling...
1256// ----------------------------------------------------------------------------
1257
Dan Stoza6b9454d2014-11-07 16:00:59 -08001258bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballos06312182015-10-07 16:32:12 -07001259 if (mSidebandStreamChanged || mSingleBufferMode) {
Dan Stozad87defa2015-07-29 16:15:50 -07001260 return true;
1261 }
1262
Dan Stoza6b9454d2014-11-07 16:00:59 -08001263 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001264 if (mQueueItems.empty()) {
1265 return false;
1266 }
1267 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001268 nsecs_t expectedPresent =
1269 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001270
1271 // Ignore timestamps more than a second in the future
1272 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1273 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1274 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1275 expectedPresent);
1276
1277 bool isDue = timestamp < expectedPresent;
1278 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001279}
1280
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001281bool Layer::onPreComposition() {
1282 mRefreshPending = false;
Pablo Ceballos06312182015-10-07 16:32:12 -07001283 return mQueuedFrames > 0 || mSidebandStreamChanged || mSingleBufferMode;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001284}
1285
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001286void Layer::onPostComposition() {
1287 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001288 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001289 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1290
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001291 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001292 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001293 mFrameTracker.setFrameReadyFence(frameReadyFence);
1294 } else {
1295 // There was no fence for this frame, so assume that it was ready
1296 // to be presented at the desired present time.
1297 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1298 }
1299
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001300 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001301 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001302 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001303 mFrameTracker.setActualPresentFence(presentFence);
1304 } else {
1305 // The HWC doesn't support present fences, so use the refresh
1306 // timestamp instead.
1307 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1308 mFrameTracker.setActualPresentTime(presentTime);
1309 }
1310
1311 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001312 mFrameLatencyNeeded = false;
1313 }
1314}
1315
Mathias Agopianda27af92012-09-13 18:17:13 -07001316bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001317 const Layer::State& s(mDrawingState);
1318 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001319 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001320}
1321
Mathias Agopian4fec8732012-06-29 14:12:52 -07001322Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001323{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001324 ATRACE_CALL();
1325
Jesse Hall399184a2014-03-03 15:42:54 -08001326 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1327 // mSidebandStreamChanged was true
1328 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001329 if (mSidebandStream != NULL) {
1330 setTransactionFlags(eTransactionNeeded);
1331 mFlinger->setTransactionFlags(eTraversalNeeded);
1332 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001333 recomputeVisibleRegions = true;
1334
1335 const State& s(getDrawingState());
1336 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001337 }
1338
Mathias Agopian4fec8732012-06-29 14:12:52 -07001339 Region outDirtyRegion;
Pablo Ceballos06312182015-10-07 16:32:12 -07001340 if (mQueuedFrames > 0 || mSingleBufferMode) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001341
1342 // if we've already called updateTexImage() without going through
1343 // a composition step, we have to skip this layer at this point
1344 // because we cannot call updateTeximage() without a corresponding
1345 // compositionComplete() call.
1346 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001347 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001348 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001349 }
1350
Jamie Gennis351a5132011-09-14 18:23:37 -07001351 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001352 const State& s(getDrawingState());
1353 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001354 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001355
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001356 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001357 Layer::State& front;
1358 Layer::State& current;
1359 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001360 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001361 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001362 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001363 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001364 recomputeVisibleRegions(recomputeVisibleRegions),
1365 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001366 }
1367
1368 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001369 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001370 if (buf == NULL) {
1371 return false;
1372 }
1373
1374 uint32_t bufWidth = buf->getWidth();
1375 uint32_t bufHeight = buf->getHeight();
1376
1377 // check that we received a buffer of the right size
1378 // (Take the buffer's orientation into account)
1379 if (item.mTransform & Transform::ROT_90) {
1380 swap(bufWidth, bufHeight);
1381 }
1382
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001383 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1384 if (front.active != front.requested) {
1385
1386 if (isFixedSize ||
1387 (bufWidth == front.requested.w &&
1388 bufHeight == front.requested.h))
1389 {
1390 // Here we pretend the transaction happened by updating the
1391 // current and drawing states. Drawing state is only accessed
1392 // in this thread, no need to have it locked
1393 front.active = front.requested;
1394
1395 // We also need to update the current state so that
1396 // we don't end-up overwriting the drawing state with
1397 // this stale current state during the next transaction
1398 //
1399 // NOTE: We don't need to hold the transaction lock here
1400 // because State::active is only accessed from this thread.
1401 current.active = front.active;
1402
1403 // recompute visible region
1404 recomputeVisibleRegions = true;
1405 }
1406
1407 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001408 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001409 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1410 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001411 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001412 front.active.w, front.active.h,
1413 front.active.crop.left,
1414 front.active.crop.top,
1415 front.active.crop.right,
1416 front.active.crop.bottom,
1417 front.active.crop.getWidth(),
1418 front.active.crop.getHeight(),
1419 front.requested.w, front.requested.h,
1420 front.requested.crop.left,
1421 front.requested.crop.top,
1422 front.requested.crop.right,
1423 front.requested.crop.bottom,
1424 front.requested.crop.getWidth(),
1425 front.requested.crop.getHeight());
1426 }
1427
Ruben Brunk1681d952014-06-27 15:51:55 -07001428 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001429 if (front.active.w != bufWidth ||
1430 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001431 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001432 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1433 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001434 return true;
1435 }
1436 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001437
1438 // if the transparent region has changed (this test is
1439 // conservative, but that's fine, worst case we're doing
1440 // a bit of extra work), we latch the new one and we
1441 // trigger a visible-region recompute.
1442 if (!front.activeTransparentRegion.isTriviallyEqual(
1443 front.requestedTransparentRegion)) {
1444 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001445
1446 // We also need to update the current state so that
1447 // we don't end-up overwriting the drawing state with
1448 // this stale current state during the next transaction
1449 //
1450 // NOTE: We don't need to hold the transaction lock here
1451 // because State::active is only accessed from this thread.
1452 current.activeTransparentRegion = front.activeTransparentRegion;
1453
1454 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001455 recomputeVisibleRegions = true;
1456 }
1457
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001458 return false;
1459 }
1460 };
1461
Ruben Brunk1681d952014-06-27 15:51:55 -07001462 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1463 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001464
Dan Stozaa4650a52015-05-12 12:56:16 -07001465 uint64_t maxFrameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001466 uint64_t headFrameNumber = 0;
Dan Stozaa4650a52015-05-12 12:56:16 -07001467 {
1468 Mutex::Autolock lock(mQueueItemLock);
1469 maxFrameNumber = mLastFrameNumberReceived;
Dan Stoza7dde5992015-05-22 09:51:44 -07001470 if (!mQueueItems.empty()) {
1471 headFrameNumber = mQueueItems[0].mFrameNumber;
1472 }
1473 }
1474
1475 bool availableFramesEmpty = true;
1476 {
1477 Mutex::Autolock lock(mAvailableFrameMutex);
1478 availableFramesEmpty = mAvailableFrames.empty();
1479 }
1480 if (!availableFramesEmpty) {
1481 Mutex::Autolock lock(mAvailableFrameMutex);
1482 bool matchingFramesFound = false;
1483 bool allTransactionsApplied = true;
1484 for (auto& frame : mAvailableFrames) {
1485 if (headFrameNumber != frame->getFrameNumber()) {
1486 break;
1487 }
1488 matchingFramesFound = true;
1489 allTransactionsApplied &= frame->transactionIsApplied();
1490 }
1491 if (matchingFramesFound && !allTransactionsApplied) {
1492 mFlinger->signalLayerUpdate();
1493 return outDirtyRegion;
1494 }
Dan Stozaa4650a52015-05-12 12:56:16 -07001495 }
1496
Pablo Ceballos06312182015-10-07 16:32:12 -07001497 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1498 // of the buffer queue isn't modified when the buffer queue is returning
1499 // BufferItem's that weren't actually queued. This can happen in single
1500 // buffer mode.
1501 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001502 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballos06312182015-10-07 16:32:12 -07001503 mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer,
1504 maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001505 if (updateResult == BufferQueue::PRESENT_LATER) {
1506 // Producer doesn't want buffer to be displayed yet. Signal a
1507 // layer update so we check again at the next opportunity.
1508 mFlinger->signalLayerUpdate();
1509 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001510 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1511 // If the buffer has been rejected, remove it from the shadow queue
1512 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001513 if (queuedBuffer) {
1514 Mutex::Autolock lock(mQueueItemLock);
1515 mQueueItems.removeAt(0);
1516 android_atomic_dec(&mQueuedFrames);
1517 }
Dan Stozaecc50402015-04-28 14:42:06 -07001518 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001519 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1520 // This can occur if something goes wrong when trying to create the
1521 // EGLImage for this buffer. If this happens, the buffer has already
1522 // been released, so we need to clean up the queue and bug out
1523 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001524 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001525 Mutex::Autolock lock(mQueueItemLock);
1526 mQueueItems.clear();
1527 android_atomic_and(0, &mQueuedFrames);
1528 }
1529
1530 // Once we have hit this state, the shadow queue may no longer
1531 // correctly reflect the incoming BufferQueue's contents, so even if
1532 // updateTexImage starts working, the only safe course of action is
1533 // to continue to ignore updates.
1534 mUpdateTexImageFailed = true;
1535
1536 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001537 }
1538
Pablo Ceballos06312182015-10-07 16:32:12 -07001539 if (queuedBuffer) {
1540 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001541 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1542
Dan Stoza6b9454d2014-11-07 16:00:59 -08001543 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001544
1545 // Remove any stale buffers that have been dropped during
1546 // updateTexImage
1547 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1548 mQueueItems.removeAt(0);
1549 android_atomic_dec(&mQueuedFrames);
1550 }
1551
Dan Stoza6b9454d2014-11-07 16:00:59 -08001552 mQueueItems.removeAt(0);
1553 }
1554
Dan Stozaecc50402015-04-28 14:42:06 -07001555
Andy McFadden1585c4d2013-06-28 13:52:40 -07001556 // Decrement the queued-frames count. Signal another event if we
1557 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001558 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1559 || mSingleBufferMode) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001560 mFlinger->signalLayerUpdate();
1561 }
1562
Dan Stoza7dde5992015-05-22 09:51:44 -07001563 if (!availableFramesEmpty) {
1564 Mutex::Autolock lock(mAvailableFrameMutex);
1565 auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1566 while (!mAvailableFrames.empty() &&
1567 frameNumber == mAvailableFrames.front()->getFrameNumber()) {
1568 mAvailableFrames.pop_front();
1569 }
1570 }
1571
Andy McFadden1585c4d2013-06-28 13:52:40 -07001572 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001573 // something happened!
1574 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001575 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001576 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001577
Jamie Gennis351a5132011-09-14 18:23:37 -07001578 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001579 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001580 if (mActiveBuffer == NULL) {
1581 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001582 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001583 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001584
Mathias Agopian4824d402012-06-04 18:16:30 -07001585 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001586 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001587 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001588 // the first time we receive a buffer, we need to trigger a
1589 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001590 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001591 }
1592
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001593 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1594 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1595 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001596 if ((crop != mCurrentCrop) ||
1597 (transform != mCurrentTransform) ||
1598 (scalingMode != mCurrentScalingMode))
1599 {
1600 mCurrentCrop = crop;
1601 mCurrentTransform = transform;
1602 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001603 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001604 }
1605
1606 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001607 uint32_t bufWidth = mActiveBuffer->getWidth();
1608 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001609 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1610 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001611 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001612 }
1613 }
1614
1615 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001616 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001617 recomputeVisibleRegions = true;
1618 }
1619
Mathias Agopian4fec8732012-06-29 14:12:52 -07001620 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001621 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001622
1623 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001624 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001625 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001626 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001627}
1628
Mathias Agopiana67932f2011-04-20 14:20:59 -07001629uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001630{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001631 // TODO: should we do something special if mSecure is set?
1632 if (mProtectedByApp) {
1633 // need a hardware-protected path to external video sink
1634 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001635 }
Riley Andrews03414a12014-07-01 14:22:59 -07001636 if (mPotentialCursor) {
1637 usage |= GraphicBuffer::USAGE_CURSOR;
1638 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001639 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001640 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001641}
1642
Mathias Agopian84300952012-11-21 16:02:13 -08001643void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001644 uint32_t orientation = 0;
1645 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001646 // The transform hint is used to improve performance, but we can
1647 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001648 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001649 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001650 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001651 if (orientation & Transform::ROT_INVALID) {
1652 orientation = 0;
1653 }
1654 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001655 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001656}
1657
Mathias Agopian13127d82013-03-05 17:47:11 -08001658// ----------------------------------------------------------------------------
1659// debugging
1660// ----------------------------------------------------------------------------
1661
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001662void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001663{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001664 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001665
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001666 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001667 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001668 "+ %s %p (%s)\n",
1669 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001670 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001671
Mathias Agopian2ca79392013-04-02 18:30:32 -07001672 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001673 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001674 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001675 sp<Client> client(mClientRef.promote());
1676
Mathias Agopian74d211a2013-04-22 16:55:35 +02001677 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001678 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1679 "isOpaque=%1d, invalidate=%1d, "
1680 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1681 " client=%p\n",
1682 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1683 s.active.crop.left, s.active.crop.top,
1684 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001685 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001686 s.alpha, s.flags,
1687 s.transform[0][0], s.transform[0][1],
1688 s.transform[1][0], s.transform[1][1],
1689 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001690
1691 sp<const GraphicBuffer> buf0(mActiveBuffer);
1692 uint32_t w0=0, h0=0, s0=0, f0=0;
1693 if (buf0 != 0) {
1694 w0 = buf0->getWidth();
1695 h0 = buf0->getHeight();
1696 s0 = buf0->getStride();
1697 f0 = buf0->format;
1698 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001699 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001700 " "
1701 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1702 " queued-frames=%d, mRefreshPending=%d\n",
1703 mFormat, w0, h0, s0,f0,
1704 mQueuedFrames, mRefreshPending);
1705
Mathias Agopian13127d82013-03-05 17:47:11 -08001706 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001707 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001708 }
1709}
1710
Svetoslavd85084b2014-03-20 10:28:31 -07001711void Layer::dumpFrameStats(String8& result) const {
1712 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001713}
1714
Svetoslavd85084b2014-03-20 10:28:31 -07001715void Layer::clearFrameStats() {
1716 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001717}
1718
Jamie Gennis6547ff42013-07-16 20:12:42 -07001719void Layer::logFrameStats() {
1720 mFrameTracker.logAndResetStats(mName);
1721}
1722
Svetoslavd85084b2014-03-20 10:28:31 -07001723void Layer::getFrameStats(FrameStats* outStats) const {
1724 mFrameTracker.getStats(outStats);
1725}
1726
Mathias Agopian13127d82013-03-05 17:47:11 -08001727// ---------------------------------------------------------------------------
1728
1729Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1730 const sp<Layer>& layer)
1731 : mFlinger(flinger), mLayer(layer) {
1732}
1733
1734Layer::LayerCleaner::~LayerCleaner() {
1735 // destroy client resources
1736 mFlinger->onLayerDestroyed(mLayer);
1737}
1738
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001739// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001740}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001741
1742#if defined(__gl_h_)
1743#error "don't include gl/gl.h in this file"
1744#endif
1745
1746#if defined(__gl2_h_)
1747#error "don't include gl2/gl2.h in this file"
1748#endif