blob: 1c2c05d9dce4fa9b5967d279e169017a0eec0b69 [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 Agopian13127d82013-03-05 17:47:11 -0800150 sp<Client> c(mClientRef.promote());
151 if (c != 0) {
152 c->detachLayer(this);
153 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700154 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700155 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700156}
157
Mathias Agopian13127d82013-03-05 17:47:11 -0800158// ---------------------------------------------------------------------------
159// callbacks
160// ---------------------------------------------------------------------------
161
Dan Stozac7014012014-02-14 15:03:43 -0800162void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800163 HWComposer::HWCLayerInterface* layer) {
164 if (layer) {
165 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700166 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800167 }
168}
169
Dan Stoza7dde5992015-05-22 09:51:44 -0700170void Layer::markSyncPointsAvailable(const BufferItem& item) {
171 auto pointIter = mLocalSyncPoints.begin();
172 while (pointIter != mLocalSyncPoints.end()) {
173 if ((*pointIter)->getFrameNumber() == item.mFrameNumber) {
174 auto syncPoint = *pointIter;
175 pointIter = mLocalSyncPoints.erase(pointIter);
176 Mutex::Autolock lock(mAvailableFrameMutex);
177 mAvailableFrames.push_back(std::move(syncPoint));
178 } else {
179 ++pointIter;
180 }
181 }
182}
183
Dan Stoza6b9454d2014-11-07 16:00:59 -0800184void Layer::onFrameAvailable(const BufferItem& item) {
185 // Add this buffer from our internal queue tracker
186 { // Autolock scope
187 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700188
189 // Reset the frame number tracker when we receive the first buffer after
190 // a frame number reset
191 if (item.mFrameNumber == 1) {
192 mLastFrameNumberReceived = 0;
193 }
194
195 // Ensure that callbacks are handled in order
196 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
197 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
198 ms2ns(500));
199 if (result != NO_ERROR) {
200 ALOGE("[%s] Timed out waiting on callback", mName.string());
201 }
202 }
203
Dan Stoza6b9454d2014-11-07 16:00:59 -0800204 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700205 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700206
207 // Wake up any pending callbacks
208 mLastFrameNumberReceived = item.mFrameNumber;
209 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800210 }
211
Dan Stoza7dde5992015-05-22 09:51:44 -0700212 markSyncPointsAvailable(item);
213
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800214 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700215}
216
Dan Stoza6b9454d2014-11-07 16:00:59 -0800217void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700218 { // Autolock scope
219 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700220
Dan Stoza7dde5992015-05-22 09:51:44 -0700221 // Ensure that callbacks are handled in order
222 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
223 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
224 ms2ns(500));
225 if (result != NO_ERROR) {
226 ALOGE("[%s] Timed out waiting on callback", mName.string());
227 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700228 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700229
230 if (mQueueItems.empty()) {
231 ALOGE("Can't replace a frame on an empty queue");
232 return;
233 }
234 mQueueItems.editItemAt(0) = item;
235
236 // Wake up any pending callbacks
237 mLastFrameNumberReceived = item.mFrameNumber;
238 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700239 }
240
Dan Stoza7dde5992015-05-22 09:51:44 -0700241 markSyncPointsAvailable(item);
Dan Stoza6b9454d2014-11-07 16:00:59 -0800242}
243
Jesse Hall399184a2014-03-03 15:42:54 -0800244void Layer::onSidebandStreamChanged() {
245 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
246 // mSidebandStreamChanged was false
247 mFlinger->signalLayerUpdate();
248 }
249}
250
Mathias Agopian67106042013-03-14 19:18:13 -0700251// called with SurfaceFlinger::mStateLock from the drawing thread after
252// the layer has been remove from the current state list (and just before
253// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800254void Layer::onRemoved() {
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;
956 }
957
958 auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber);
959 handleLayer->addSyncPoint(syncPoint);
960 mRemoteSyncPoints.push_back(std::move(syncPoint));
961
962 // Wake us up to check if the frame has been received
963 setTransactionFlags(eTransactionNeeded);
964 }
965 mPendingStates.push_back(mCurrentState);
966}
967
968void Layer::popPendingState() {
969 auto oldFlags = mCurrentState.flags;
970 mCurrentState = mPendingStates[0];
971 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
972 (mCurrentState.flags & mCurrentState.mask);
973
974 mPendingStates.removeAt(0);
975}
976
977bool Layer::applyPendingStates() {
978 Mutex::Autolock lock(mPendingStateMutex);
979
980 bool stateUpdateAvailable = false;
981 while (!mPendingStates.empty()) {
982 if (mPendingStates[0].handle != nullptr) {
983 if (mRemoteSyncPoints.empty()) {
984 // If we don't have a sync point for this, apply it anyway. It
985 // will be visually wrong, but it should keep us from getting
986 // into too much trouble.
987 ALOGE("[%s] No local sync point found", mName.string());
988 popPendingState();
989 stateUpdateAvailable = true;
990 continue;
991 }
992
993 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
994 // Apply the state update
995 popPendingState();
996 stateUpdateAvailable = true;
997
998 // Signal our end of the sync point and then dispose of it
999 mRemoteSyncPoints.front()->setTransactionApplied();
1000 mRemoteSyncPoints.pop_front();
1001 }
1002 break;
1003 } else {
1004 popPendingState();
1005 stateUpdateAvailable = true;
1006 }
1007 }
1008
1009 // If we still have pending updates, wake SurfaceFlinger back up and point
1010 // it at this layer so we can process them
1011 if (!mPendingStates.empty()) {
1012 setTransactionFlags(eTransactionNeeded);
1013 mFlinger->setTransactionFlags(eTraversalNeeded);
1014 }
1015
1016 mCurrentState.modified = false;
1017 return stateUpdateAvailable;
1018}
1019
1020void Layer::notifyAvailableFrames() {
1021 Mutex::Autolock lock(mAvailableFrameMutex);
1022 for (auto frame : mAvailableFrames) {
1023 frame->setFrameAvailable();
1024 }
1025}
1026
Mathias Agopian13127d82013-03-05 17:47:11 -08001027uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001028 ATRACE_CALL();
1029
Dan Stoza7dde5992015-05-22 09:51:44 -07001030 pushPendingState();
1031 if (!applyPendingStates()) {
1032 return 0;
1033 }
1034
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001035 const Layer::State& s(getDrawingState());
1036 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001037
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001038 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1039 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001040
1041 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001042 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001043 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001044 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001045 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1046 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1047 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1048 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001049 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1050 c.active.w, c.active.h,
1051 c.active.crop.left,
1052 c.active.crop.top,
1053 c.active.crop.right,
1054 c.active.crop.bottom,
1055 c.active.crop.getWidth(),
1056 c.active.crop.getHeight(),
1057 c.requested.w, c.requested.h,
1058 c.requested.crop.left,
1059 c.requested.crop.top,
1060 c.requested.crop.right,
1061 c.requested.crop.bottom,
1062 c.requested.crop.getWidth(),
1063 c.requested.crop.getHeight(),
1064 s.active.w, s.active.h,
1065 s.active.crop.left,
1066 s.active.crop.top,
1067 s.active.crop.right,
1068 s.active.crop.bottom,
1069 s.active.crop.getWidth(),
1070 s.active.crop.getHeight(),
1071 s.requested.w, s.requested.h,
1072 s.requested.crop.left,
1073 s.requested.crop.top,
1074 s.requested.crop.right,
1075 s.requested.crop.bottom,
1076 s.requested.crop.getWidth(),
1077 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001078
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001079 // record the new size, form this point on, when the client request
1080 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001081 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001082 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001083 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001084
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001085 if (!isFixedSize()) {
1086
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001087 const bool resizePending = (c.requested.w != c.active.w) ||
1088 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001089
Dan Stoza9e9b0442015-04-22 14:59:08 -07001090 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001091 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001092 // if we have a pending resize, unless we are in fixed-size mode.
1093 // the drawing state will be updated only once we receive a buffer
1094 // with the correct size.
1095 //
1096 // in particular, we want to make sure the clip (which is part
1097 // of the geometry state) is latched together with the size but is
1098 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001099 //
1100 // If a sideband stream is attached, however, we want to skip this
1101 // optimization so that transactions aren't missed when a buffer
1102 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001103
1104 flags |= eDontUpdateGeometryState;
1105 }
1106 }
1107
Mathias Agopian13127d82013-03-05 17:47:11 -08001108 // always set active to requested, unless we're asked not to
1109 // this is used by Layer, which special cases resizes.
1110 if (flags & eDontUpdateGeometryState) {
1111 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001112 Layer::State& editCurrentState(getCurrentState());
1113 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001114 }
1115
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001116 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001117 // invalidate and recompute the visible regions if needed
1118 flags |= Layer::eVisibleRegion;
1119 }
1120
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001121 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001122 // invalidate and recompute the visible regions if needed
1123 flags |= eVisibleRegion;
1124 this->contentDirty = true;
1125
1126 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001127 const uint8_t type = c.transform.getType();
1128 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001129 (type >= Transform::SCALE));
1130 }
1131
1132 // Commit the transaction
1133 commitTransaction();
1134 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001135}
1136
Mathias Agopian13127d82013-03-05 17:47:11 -08001137void Layer::commitTransaction() {
1138 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001139}
1140
Mathias Agopian13127d82013-03-05 17:47:11 -08001141uint32_t Layer::getTransactionFlags(uint32_t flags) {
1142 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1143}
1144
1145uint32_t Layer::setTransactionFlags(uint32_t flags) {
1146 return android_atomic_or(flags, &mTransactionFlags);
1147}
1148
1149bool Layer::setPosition(float x, float y) {
1150 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1151 return false;
1152 mCurrentState.sequence++;
1153 mCurrentState.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001154 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001155 setTransactionFlags(eTransactionNeeded);
1156 return true;
1157}
1158bool Layer::setLayer(uint32_t z) {
1159 if (mCurrentState.z == z)
1160 return false;
1161 mCurrentState.sequence++;
1162 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001163 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001164 setTransactionFlags(eTransactionNeeded);
1165 return true;
1166}
1167bool Layer::setSize(uint32_t w, uint32_t h) {
1168 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1169 return false;
1170 mCurrentState.requested.w = w;
1171 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001172 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001173 setTransactionFlags(eTransactionNeeded);
1174 return true;
1175}
1176bool Layer::setAlpha(uint8_t alpha) {
1177 if (mCurrentState.alpha == alpha)
1178 return false;
1179 mCurrentState.sequence++;
1180 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001181 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001182 setTransactionFlags(eTransactionNeeded);
1183 return true;
1184}
1185bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1186 mCurrentState.sequence++;
1187 mCurrentState.transform.set(
1188 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001189 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001190 setTransactionFlags(eTransactionNeeded);
1191 return true;
1192}
1193bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001194 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001195 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001196 setTransactionFlags(eTransactionNeeded);
1197 return true;
1198}
1199bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1200 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1201 if (mCurrentState.flags == newFlags)
1202 return false;
1203 mCurrentState.sequence++;
1204 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001205 mCurrentState.mask = mask;
1206 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001207 setTransactionFlags(eTransactionNeeded);
1208 return true;
1209}
1210bool Layer::setCrop(const Rect& crop) {
1211 if (mCurrentState.requested.crop == crop)
1212 return false;
1213 mCurrentState.sequence++;
1214 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001215 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001216 setTransactionFlags(eTransactionNeeded);
1217 return true;
1218}
1219
1220bool Layer::setLayerStack(uint32_t layerStack) {
1221 if (mCurrentState.layerStack == layerStack)
1222 return false;
1223 mCurrentState.sequence++;
1224 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001225 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001226 setTransactionFlags(eTransactionNeeded);
1227 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001228}
1229
Dan Stoza7dde5992015-05-22 09:51:44 -07001230void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1231 uint64_t frameNumber) {
1232 mCurrentState.handle = handle;
1233 mCurrentState.frameNumber = frameNumber;
1234 // We don't set eTransactionNeeded, because just receiving a deferral
1235 // request without any other state updates shouldn't actually induce a delay
1236 mCurrentState.modified = true;
1237 pushPendingState();
1238 mCurrentState.modified = false;
1239}
1240
Dan Stozaee44edd2015-03-23 15:50:23 -07001241void Layer::useSurfaceDamage() {
1242 if (mFlinger->mForceFullDamage) {
1243 surfaceDamageRegion = Region::INVALID_REGION;
1244 } else {
1245 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1246 }
1247}
1248
1249void Layer::useEmptyDamage() {
1250 surfaceDamageRegion.clear();
1251}
1252
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001253// ----------------------------------------------------------------------------
1254// pageflip handling...
1255// ----------------------------------------------------------------------------
1256
Dan Stoza6b9454d2014-11-07 16:00:59 -08001257bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballos06312182015-10-07 16:32:12 -07001258 if (mSidebandStreamChanged || mSingleBufferMode) {
Dan Stozad87defa2015-07-29 16:15:50 -07001259 return true;
1260 }
1261
Dan Stoza6b9454d2014-11-07 16:00:59 -08001262 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001263 if (mQueueItems.empty()) {
1264 return false;
1265 }
1266 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001267 nsecs_t expectedPresent =
1268 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001269
1270 // Ignore timestamps more than a second in the future
1271 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1272 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1273 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1274 expectedPresent);
1275
1276 bool isDue = timestamp < expectedPresent;
1277 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001278}
1279
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001280bool Layer::onPreComposition() {
1281 mRefreshPending = false;
Pablo Ceballos06312182015-10-07 16:32:12 -07001282 return mQueuedFrames > 0 || mSidebandStreamChanged || mSingleBufferMode;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001283}
1284
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001285void Layer::onPostComposition() {
1286 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001287 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001288 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1289
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001290 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001291 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001292 mFrameTracker.setFrameReadyFence(frameReadyFence);
1293 } else {
1294 // There was no fence for this frame, so assume that it was ready
1295 // to be presented at the desired present time.
1296 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1297 }
1298
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001299 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001300 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001301 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001302 mFrameTracker.setActualPresentFence(presentFence);
1303 } else {
1304 // The HWC doesn't support present fences, so use the refresh
1305 // timestamp instead.
1306 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1307 mFrameTracker.setActualPresentTime(presentTime);
1308 }
1309
1310 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001311 mFrameLatencyNeeded = false;
1312 }
1313}
1314
Mathias Agopianda27af92012-09-13 18:17:13 -07001315bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001316 const Layer::State& s(mDrawingState);
1317 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001318 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001319}
1320
Mathias Agopian4fec8732012-06-29 14:12:52 -07001321Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001322{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001323 ATRACE_CALL();
1324
Jesse Hall399184a2014-03-03 15:42:54 -08001325 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1326 // mSidebandStreamChanged was true
1327 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001328 if (mSidebandStream != NULL) {
1329 setTransactionFlags(eTransactionNeeded);
1330 mFlinger->setTransactionFlags(eTraversalNeeded);
1331 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001332 recomputeVisibleRegions = true;
1333
1334 const State& s(getDrawingState());
1335 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001336 }
1337
Mathias Agopian4fec8732012-06-29 14:12:52 -07001338 Region outDirtyRegion;
Pablo Ceballos06312182015-10-07 16:32:12 -07001339 if (mQueuedFrames > 0 || mSingleBufferMode) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001340
1341 // if we've already called updateTexImage() without going through
1342 // a composition step, we have to skip this layer at this point
1343 // because we cannot call updateTeximage() without a corresponding
1344 // compositionComplete() call.
1345 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001346 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001347 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001348 }
1349
Jamie Gennis351a5132011-09-14 18:23:37 -07001350 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001351 const State& s(getDrawingState());
1352 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001353 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001354
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001355 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001356 Layer::State& front;
1357 Layer::State& current;
1358 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001359 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001360 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001361 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001362 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001363 recomputeVisibleRegions(recomputeVisibleRegions),
1364 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001365 }
1366
1367 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001368 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001369 if (buf == NULL) {
1370 return false;
1371 }
1372
1373 uint32_t bufWidth = buf->getWidth();
1374 uint32_t bufHeight = buf->getHeight();
1375
1376 // check that we received a buffer of the right size
1377 // (Take the buffer's orientation into account)
1378 if (item.mTransform & Transform::ROT_90) {
1379 swap(bufWidth, bufHeight);
1380 }
1381
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001382 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1383 if (front.active != front.requested) {
1384
1385 if (isFixedSize ||
1386 (bufWidth == front.requested.w &&
1387 bufHeight == front.requested.h))
1388 {
1389 // Here we pretend the transaction happened by updating the
1390 // current and drawing states. Drawing state is only accessed
1391 // in this thread, no need to have it locked
1392 front.active = front.requested;
1393
1394 // We also need to update the current state so that
1395 // we don't end-up overwriting the drawing state with
1396 // this stale current state during the next transaction
1397 //
1398 // NOTE: We don't need to hold the transaction lock here
1399 // because State::active is only accessed from this thread.
1400 current.active = front.active;
1401
1402 // recompute visible region
1403 recomputeVisibleRegions = true;
1404 }
1405
1406 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001407 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001408 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1409 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001410 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001411 front.active.w, front.active.h,
1412 front.active.crop.left,
1413 front.active.crop.top,
1414 front.active.crop.right,
1415 front.active.crop.bottom,
1416 front.active.crop.getWidth(),
1417 front.active.crop.getHeight(),
1418 front.requested.w, front.requested.h,
1419 front.requested.crop.left,
1420 front.requested.crop.top,
1421 front.requested.crop.right,
1422 front.requested.crop.bottom,
1423 front.requested.crop.getWidth(),
1424 front.requested.crop.getHeight());
1425 }
1426
Ruben Brunk1681d952014-06-27 15:51:55 -07001427 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001428 if (front.active.w != bufWidth ||
1429 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001430 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001431 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1432 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001433 return true;
1434 }
1435 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001436
1437 // if the transparent region has changed (this test is
1438 // conservative, but that's fine, worst case we're doing
1439 // a bit of extra work), we latch the new one and we
1440 // trigger a visible-region recompute.
1441 if (!front.activeTransparentRegion.isTriviallyEqual(
1442 front.requestedTransparentRegion)) {
1443 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001444
1445 // We also need to update the current state so that
1446 // we don't end-up overwriting the drawing state with
1447 // this stale current state during the next transaction
1448 //
1449 // NOTE: We don't need to hold the transaction lock here
1450 // because State::active is only accessed from this thread.
1451 current.activeTransparentRegion = front.activeTransparentRegion;
1452
1453 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001454 recomputeVisibleRegions = true;
1455 }
1456
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001457 return false;
1458 }
1459 };
1460
Ruben Brunk1681d952014-06-27 15:51:55 -07001461 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1462 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001463
Dan Stozaa4650a52015-05-12 12:56:16 -07001464 uint64_t maxFrameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001465 uint64_t headFrameNumber = 0;
Dan Stozaa4650a52015-05-12 12:56:16 -07001466 {
1467 Mutex::Autolock lock(mQueueItemLock);
1468 maxFrameNumber = mLastFrameNumberReceived;
Dan Stoza7dde5992015-05-22 09:51:44 -07001469 if (!mQueueItems.empty()) {
1470 headFrameNumber = mQueueItems[0].mFrameNumber;
1471 }
1472 }
1473
1474 bool availableFramesEmpty = true;
1475 {
1476 Mutex::Autolock lock(mAvailableFrameMutex);
1477 availableFramesEmpty = mAvailableFrames.empty();
1478 }
1479 if (!availableFramesEmpty) {
1480 Mutex::Autolock lock(mAvailableFrameMutex);
1481 bool matchingFramesFound = false;
1482 bool allTransactionsApplied = true;
1483 for (auto& frame : mAvailableFrames) {
1484 if (headFrameNumber != frame->getFrameNumber()) {
1485 break;
1486 }
1487 matchingFramesFound = true;
1488 allTransactionsApplied &= frame->transactionIsApplied();
1489 }
1490 if (matchingFramesFound && !allTransactionsApplied) {
1491 mFlinger->signalLayerUpdate();
1492 return outDirtyRegion;
1493 }
Dan Stozaa4650a52015-05-12 12:56:16 -07001494 }
1495
Pablo Ceballos06312182015-10-07 16:32:12 -07001496 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1497 // of the buffer queue isn't modified when the buffer queue is returning
1498 // BufferItem's that weren't actually queued. This can happen in single
1499 // buffer mode.
1500 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001501 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballos06312182015-10-07 16:32:12 -07001502 mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer,
1503 maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001504 if (updateResult == BufferQueue::PRESENT_LATER) {
1505 // Producer doesn't want buffer to be displayed yet. Signal a
1506 // layer update so we check again at the next opportunity.
1507 mFlinger->signalLayerUpdate();
1508 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001509 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1510 // If the buffer has been rejected, remove it from the shadow queue
1511 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001512 if (queuedBuffer) {
1513 Mutex::Autolock lock(mQueueItemLock);
1514 mQueueItems.removeAt(0);
1515 android_atomic_dec(&mQueuedFrames);
1516 }
Dan Stozaecc50402015-04-28 14:42:06 -07001517 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001518 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1519 // This can occur if something goes wrong when trying to create the
1520 // EGLImage for this buffer. If this happens, the buffer has already
1521 // been released, so we need to clean up the queue and bug out
1522 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001523 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001524 Mutex::Autolock lock(mQueueItemLock);
1525 mQueueItems.clear();
1526 android_atomic_and(0, &mQueuedFrames);
1527 }
1528
1529 // Once we have hit this state, the shadow queue may no longer
1530 // correctly reflect the incoming BufferQueue's contents, so even if
1531 // updateTexImage starts working, the only safe course of action is
1532 // to continue to ignore updates.
1533 mUpdateTexImageFailed = true;
1534
1535 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001536 }
1537
Pablo Ceballos06312182015-10-07 16:32:12 -07001538 if (queuedBuffer) {
1539 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001540 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1541
Dan Stoza6b9454d2014-11-07 16:00:59 -08001542 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001543
1544 // Remove any stale buffers that have been dropped during
1545 // updateTexImage
1546 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1547 mQueueItems.removeAt(0);
1548 android_atomic_dec(&mQueuedFrames);
1549 }
1550
Dan Stoza6b9454d2014-11-07 16:00:59 -08001551 mQueueItems.removeAt(0);
1552 }
1553
Dan Stozaecc50402015-04-28 14:42:06 -07001554
Andy McFadden1585c4d2013-06-28 13:52:40 -07001555 // Decrement the queued-frames count. Signal another event if we
1556 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001557 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
1558 || mSingleBufferMode) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001559 mFlinger->signalLayerUpdate();
1560 }
1561
Dan Stoza7dde5992015-05-22 09:51:44 -07001562 if (!availableFramesEmpty) {
1563 Mutex::Autolock lock(mAvailableFrameMutex);
1564 auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1565 while (!mAvailableFrames.empty() &&
1566 frameNumber == mAvailableFrames.front()->getFrameNumber()) {
1567 mAvailableFrames.pop_front();
1568 }
1569 }
1570
Andy McFadden1585c4d2013-06-28 13:52:40 -07001571 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001572 // something happened!
1573 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001574 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001575 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001576
Jamie Gennis351a5132011-09-14 18:23:37 -07001577 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001578 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001579 if (mActiveBuffer == NULL) {
1580 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001581 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001582 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001583
Mathias Agopian4824d402012-06-04 18:16:30 -07001584 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001585 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001586 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001587 // the first time we receive a buffer, we need to trigger a
1588 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001589 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001590 }
1591
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001592 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1593 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1594 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001595 if ((crop != mCurrentCrop) ||
1596 (transform != mCurrentTransform) ||
1597 (scalingMode != mCurrentScalingMode))
1598 {
1599 mCurrentCrop = crop;
1600 mCurrentTransform = transform;
1601 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001602 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001603 }
1604
1605 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001606 uint32_t bufWidth = mActiveBuffer->getWidth();
1607 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001608 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1609 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001610 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001611 }
1612 }
1613
1614 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001615 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001616 recomputeVisibleRegions = true;
1617 }
1618
Mathias Agopian4fec8732012-06-29 14:12:52 -07001619 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001620 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001621
1622 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001623 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001624 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001625 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001626}
1627
Mathias Agopiana67932f2011-04-20 14:20:59 -07001628uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001629{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001630 // TODO: should we do something special if mSecure is set?
1631 if (mProtectedByApp) {
1632 // need a hardware-protected path to external video sink
1633 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001634 }
Riley Andrews03414a12014-07-01 14:22:59 -07001635 if (mPotentialCursor) {
1636 usage |= GraphicBuffer::USAGE_CURSOR;
1637 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001638 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001639 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001640}
1641
Mathias Agopian84300952012-11-21 16:02:13 -08001642void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001643 uint32_t orientation = 0;
1644 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001645 // The transform hint is used to improve performance, but we can
1646 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001647 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001648 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001649 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001650 if (orientation & Transform::ROT_INVALID) {
1651 orientation = 0;
1652 }
1653 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001654 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001655}
1656
Mathias Agopian13127d82013-03-05 17:47:11 -08001657// ----------------------------------------------------------------------------
1658// debugging
1659// ----------------------------------------------------------------------------
1660
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001661void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001662{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001663 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001664
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001665 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001666 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001667 "+ %s %p (%s)\n",
1668 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001669 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001670
Mathias Agopian2ca79392013-04-02 18:30:32 -07001671 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001672 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001673 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001674 sp<Client> client(mClientRef.promote());
1675
Mathias Agopian74d211a2013-04-22 16:55:35 +02001676 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001677 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1678 "isOpaque=%1d, invalidate=%1d, "
1679 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1680 " client=%p\n",
1681 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1682 s.active.crop.left, s.active.crop.top,
1683 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001684 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001685 s.alpha, s.flags,
1686 s.transform[0][0], s.transform[0][1],
1687 s.transform[1][0], s.transform[1][1],
1688 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001689
1690 sp<const GraphicBuffer> buf0(mActiveBuffer);
1691 uint32_t w0=0, h0=0, s0=0, f0=0;
1692 if (buf0 != 0) {
1693 w0 = buf0->getWidth();
1694 h0 = buf0->getHeight();
1695 s0 = buf0->getStride();
1696 f0 = buf0->format;
1697 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001698 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001699 " "
1700 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1701 " queued-frames=%d, mRefreshPending=%d\n",
1702 mFormat, w0, h0, s0,f0,
1703 mQueuedFrames, mRefreshPending);
1704
Mathias Agopian13127d82013-03-05 17:47:11 -08001705 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001706 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001707 }
1708}
1709
Svetoslavd85084b2014-03-20 10:28:31 -07001710void Layer::dumpFrameStats(String8& result) const {
1711 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001712}
1713
Svetoslavd85084b2014-03-20 10:28:31 -07001714void Layer::clearFrameStats() {
1715 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001716}
1717
Jamie Gennis6547ff42013-07-16 20:12:42 -07001718void Layer::logFrameStats() {
1719 mFrameTracker.logAndResetStats(mName);
1720}
1721
Svetoslavd85084b2014-03-20 10:28:31 -07001722void Layer::getFrameStats(FrameStats* outStats) const {
1723 mFrameTracker.getStats(outStats);
1724}
1725
Mathias Agopian13127d82013-03-05 17:47:11 -08001726// ---------------------------------------------------------------------------
1727
1728Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1729 const sp<Layer>& layer)
1730 : mFlinger(flinger), mLayer(layer) {
1731}
1732
1733Layer::LayerCleaner::~LayerCleaner() {
1734 // destroy client resources
1735 mFlinger->onLayerDestroyed(mLayer);
1736}
1737
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001738// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001739}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001740
1741#if defined(__gl_h_)
1742#error "don't include gl/gl.h in this file"
1743#endif
1744
1745#if defined(__gl2_h_)
1746#error "don't include gl2/gl2.h in this file"
1747#endif