blob: 04256e11267d04cba4d1d081884cca7b450a6551 [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
Dan Stoza9e56aa02015-11-02 13:00:03 -080017//#define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "Layer"
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080020#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080022#include <stdlib.h>
23#include <stdint.h>
24#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080025#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026
Mathias Agopiana67932f2011-04-20 14:20:59 -070027#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070028#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070029#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080030
31#include <utils/Errors.h>
32#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080033#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080035#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080036
Mathias Agopian3330b202009-10-05 17:07:12 -070037#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080039
Dan Stoza6b9454d2014-11-07 16:00:59 -080040#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080041#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042
43#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020044#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070045#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070047#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049
Mathias Agopian1b031492012-06-20 17:51:20 -070050#include "DisplayHardware/HWComposer.h"
51
Mathias Agopian875d8e12013-06-07 15:35:48 -070052#include "RenderEngine/RenderEngine.h"
53
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080054#define DEBUG_RESIZE 0
55
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080056namespace android {
57
58// ---------------------------------------------------------------------------
59
Mathias Agopian13127d82013-03-05 17:47:11 -080060int32_t Layer::sSequence = 1;
61
Mathias Agopian4d9b8222013-03-12 17:11:48 -070062Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
63 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080064 : contentDirty(false),
65 sequence(uint32_t(android_atomic_inc(&sSequence))),
66 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070067 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mPremultipliedAlpha(true),
69 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080070 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080071 mTransactionFlags(0),
Dan Stoza7dde5992015-05-22 09:51:44 -070072 mPendingStateMutex(),
73 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070074 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080075 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070076 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070077 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070078 mCurrentOpacity(true),
Dan Stozacac35382016-01-27 12:21:06 -080079 mCurrentFrameNumber(0),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080080 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080081 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080082 mFiltering(false),
83 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070084 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080085 mProtectedByApp(false),
86 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070087 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070088 mPotentialCursor(false),
89 mQueueItemLock(),
90 mQueueItemCondition(),
91 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070092 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080093 mUpdateTexImageFailed(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080094 mAutoRefresh(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080095{
Dan Stoza9e56aa02015-11-02 13:00:03 -080096#ifdef USE_HWC2
97 ALOGV("Creating Layer %s", name.string());
98#endif
99
Mathias Agopiana67932f2011-04-20 14:20:59 -0700100 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -0700101 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -0700102 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700103
104 uint32_t layerFlags = 0;
105 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -0800106 layerFlags |= layer_state_t::eLayerHidden;
107 if (flags & ISurfaceComposerClient::eOpaque)
108 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700109 if (flags & ISurfaceComposerClient::eSecure)
110 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700111
112 if (flags & ISurfaceComposerClient::eNonPremultiplied)
113 mPremultipliedAlpha = false;
114
115 mName = name;
116
117 mCurrentState.active.w = w;
118 mCurrentState.active.h = h;
119 mCurrentState.active.crop.makeInvalid();
120 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800121#ifdef USE_HWC2
122 mCurrentState.alpha = 1.0f;
123#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700124 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800125#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700126 mCurrentState.layerStack = 0;
127 mCurrentState.flags = layerFlags;
128 mCurrentState.sequence = 0;
129 mCurrentState.transform.set(0, 0);
130 mCurrentState.requested = mCurrentState.active;
131
132 // drawing state & current state are identical
133 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700134
Dan Stoza9e56aa02015-11-02 13:00:03 -0800135#ifdef USE_HWC2
136 const auto& hwc = flinger->getHwComposer();
137 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
138 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
139#else
Jamie Gennis6547ff42013-07-16 20:12:42 -0700140 nsecs_t displayPeriod =
141 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800142#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700143 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800144}
145
Mathias Agopian3f844832013-08-07 21:24:32 -0700146void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800147 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700148 sp<IGraphicBufferProducer> producer;
149 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700150 BufferQueue::createBufferQueue(&producer, &consumer);
151 mProducer = new MonitoredProducer(producer, mFlinger);
152 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800153 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800154 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700155 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800156
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700157#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
158#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700159#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700160 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800161#endif
Andy McFadden69052052012-09-14 16:10:11 -0700162
Mathias Agopian84300952012-11-21 16:02:13 -0800163 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
164 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700165}
166
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700167Layer::~Layer() {
Dan Stozacac35382016-01-27 12:21:06 -0800168 for (auto& point : mRemoteSyncPoints) {
169 point->setTransactionApplied();
170 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700171 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700172 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700173}
174
Mathias Agopian13127d82013-03-05 17:47:11 -0800175// ---------------------------------------------------------------------------
176// callbacks
177// ---------------------------------------------------------------------------
178
Dan Stoza9e56aa02015-11-02 13:00:03 -0800179#ifdef USE_HWC2
180void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
181 if (mHwcLayers.empty()) {
182 return;
183 }
184 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
185}
186#else
Dan Stozac7014012014-02-14 15:03:43 -0800187void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800188 HWComposer::HWCLayerInterface* layer) {
189 if (layer) {
190 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700191 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800192 }
193}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800194#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800195
Dan Stoza6b9454d2014-11-07 16:00:59 -0800196void Layer::onFrameAvailable(const BufferItem& item) {
197 // Add this buffer from our internal queue tracker
198 { // Autolock scope
199 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700200
201 // Reset the frame number tracker when we receive the first buffer after
202 // a frame number reset
203 if (item.mFrameNumber == 1) {
204 mLastFrameNumberReceived = 0;
205 }
206
207 // Ensure that callbacks are handled in order
208 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
209 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
210 ms2ns(500));
211 if (result != NO_ERROR) {
212 ALOGE("[%s] Timed out waiting on callback", mName.string());
213 }
214 }
215
Dan Stoza6b9454d2014-11-07 16:00:59 -0800216 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700217 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700218
219 // Wake up any pending callbacks
220 mLastFrameNumberReceived = item.mFrameNumber;
221 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800222 }
223
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800224 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700225}
226
Dan Stoza6b9454d2014-11-07 16:00:59 -0800227void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700228 { // Autolock scope
229 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700230
Dan Stoza7dde5992015-05-22 09:51:44 -0700231 // Ensure that callbacks are handled in order
232 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
233 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
234 ms2ns(500));
235 if (result != NO_ERROR) {
236 ALOGE("[%s] Timed out waiting on callback", mName.string());
237 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700238 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700239
240 if (mQueueItems.empty()) {
241 ALOGE("Can't replace a frame on an empty queue");
242 return;
243 }
244 mQueueItems.editItemAt(0) = item;
245
246 // Wake up any pending callbacks
247 mLastFrameNumberReceived = item.mFrameNumber;
248 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700249 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800250}
251
Jesse Hall399184a2014-03-03 15:42:54 -0800252void Layer::onSidebandStreamChanged() {
253 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
254 // mSidebandStreamChanged was false
255 mFlinger->signalLayerUpdate();
256 }
257}
258
Mathias Agopian67106042013-03-14 19:18:13 -0700259// called with SurfaceFlinger::mStateLock from the drawing thread after
260// the layer has been remove from the current state list (and just before
261// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800262void Layer::onRemoved() {
Pablo Ceballose338df12015-12-03 11:44:46 -0800263 sp<Client> c(mClientRef.promote());
264 if (c != 0) {
265 c->detachLayer(this);
266 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800267 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700268}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700269
Mathias Agopian13127d82013-03-05 17:47:11 -0800270// ---------------------------------------------------------------------------
271// set-up
272// ---------------------------------------------------------------------------
273
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700274const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800275 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800276}
277
Mathias Agopianf9d93272009-06-19 17:00:27 -0700278status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800279 PixelFormat format, uint32_t flags)
280{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700281 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700282 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700283
284 // never allow a surface larger than what our underlying GL implementation
285 // can handle.
286 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800287 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700288 return BAD_VALUE;
289 }
290
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700291 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700292
Riley Andrews03414a12014-07-01 14:22:59 -0700293 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700294 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700295 mCurrentOpacity = getOpacityForFormat(format);
296
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800297 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
298 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
299 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700300
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800301 return NO_ERROR;
302}
303
Dan Stoza7dde5992015-05-22 09:51:44 -0700304/*
305 * The layer handle is just a BBinder object passed to the client
306 * (remote process) -- we don't keep any reference on our side such that
307 * the dtor is called when the remote side let go of its reference.
308 *
309 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
310 * this layer when the handle is destroyed.
311 */
312class Layer::Handle : public BBinder, public LayerCleaner {
313 public:
314 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
315 : LayerCleaner(flinger, layer), owner(layer) {}
316
317 wp<Layer> owner;
318};
319
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700320sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800321 Mutex::Autolock _l(mLock);
322
323 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700324 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800325
326 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700327
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700328 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800329}
330
Dan Stozab9b08832014-03-13 11:55:57 -0700331sp<IGraphicBufferProducer> Layer::getProducer() const {
332 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700333}
334
Mathias Agopian13127d82013-03-05 17:47:11 -0800335// ---------------------------------------------------------------------------
336// h/w composer set-up
337// ---------------------------------------------------------------------------
338
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800339Rect Layer::getContentCrop() const {
340 // this is the crop rectangle that applies to the buffer
341 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700342 Rect crop;
343 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800344 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700345 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800346 } else if (mActiveBuffer != NULL) {
347 // otherwise we use the whole buffer
348 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700349 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800350 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700351 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700352 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700353 return crop;
354}
355
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700356static Rect reduce(const Rect& win, const Region& exclude) {
357 if (CC_LIKELY(exclude.isEmpty())) {
358 return win;
359 }
360 if (exclude.isRect()) {
361 return win.reduce(exclude.getBounds());
362 }
363 return Region(win).subtract(exclude).getBounds();
364}
365
Mathias Agopian13127d82013-03-05 17:47:11 -0800366Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700367 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700368 return computeBounds(s.activeTransparentRegion);
369}
370
371Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
372 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800373 Rect win(s.active.w, s.active.h);
374 if (!s.active.crop.isEmpty()) {
375 win.intersect(s.active.crop, &win);
376 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700377 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700378 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800379}
380
Mathias Agopian6b442672013-07-09 21:24:52 -0700381FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800382 // the content crop is the area of the content that gets scaled to the
383 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700384 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800385
386 // the active.crop is the area of the window that gets cropped, but not
387 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700388 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800389
390 // apply the projection's clipping to the window crop in
391 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700392 // if there are no window scaling involved, this operation will map to full
393 // pixels in the buffer.
394 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
395 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700396
397 Rect activeCrop(s.active.w, s.active.h);
398 if (!s.active.crop.isEmpty()) {
399 activeCrop = s.active.crop;
400 }
401
402 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800403 activeCrop.intersect(hw->getViewport(), &activeCrop);
404 activeCrop = s.transform.inverse().transform(activeCrop);
405
Michael Lentine28ea2172014-11-19 18:32:37 -0800406 // This needs to be here as transform.transform(Rect) computes the
407 // transformed rect and then takes the bounding box of the result before
408 // returning. This means
409 // transform.inverse().transform(transform.transform(Rect)) != Rect
410 // in which case we need to make sure the final rect is clipped to the
411 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800412 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
413
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700414 // subtract the transparent region and snap to the bounds
415 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
416
Mathias Agopian13127d82013-03-05 17:47:11 -0800417 if (!activeCrop.isEmpty()) {
418 // Transform the window crop to match the buffer coordinate system,
419 // which means using the inverse of the current transform set on the
420 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700421 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700422 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
423 /*
424 * the code below applies the display's inverse transform to the buffer
425 */
426 uint32_t invTransformOrient = hw->getOrientationTransform();
427 // calculate the inverse transform
428 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
429 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
430 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700431 // If the transform has been rotated the axis of flip has been swapped
432 // so we need to swap which flip operations we are performing
433 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
434 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
435 if (is_h_flipped != is_v_flipped) {
436 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
437 NATIVE_WINDOW_TRANSFORM_FLIP_H;
438 }
Michael Lentinef7551402014-08-18 16:35:43 -0700439 }
440 // and apply to the current transform
441 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
442 }
443
Mathias Agopian13127d82013-03-05 17:47:11 -0800444 int winWidth = s.active.w;
445 int winHeight = s.active.h;
446 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700447 // If the activeCrop has been rotate the ends are rotated but not
448 // the space itself so when transforming ends back we can't rely on
449 // a modification of the axes of rotation. To account for this we
450 // need to reorient the inverse rotation in terms of the current
451 // axes of rotation.
452 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
453 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
454 if (is_h_flipped == is_v_flipped) {
455 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
456 NATIVE_WINDOW_TRANSFORM_FLIP_H;
457 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800458 winWidth = s.active.h;
459 winHeight = s.active.w;
460 }
461 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700462 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800463
Mathias Agopian6b442672013-07-09 21:24:52 -0700464 // below, crop is intersected with winCrop expressed in crop's coordinate space
465 float xScale = crop.getWidth() / float(winWidth);
466 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800467
Michael Lentinef7551402014-08-18 16:35:43 -0700468 float insetL = winCrop.left * xScale;
469 float insetT = winCrop.top * yScale;
470 float insetR = (winWidth - winCrop.right ) * xScale;
471 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800472
473 crop.left += insetL;
474 crop.top += insetT;
475 crop.right -= insetR;
476 crop.bottom -= insetB;
477 }
478 return crop;
479}
480
Dan Stoza9e56aa02015-11-02 13:00:03 -0800481#ifdef USE_HWC2
482void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
483#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700484void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700485 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700486 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800487#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700488{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800489#ifdef USE_HWC2
490 const auto hwcId = displayDevice->getHwcDisplayId();
491 auto& hwcInfo = mHwcLayers[hwcId];
492#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800493 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800494#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700495
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700496 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800497#ifdef USE_HWC2
498 hwcInfo.forceClientComposition = false;
499
500 if (isSecure() && !displayDevice->isSecure()) {
501 hwcInfo.forceClientComposition = true;
502 }
503
504 auto& hwcLayer = hwcInfo.layer;
505#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700506 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700507
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700508 if (isSecure() && !hw->isSecure()) {
509 layer.setSkip(true);
510 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800511#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700512
Mathias Agopian13127d82013-03-05 17:47:11 -0800513 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700514 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800515#ifdef USE_HWC2
516 if (!isOpaque(s) || s.alpha != 1.0f) {
517 auto blendMode = mPremultipliedAlpha ?
518 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
519 auto error = hwcLayer->setBlendMode(blendMode);
520 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
521 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
522 to_string(error).c_str(), static_cast<int32_t>(error));
523 }
524#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800525 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800526 layer.setBlending(mPremultipliedAlpha ?
527 HWC_BLENDING_PREMULT :
528 HWC_BLENDING_COVERAGE);
529 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800530#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800531
532 // apply the layer's transform, followed by the display's global transform
533 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700534 Region activeTransparentRegion(s.activeTransparentRegion);
535 if (!s.active.crop.isEmpty()) {
536 Rect activeCrop(s.active.crop);
537 activeCrop = s.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800538#ifdef USE_HWC2
539 activeCrop.intersect(displayDevice->getViewport(), &activeCrop);
540#else
Michael Lentine6c925ed2014-09-26 17:55:01 -0700541 activeCrop.intersect(hw->getViewport(), &activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800542#endif
Michael Lentine6c925ed2014-09-26 17:55:01 -0700543 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800544 // This needs to be here as transform.transform(Rect) computes the
545 // transformed rect and then takes the bounding box of the result before
546 // returning. This means
547 // transform.inverse().transform(transform.transform(Rect)) != Rect
548 // in which case we need to make sure the final rect is clipped to the
549 // display bounds.
550 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700551 // mark regions outside the crop as transparent
552 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
553 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
554 s.active.w, s.active.h));
555 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
556 activeCrop.left, activeCrop.bottom));
557 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
558 s.active.w, activeCrop.bottom));
559 }
560 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800561#ifdef USE_HWC2
562 frame.intersect(displayDevice->getViewport(), &frame);
563 const Transform& tr(displayDevice->getTransform());
564 Rect transformedFrame = tr.transform(frame);
565 auto error = hwcLayer->setDisplayFrame(transformedFrame);
566 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
567 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
568 transformedFrame.top, transformedFrame.right,
569 transformedFrame.bottom, to_string(error).c_str(),
570 static_cast<int32_t>(error));
571
572 FloatRect sourceCrop = computeCrop(displayDevice);
573 error = hwcLayer->setSourceCrop(sourceCrop);
574 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
575 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
576 sourceCrop.left, sourceCrop.top, sourceCrop.right,
577 sourceCrop.bottom, to_string(error).c_str(),
578 static_cast<int32_t>(error));
579
580 error = hwcLayer->setPlaneAlpha(s.alpha);
581 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
582 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
583 static_cast<int32_t>(error));
584
585 error = hwcLayer->setZOrder(s.z);
586 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
587 mName.string(), s.z, to_string(error).c_str(),
588 static_cast<int32_t>(error));
589#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800590 frame.intersect(hw->getViewport(), &frame);
591 const Transform& tr(hw->getTransform());
592 layer.setFrame(tr.transform(frame));
593 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800594 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800595#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800596
Mathias Agopian29a367b2011-07-12 14:51:45 -0700597 /*
598 * Transformations are applied in this order:
599 * 1) buffer orientation/flip/mirror
600 * 2) state transformation (window manager)
601 * 3) layer orientation (screen orientation)
602 * (NOTE: the matrices are multiplied in reverse order)
603 */
604
605 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700606 Transform transform(tr * s.transform * bufferOrientation);
607
608 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
609 /*
610 * the code below applies the display's inverse transform to the buffer
611 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800612#ifdef USE_HWC2
613 uint32_t invTransform = displayDevice->getOrientationTransform();
614#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700615 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800616#endif
Michael Lentine14409632014-08-19 11:27:30 -0700617 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700618 // calculate the inverse transform
619 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
620 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
621 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700622 // If the transform has been rotated the axis of flip has been swapped
623 // so we need to swap which flip operations we are performing
624 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
625 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
626 if (is_h_flipped != is_v_flipped) {
627 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
628 NATIVE_WINDOW_TRANSFORM_FLIP_H;
629 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700630 }
631 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700632 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700633 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700634
635 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800636 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800637#ifdef USE_HWC2
638 if (orientation & Transform::ROT_INVALID) {
639 // we can only handle simple transformation
640 hwcInfo.forceClientComposition = true;
641 } else {
642 auto transform = static_cast<HWC2::Transform>(orientation);
643 auto error = hwcLayer->setTransform(transform);
644 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
645 "%s (%d)", mName.string(), to_string(transform).c_str(),
646 to_string(error).c_str(), static_cast<int32_t>(error));
647 }
648#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800649 if (orientation & Transform::ROT_INVALID) {
650 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700651 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700652 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800653 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700654 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800655#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700656}
657
Dan Stoza9e56aa02015-11-02 13:00:03 -0800658#ifdef USE_HWC2
659void Layer::forceClientComposition(int32_t hwcId) {
660 if (mHwcLayers.count(hwcId) == 0) {
661 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
662 return;
663 }
664
665 mHwcLayers[hwcId].forceClientComposition = true;
666}
667#endif
668
669#ifdef USE_HWC2
670void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
671 // Apply this display's projection's viewport to the visible region
672 // before giving it to the HWC HAL.
673 const Transform& tr = displayDevice->getTransform();
674 const auto& viewport = displayDevice->getViewport();
675 Region visible = tr.transform(visibleRegion.intersect(viewport));
676 auto hwcId = displayDevice->getHwcDisplayId();
677 auto& hwcLayer = mHwcLayers[hwcId].layer;
678 auto error = hwcLayer->setVisibleRegion(visible);
679 if (error != HWC2::Error::None) {
680 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
681 to_string(error).c_str(), static_cast<int32_t>(error));
682 visible.dump(LOG_TAG);
683 }
684
685 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
686 if (error != HWC2::Error::None) {
687 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
688 to_string(error).c_str(), static_cast<int32_t>(error));
689 surfaceDamageRegion.dump(LOG_TAG);
690 }
691
692 auto compositionType = HWC2::Composition::Invalid;
693 if (mSidebandStream.get()) {
694 compositionType = HWC2::Composition::Sideband;
695 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
696 if (error != HWC2::Error::None) {
697 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
698 mName.string(), mSidebandStream->handle(),
699 to_string(error).c_str(), static_cast<int32_t>(error));
700 return;
701 }
702 } else {
703 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
704 compositionType = HWC2::Composition::Client;
705 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
706 if (error != HWC2::Error::None) {
707 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
708 to_string(error).c_str(), static_cast<int32_t>(error));
709 return;
710 }
711 } else {
712 if (mPotentialCursor) {
713 compositionType = HWC2::Composition::Cursor;
714 }
715 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
716 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
717 acquireFence);
718 if (error != HWC2::Error::None) {
719 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
720 mActiveBuffer->handle, to_string(error).c_str(),
721 static_cast<int32_t>(error));
722 return;
723 }
724 // If it's not a cursor, default to device composition
725 }
726 }
727
728 if (mHwcLayers[hwcId].forceClientComposition) {
729 ALOGV("[%s] Forcing Client composition", mName.string());
730 setCompositionType(hwcId, HWC2::Composition::Client);
731 } else if (compositionType != HWC2::Composition::Invalid) {
732 ALOGV("[%s] Requesting %s composition", mName.string(),
733 to_string(compositionType).c_str());
734 setCompositionType(hwcId, compositionType);
735 } else {
736 ALOGV("[%s] Requesting Device composition", mName.string());
737 setCompositionType(hwcId, HWC2::Composition::Device);
738 }
739}
740#else
Mathias Agopian42977342012-08-05 00:40:46 -0700741void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700742 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800743 // we have to set the visible region on every frame because
744 // we currently free it during onLayerDisplayed(), which is called
745 // after HWComposer::commit() -- every frame.
746 // Apply this display's projection's viewport to the visible region
747 // before giving it to the HWC HAL.
748 const Transform& tr = hw->getTransform();
749 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
750 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700751 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700752
Jesse Hall399184a2014-03-03 15:42:54 -0800753 if (mSidebandStream.get()) {
754 layer.setSidebandStream(mSidebandStream);
755 } else {
756 // NOTE: buffer can be NULL if the client never drew into this
757 // layer yet, or if we ran out of memory
758 layer.setBuffer(mActiveBuffer);
759 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700760}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800761#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700762
Dan Stoza9e56aa02015-11-02 13:00:03 -0800763#ifdef USE_HWC2
764void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
765 auto hwcId = displayDevice->getHwcDisplayId();
766 if (mHwcLayers.count(hwcId) == 0 ||
767 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
768 return;
769 }
770
771 // This gives us only the "orientation" component of the transform
772 const State& s(getCurrentState());
773
774 // Apply the layer's transform, followed by the display's global transform
775 // Here we're guaranteed that the layer's transform preserves rects
776 Rect win(s.active.w, s.active.h);
777 if (!s.active.crop.isEmpty()) {
778 win.intersect(s.active.crop, &win);
779 }
780 // Subtract the transparent region and snap to the bounds
781 Rect bounds = reduce(win, s.activeTransparentRegion);
782 Rect frame(s.transform.transform(bounds));
783 frame.intersect(displayDevice->getViewport(), &frame);
784 auto& displayTransform(displayDevice->getTransform());
785 auto position = displayTransform.transform(frame);
786
787 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
788 position.top);
789 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
790 "to (%d, %d): %s (%d)", mName.string(), position.left,
791 position.top, to_string(error).c_str(),
792 static_cast<int32_t>(error));
793}
794#else
Dan Stozac7014012014-02-14 15:03:43 -0800795void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700796 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700797 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700798
799 // TODO: there is a possible optimization here: we only need to set the
800 // acquire fence the first time a new buffer is acquired on EACH display.
801
Riley Andrews03414a12014-07-01 14:22:59 -0700802 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800803 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800804 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700805 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700806 if (fenceFd == -1) {
807 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
808 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700809 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700810 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700811 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700812}
813
Riley Andrews03414a12014-07-01 14:22:59 -0700814Rect Layer::getPosition(
815 const sp<const DisplayDevice>& hw)
816{
817 // this gives us only the "orientation" component of the transform
818 const State& s(getCurrentState());
819
820 // apply the layer's transform, followed by the display's global transform
821 // here we're guaranteed that the layer's transform preserves rects
822 Rect win(s.active.w, s.active.h);
823 if (!s.active.crop.isEmpty()) {
824 win.intersect(s.active.crop, &win);
825 }
826 // subtract the transparent region and snap to the bounds
827 Rect bounds = reduce(win, s.activeTransparentRegion);
828 Rect frame(s.transform.transform(bounds));
829 frame.intersect(hw->getViewport(), &frame);
830 const Transform& tr(hw->getTransform());
831 return Rect(tr.transform(frame));
832}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800833#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700834
Mathias Agopian13127d82013-03-05 17:47:11 -0800835// ---------------------------------------------------------------------------
836// drawing...
837// ---------------------------------------------------------------------------
838
839void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800840 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800841}
842
Dan Stozac7014012014-02-14 15:03:43 -0800843void Layer::draw(const sp<const DisplayDevice>& hw,
844 bool useIdentityTransform) const {
845 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800846}
847
Dan Stozac7014012014-02-14 15:03:43 -0800848void Layer::draw(const sp<const DisplayDevice>& hw) const {
849 onDraw(hw, Region(hw->bounds()), false);
850}
851
852void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
853 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800854{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800855 ATRACE_CALL();
856
Mathias Agopiana67932f2011-04-20 14:20:59 -0700857 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800858 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700859 // in fact never been drawn into. This happens frequently with
860 // SurfaceView because the WindowManager can't know when the client
861 // has drawn the first time.
862
863 // If there is nothing under us, we paint the screen in black, otherwise
864 // we just skip this update.
865
866 // figure out if there is something below us
867 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700868 const SurfaceFlinger::LayerVector& drawingLayers(
869 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700870 const size_t count = drawingLayers.size();
871 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800872 const sp<Layer>& layer(drawingLayers[i]);
873 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700874 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700875 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700876 }
877 // if not everything below us is covered, we plug the holes!
878 Region holes(clip.subtract(under));
879 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700880 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700881 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800882 return;
883 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700884
Andy McFadden97eba892012-12-11 15:21:45 -0800885 // Bind the current buffer to the GL texture, and wait for it to be
886 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800887 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
888 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800889 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700890 // Go ahead and draw the buffer anyway; no matter what we do the screen
891 // is probably going to have something visibly wrong.
892 }
893
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700894 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
895
Mathias Agopian875d8e12013-06-07 15:35:48 -0700896 RenderEngine& engine(mFlinger->getRenderEngine());
897
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700898 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700899 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700900 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700901
902 // Query the texture matrix given our current filtering mode.
903 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800904 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
905 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700906
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700907 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
908
909 /*
910 * the code below applies the display's inverse transform to the texture transform
911 */
912
913 // create a 4x4 transform matrix from the display transform flags
914 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
915 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
916 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
917
918 mat4 tr;
919 uint32_t transform = hw->getOrientationTransform();
920 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
921 tr = tr * rot90;
922 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
923 tr = tr * flipH;
924 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
925 tr = tr * flipV;
926
927 // calculate the inverse
928 tr = inverse(tr);
929
930 // and finally apply it to the original texture matrix
931 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
932 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
933 }
934
Jamie Genniscbb1a952012-05-08 17:05:52 -0700935 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700936 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
937 mTexture.setFiltering(useFiltering);
938 mTexture.setMatrix(textureMatrix);
939
940 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700941 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700942 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700943 }
Dan Stozac7014012014-02-14 15:03:43 -0800944 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700945 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800946}
947
Mathias Agopian13127d82013-03-05 17:47:11 -0800948
Dan Stozac7014012014-02-14 15:03:43 -0800949void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
950 const Region& /* clip */, float red, float green, float blue,
951 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800952{
Mathias Agopian19733a32013-08-28 18:13:56 -0700953 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800954 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700955 engine.setupFillWithColor(red, green, blue, alpha);
956 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800957}
958
959void Layer::clearWithOpenGL(
960 const sp<const DisplayDevice>& hw, const Region& clip) const {
961 clearWithOpenGL(hw, clip, 0,0,0,0);
962}
963
Dan Stozac7014012014-02-14 15:03:43 -0800964void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
965 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700966 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800967
Dan Stozac7014012014-02-14 15:03:43 -0800968 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800969
Mathias Agopian13127d82013-03-05 17:47:11 -0800970 /*
971 * NOTE: the way we compute the texture coordinates here produces
972 * different results than when we take the HWC path -- in the later case
973 * the "source crop" is rounded to texel boundaries.
974 * This can produce significantly different results when the texture
975 * is scaled by a large amount.
976 *
977 * The GL code below is more logical (imho), and the difference with
978 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700979 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800980 * GL composition when a buffer scaling is applied (maybe with some
981 * minimal value)? Or, we could make GL behave like HWC -- but this feel
982 * like more of a hack.
983 */
984 const Rect win(computeBounds());
985
Mathias Agopian3f844832013-08-07 21:24:32 -0700986 float left = float(win.left) / float(s.active.w);
987 float top = float(win.top) / float(s.active.h);
988 float right = float(win.right) / float(s.active.w);
989 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800990
Mathias Agopian875d8e12013-06-07 15:35:48 -0700991 // TODO: we probably want to generate the texture coords with the mesh
992 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700993 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
994 texCoords[0] = vec2(left, 1.0f - top);
995 texCoords[1] = vec2(left, 1.0f - bottom);
996 texCoords[2] = vec2(right, 1.0f - bottom);
997 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800998
Mathias Agopian875d8e12013-06-07 15:35:48 -0700999 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -08001000 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001001 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001002 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001003}
1004
Dan Stoza9e56aa02015-11-02 13:00:03 -08001005#ifdef USE_HWC2
1006void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1007 bool callIntoHwc) {
1008 if (mHwcLayers.count(hwcId) == 0) {
1009 ALOGE("setCompositionType called without a valid HWC layer");
1010 return;
1011 }
1012 auto& hwcInfo = mHwcLayers[hwcId];
1013 auto& hwcLayer = hwcInfo.layer;
1014 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1015 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1016 if (hwcInfo.compositionType != type) {
1017 ALOGV(" actually setting");
1018 hwcInfo.compositionType = type;
1019 if (callIntoHwc) {
1020 auto error = hwcLayer->setCompositionType(type);
1021 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1022 "composition type %s: %s (%d)", mName.string(),
1023 to_string(type).c_str(), to_string(error).c_str(),
1024 static_cast<int32_t>(error));
1025 }
1026 }
1027}
1028
1029HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1030 if (mHwcLayers.count(hwcId) == 0) {
1031 ALOGE("getCompositionType called without a valid HWC layer");
1032 return HWC2::Composition::Invalid;
1033 }
1034 return mHwcLayers.at(hwcId).compositionType;
1035}
1036
1037void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1038 if (mHwcLayers.count(hwcId) == 0) {
1039 ALOGE("setClearClientTarget called without a valid HWC layer");
1040 return;
1041 }
1042 mHwcLayers[hwcId].clearClientTarget = clear;
1043}
1044
1045bool Layer::getClearClientTarget(int32_t hwcId) const {
1046 if (mHwcLayers.count(hwcId) == 0) {
1047 ALOGE("getClearClientTarget called without a valid HWC layer");
1048 return false;
1049 }
1050 return mHwcLayers.at(hwcId).clearClientTarget;
1051}
1052#endif
1053
Ruben Brunk1681d952014-06-27 15:51:55 -07001054uint32_t Layer::getProducerStickyTransform() const {
1055 int producerStickyTransform = 0;
1056 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1057 if (ret != OK) {
1058 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1059 strerror(-ret), ret);
1060 return 0;
1061 }
1062 return static_cast<uint32_t>(producerStickyTransform);
1063}
1064
Dan Stozacac35382016-01-27 12:21:06 -08001065uint64_t Layer::getHeadFrameNumber() const {
1066 Mutex::Autolock lock(mQueueItemLock);
1067 if (!mQueueItems.empty()) {
1068 return mQueueItems[0].mFrameNumber;
1069 } else {
1070 return mCurrentFrameNumber;
1071 }
1072}
1073
1074bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1075 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1076 // Don't bother with a SyncPoint, since we've already latched the
1077 // relevant frame
1078 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001079 }
1080
Dan Stozacac35382016-01-27 12:21:06 -08001081 Mutex::Autolock lock(mLocalSyncPointMutex);
1082 mLocalSyncPoints.push_back(point);
1083 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001084}
1085
Mathias Agopian13127d82013-03-05 17:47:11 -08001086void Layer::setFiltering(bool filtering) {
1087 mFiltering = filtering;
1088}
1089
1090bool Layer::getFiltering() const {
1091 return mFiltering;
1092}
1093
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001094// As documented in libhardware header, formats in the range
1095// 0x100 - 0x1FF are specific to the HAL implementation, and
1096// are known to have no alpha channel
1097// TODO: move definition for device-specific range into
1098// hardware.h, instead of using hard-coded values here.
1099#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1100
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001101bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001102 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1103 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001104 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001105 switch (format) {
1106 case HAL_PIXEL_FORMAT_RGBA_8888:
1107 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001108 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001109 }
1110 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001111 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001112}
1113
Mathias Agopian13127d82013-03-05 17:47:11 -08001114// ----------------------------------------------------------------------------
1115// local state
1116// ----------------------------------------------------------------------------
1117
Dan Stozac7014012014-02-14 15:03:43 -08001118void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1119 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001120{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001121 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -08001122 const Transform tr(useIdentityTransform ?
1123 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -08001124 const uint32_t hw_h = hw->getHeight();
1125 Rect win(s.active.w, s.active.h);
1126 if (!s.active.crop.isEmpty()) {
1127 win.intersect(s.active.crop, &win);
1128 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001129 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001130 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001131
Mathias Agopianff2ed702013-09-01 21:36:12 -07001132 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1133 position[0] = tr.transform(win.left, win.top);
1134 position[1] = tr.transform(win.left, win.bottom);
1135 position[2] = tr.transform(win.right, win.bottom);
1136 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -07001137 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001138 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001139 }
1140}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001141
Andy McFadden4125a4f2014-01-29 17:17:11 -08001142bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001143{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001144 // if we don't have a buffer yet, we're translucent regardless of the
1145 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001146 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001147 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001148 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001149
1150 // if the layer has the opaque flag, then we're always opaque,
1151 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001152 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001153}
1154
Dan Stoza23116082015-06-18 14:58:39 -07001155bool Layer::isSecure() const
1156{
1157 const Layer::State& s(mDrawingState);
1158 return (s.flags & layer_state_t::eLayerSecure);
1159}
1160
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001161bool Layer::isProtected() const
1162{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001163 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001164 return (activeBuffer != 0) &&
1165 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1166}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001167
Mathias Agopian13127d82013-03-05 17:47:11 -08001168bool Layer::isFixedSize() const {
1169 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1170}
1171
1172bool Layer::isCropped() const {
1173 return !mCurrentCrop.isEmpty();
1174}
1175
1176bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1177 return mNeedsFiltering || hw->needsFiltering();
1178}
1179
1180void Layer::setVisibleRegion(const Region& visibleRegion) {
1181 // always called from main thread
1182 this->visibleRegion = visibleRegion;
1183}
1184
1185void Layer::setCoveredRegion(const Region& coveredRegion) {
1186 // always called from main thread
1187 this->coveredRegion = coveredRegion;
1188}
1189
1190void Layer::setVisibleNonTransparentRegion(const Region&
1191 setVisibleNonTransparentRegion) {
1192 // always called from main thread
1193 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1194}
1195
1196// ----------------------------------------------------------------------------
1197// transaction
1198// ----------------------------------------------------------------------------
1199
Dan Stoza7dde5992015-05-22 09:51:44 -07001200void Layer::pushPendingState() {
1201 if (!mCurrentState.modified) {
1202 return;
1203 }
1204
Dan Stoza7dde5992015-05-22 09:51:44 -07001205 // If this transaction is waiting on the receipt of a frame, generate a sync
1206 // point and send it to the remote layer.
1207 if (mCurrentState.handle != nullptr) {
1208 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1209 sp<Layer> handleLayer = handle->owner.promote();
1210 if (handleLayer == nullptr) {
1211 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1212 // If we can't promote the layer we are intended to wait on,
1213 // then it is expired or otherwise invalid. Allow this transaction
1214 // to be applied as per normal (no synchronization).
1215 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001216 } else {
1217 auto syncPoint = std::make_shared<SyncPoint>(
1218 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001219 if (handleLayer->addSyncPoint(syncPoint)) {
1220 mRemoteSyncPoints.push_back(std::move(syncPoint));
1221 } else {
1222 // We already missed the frame we're supposed to synchronize
1223 // on, so go ahead and apply the state update
1224 mCurrentState.handle = nullptr;
1225 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001226 }
1227
Dan Stoza7dde5992015-05-22 09:51:44 -07001228 // Wake us up to check if the frame has been received
1229 setTransactionFlags(eTransactionNeeded);
1230 }
1231 mPendingStates.push_back(mCurrentState);
1232}
1233
1234void Layer::popPendingState() {
1235 auto oldFlags = mCurrentState.flags;
1236 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001237 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001238 (mCurrentState.flags & mCurrentState.mask);
1239
1240 mPendingStates.removeAt(0);
1241}
1242
1243bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001244 bool stateUpdateAvailable = false;
1245 while (!mPendingStates.empty()) {
1246 if (mPendingStates[0].handle != nullptr) {
1247 if (mRemoteSyncPoints.empty()) {
1248 // If we don't have a sync point for this, apply it anyway. It
1249 // will be visually wrong, but it should keep us from getting
1250 // into too much trouble.
1251 ALOGE("[%s] No local sync point found", mName.string());
1252 popPendingState();
1253 stateUpdateAvailable = true;
1254 continue;
1255 }
1256
Dan Stozacac35382016-01-27 12:21:06 -08001257 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1258 mPendingStates[0].frameNumber) {
1259 ALOGE("[%s] Unexpected sync point frame number found",
1260 mName.string());
1261
1262 // Signal our end of the sync point and then dispose of it
1263 mRemoteSyncPoints.front()->setTransactionApplied();
1264 mRemoteSyncPoints.pop_front();
1265 continue;
1266 }
1267
Dan Stoza7dde5992015-05-22 09:51:44 -07001268 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1269 // Apply the state update
1270 popPendingState();
1271 stateUpdateAvailable = true;
1272
1273 // Signal our end of the sync point and then dispose of it
1274 mRemoteSyncPoints.front()->setTransactionApplied();
1275 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001276 } else {
1277 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001278 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001279 } else {
1280 popPendingState();
1281 stateUpdateAvailable = true;
1282 }
1283 }
1284
1285 // If we still have pending updates, wake SurfaceFlinger back up and point
1286 // it at this layer so we can process them
1287 if (!mPendingStates.empty()) {
1288 setTransactionFlags(eTransactionNeeded);
1289 mFlinger->setTransactionFlags(eTraversalNeeded);
1290 }
1291
1292 mCurrentState.modified = false;
1293 return stateUpdateAvailable;
1294}
1295
1296void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001297 auto headFrameNumber = getHeadFrameNumber();
1298 Mutex::Autolock lock(mLocalSyncPointMutex);
1299 for (auto& point : mLocalSyncPoints) {
1300 if (headFrameNumber >= point->getFrameNumber()) {
1301 point->setFrameAvailable();
1302 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001303 }
1304}
1305
Mathias Agopian13127d82013-03-05 17:47:11 -08001306uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001307 ATRACE_CALL();
1308
Dan Stoza7dde5992015-05-22 09:51:44 -07001309 pushPendingState();
1310 if (!applyPendingStates()) {
1311 return 0;
1312 }
1313
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001314 const Layer::State& s(getDrawingState());
1315 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001316
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001317 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1318 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001319
1320 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001321 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001322 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001323 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001324 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1325 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1326 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1327 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001328 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1329 c.active.w, c.active.h,
1330 c.active.crop.left,
1331 c.active.crop.top,
1332 c.active.crop.right,
1333 c.active.crop.bottom,
1334 c.active.crop.getWidth(),
1335 c.active.crop.getHeight(),
1336 c.requested.w, c.requested.h,
1337 c.requested.crop.left,
1338 c.requested.crop.top,
1339 c.requested.crop.right,
1340 c.requested.crop.bottom,
1341 c.requested.crop.getWidth(),
1342 c.requested.crop.getHeight(),
1343 s.active.w, s.active.h,
1344 s.active.crop.left,
1345 s.active.crop.top,
1346 s.active.crop.right,
1347 s.active.crop.bottom,
1348 s.active.crop.getWidth(),
1349 s.active.crop.getHeight(),
1350 s.requested.w, s.requested.h,
1351 s.requested.crop.left,
1352 s.requested.crop.top,
1353 s.requested.crop.right,
1354 s.requested.crop.bottom,
1355 s.requested.crop.getWidth(),
1356 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001357
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001358 // record the new size, form this point on, when the client request
1359 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001360 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001361 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001362 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001363
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001364 if (!isFixedSize()) {
1365
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001366 const bool resizePending = (c.requested.w != c.active.w) ||
1367 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001368
Dan Stoza9e9b0442015-04-22 14:59:08 -07001369 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001370 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001371 // if we have a pending resize, unless we are in fixed-size mode.
1372 // the drawing state will be updated only once we receive a buffer
1373 // with the correct size.
1374 //
1375 // in particular, we want to make sure the clip (which is part
1376 // of the geometry state) is latched together with the size but is
1377 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001378 //
1379 // If a sideband stream is attached, however, we want to skip this
1380 // optimization so that transactions aren't missed when a buffer
1381 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001382
1383 flags |= eDontUpdateGeometryState;
1384 }
1385 }
1386
Mathias Agopian13127d82013-03-05 17:47:11 -08001387 // always set active to requested, unless we're asked not to
1388 // this is used by Layer, which special cases resizes.
1389 if (flags & eDontUpdateGeometryState) {
1390 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001391 Layer::State& editCurrentState(getCurrentState());
1392 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001393 }
1394
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001395 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001396 // invalidate and recompute the visible regions if needed
1397 flags |= Layer::eVisibleRegion;
1398 }
1399
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001400 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001401 // invalidate and recompute the visible regions if needed
1402 flags |= eVisibleRegion;
1403 this->contentDirty = true;
1404
1405 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001406 const uint8_t type = c.transform.getType();
1407 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001408 (type >= Transform::SCALE));
1409 }
1410
1411 // Commit the transaction
1412 commitTransaction();
1413 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001414}
1415
Mathias Agopian13127d82013-03-05 17:47:11 -08001416void Layer::commitTransaction() {
1417 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001418}
1419
Mathias Agopian13127d82013-03-05 17:47:11 -08001420uint32_t Layer::getTransactionFlags(uint32_t flags) {
1421 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1422}
1423
1424uint32_t Layer::setTransactionFlags(uint32_t flags) {
1425 return android_atomic_or(flags, &mTransactionFlags);
1426}
1427
1428bool Layer::setPosition(float x, float y) {
1429 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1430 return false;
1431 mCurrentState.sequence++;
1432 mCurrentState.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001433 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001434 setTransactionFlags(eTransactionNeeded);
1435 return true;
1436}
1437bool Layer::setLayer(uint32_t z) {
1438 if (mCurrentState.z == z)
1439 return false;
1440 mCurrentState.sequence++;
1441 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001442 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001443 setTransactionFlags(eTransactionNeeded);
1444 return true;
1445}
1446bool Layer::setSize(uint32_t w, uint32_t h) {
1447 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1448 return false;
1449 mCurrentState.requested.w = w;
1450 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001451 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001452 setTransactionFlags(eTransactionNeeded);
1453 return true;
1454}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001455#ifdef USE_HWC2
1456bool Layer::setAlpha(float alpha) {
1457#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001458bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001459#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001460 if (mCurrentState.alpha == alpha)
1461 return false;
1462 mCurrentState.sequence++;
1463 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001464 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001465 setTransactionFlags(eTransactionNeeded);
1466 return true;
1467}
1468bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1469 mCurrentState.sequence++;
1470 mCurrentState.transform.set(
1471 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001472 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001473 setTransactionFlags(eTransactionNeeded);
1474 return true;
1475}
1476bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001477 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001478 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001479 setTransactionFlags(eTransactionNeeded);
1480 return true;
1481}
1482bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1483 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1484 if (mCurrentState.flags == newFlags)
1485 return false;
1486 mCurrentState.sequence++;
1487 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001488 mCurrentState.mask = mask;
1489 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001490 setTransactionFlags(eTransactionNeeded);
1491 return true;
1492}
1493bool Layer::setCrop(const Rect& crop) {
1494 if (mCurrentState.requested.crop == crop)
1495 return false;
1496 mCurrentState.sequence++;
1497 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001498 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001499 setTransactionFlags(eTransactionNeeded);
1500 return true;
1501}
1502
1503bool Layer::setLayerStack(uint32_t layerStack) {
1504 if (mCurrentState.layerStack == layerStack)
1505 return false;
1506 mCurrentState.sequence++;
1507 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001508 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001509 setTransactionFlags(eTransactionNeeded);
1510 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001511}
1512
Dan Stoza7dde5992015-05-22 09:51:44 -07001513void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1514 uint64_t frameNumber) {
1515 mCurrentState.handle = handle;
1516 mCurrentState.frameNumber = frameNumber;
1517 // We don't set eTransactionNeeded, because just receiving a deferral
1518 // request without any other state updates shouldn't actually induce a delay
1519 mCurrentState.modified = true;
1520 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001521 mCurrentState.handle = nullptr;
1522 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001523 mCurrentState.modified = false;
1524}
1525
Dan Stozaee44edd2015-03-23 15:50:23 -07001526void Layer::useSurfaceDamage() {
1527 if (mFlinger->mForceFullDamage) {
1528 surfaceDamageRegion = Region::INVALID_REGION;
1529 } else {
1530 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1531 }
1532}
1533
1534void Layer::useEmptyDamage() {
1535 surfaceDamageRegion.clear();
1536}
1537
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001538// ----------------------------------------------------------------------------
1539// pageflip handling...
1540// ----------------------------------------------------------------------------
1541
Dan Stoza6b9454d2014-11-07 16:00:59 -08001542bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001543 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001544 return true;
1545 }
1546
Dan Stoza6b9454d2014-11-07 16:00:59 -08001547 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001548 if (mQueueItems.empty()) {
1549 return false;
1550 }
1551 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001552 nsecs_t expectedPresent =
1553 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001554
1555 // Ignore timestamps more than a second in the future
1556 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1557 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1558 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1559 expectedPresent);
1560
1561 bool isDue = timestamp < expectedPresent;
1562 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001563}
1564
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001565bool Layer::onPreComposition() {
1566 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001567 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001568}
1569
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001570void Layer::onPostComposition() {
1571 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001572 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001573 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1574
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001575 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001576 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001577 mFrameTracker.setFrameReadyFence(frameReadyFence);
1578 } else {
1579 // There was no fence for this frame, so assume that it was ready
1580 // to be presented at the desired present time.
1581 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1582 }
1583
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001584 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001585#ifdef USE_HWC2
1586 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1587#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001588 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001589#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001590 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001591 mFrameTracker.setActualPresentFence(presentFence);
1592 } else {
1593 // The HWC doesn't support present fences, so use the refresh
1594 // timestamp instead.
1595 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1596 mFrameTracker.setActualPresentTime(presentTime);
1597 }
1598
1599 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001600 mFrameLatencyNeeded = false;
1601 }
1602}
1603
Dan Stoza9e56aa02015-11-02 13:00:03 -08001604#ifdef USE_HWC2
1605void Layer::releasePendingBuffer() {
1606 mSurfaceFlingerConsumer->releasePendingBuffer();
1607}
1608#endif
1609
Mathias Agopianda27af92012-09-13 18:17:13 -07001610bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001611 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001612#ifdef USE_HWC2
1613 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1614 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1615#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001616 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001617 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001618#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001619}
1620
Mathias Agopian4fec8732012-06-29 14:12:52 -07001621Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001622{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001623 ATRACE_CALL();
1624
Jesse Hall399184a2014-03-03 15:42:54 -08001625 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1626 // mSidebandStreamChanged was true
1627 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001628 if (mSidebandStream != NULL) {
1629 setTransactionFlags(eTransactionNeeded);
1630 mFlinger->setTransactionFlags(eTraversalNeeded);
1631 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001632 recomputeVisibleRegions = true;
1633
1634 const State& s(getDrawingState());
1635 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001636 }
1637
Mathias Agopian4fec8732012-06-29 14:12:52 -07001638 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001639 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001640
1641 // if we've already called updateTexImage() without going through
1642 // a composition step, we have to skip this layer at this point
1643 // because we cannot call updateTeximage() without a corresponding
1644 // compositionComplete() call.
1645 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001646 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001647 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001648 }
1649
Jamie Gennis351a5132011-09-14 18:23:37 -07001650 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001651 const State& s(getDrawingState());
1652 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001653 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001654
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001655 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001656 Layer::State& front;
1657 Layer::State& current;
1658 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001659 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001660 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001661 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001662 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001663 recomputeVisibleRegions(recomputeVisibleRegions),
1664 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001665 }
1666
1667 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001668 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001669 if (buf == NULL) {
1670 return false;
1671 }
1672
1673 uint32_t bufWidth = buf->getWidth();
1674 uint32_t bufHeight = buf->getHeight();
1675
1676 // check that we received a buffer of the right size
1677 // (Take the buffer's orientation into account)
1678 if (item.mTransform & Transform::ROT_90) {
1679 swap(bufWidth, bufHeight);
1680 }
1681
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001682 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1683 if (front.active != front.requested) {
1684
1685 if (isFixedSize ||
1686 (bufWidth == front.requested.w &&
1687 bufHeight == front.requested.h))
1688 {
1689 // Here we pretend the transaction happened by updating the
1690 // current and drawing states. Drawing state is only accessed
1691 // in this thread, no need to have it locked
1692 front.active = front.requested;
1693
1694 // We also need to update the current state so that
1695 // we don't end-up overwriting the drawing state with
1696 // this stale current state during the next transaction
1697 //
1698 // NOTE: We don't need to hold the transaction lock here
1699 // because State::active is only accessed from this thread.
1700 current.active = front.active;
1701
1702 // recompute visible region
1703 recomputeVisibleRegions = true;
1704 }
1705
1706 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001707 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001708 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1709 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001710 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001711 front.active.w, front.active.h,
1712 front.active.crop.left,
1713 front.active.crop.top,
1714 front.active.crop.right,
1715 front.active.crop.bottom,
1716 front.active.crop.getWidth(),
1717 front.active.crop.getHeight(),
1718 front.requested.w, front.requested.h,
1719 front.requested.crop.left,
1720 front.requested.crop.top,
1721 front.requested.crop.right,
1722 front.requested.crop.bottom,
1723 front.requested.crop.getWidth(),
1724 front.requested.crop.getHeight());
1725 }
1726
Ruben Brunk1681d952014-06-27 15:51:55 -07001727 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001728 if (front.active.w != bufWidth ||
1729 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001730 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001731 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1732 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001733 return true;
1734 }
1735 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001736
1737 // if the transparent region has changed (this test is
1738 // conservative, but that's fine, worst case we're doing
1739 // a bit of extra work), we latch the new one and we
1740 // trigger a visible-region recompute.
1741 if (!front.activeTransparentRegion.isTriviallyEqual(
1742 front.requestedTransparentRegion)) {
1743 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001744
1745 // We also need to update the current state so that
1746 // we don't end-up overwriting the drawing state with
1747 // this stale current state during the next transaction
1748 //
1749 // NOTE: We don't need to hold the transaction lock here
1750 // because State::active is only accessed from this thread.
1751 current.activeTransparentRegion = front.activeTransparentRegion;
1752
1753 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001754 recomputeVisibleRegions = true;
1755 }
1756
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001757 return false;
1758 }
1759 };
1760
Ruben Brunk1681d952014-06-27 15:51:55 -07001761 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1762 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001763
Dan Stozacac35382016-01-27 12:21:06 -08001764
1765 // Check all of our local sync points to ensure that all transactions
1766 // which need to have been applied prior to the frame which is about to
1767 // be latched have signaled
1768
1769 auto headFrameNumber = getHeadFrameNumber();
1770 bool matchingFramesFound = false;
1771 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001772 {
Dan Stozacac35382016-01-27 12:21:06 -08001773 Mutex::Autolock lock(mLocalSyncPointMutex);
1774 for (auto& point : mLocalSyncPoints) {
1775 if (point->getFrameNumber() > headFrameNumber) {
1776 break;
1777 }
1778
1779 matchingFramesFound = true;
1780
1781 if (!point->frameIsAvailable()) {
1782 // We haven't notified the remote layer that the frame for
1783 // this point is available yet. Notify it now, and then
1784 // abort this attempt to latch.
1785 point->setFrameAvailable();
1786 allTransactionsApplied = false;
1787 break;
1788 }
1789
1790 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001791 }
1792 }
1793
Dan Stozacac35382016-01-27 12:21:06 -08001794 if (matchingFramesFound && !allTransactionsApplied) {
1795 mFlinger->signalLayerUpdate();
1796 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001797 }
1798
Pablo Ceballos06312182015-10-07 16:32:12 -07001799 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1800 // of the buffer queue isn't modified when the buffer queue is returning
1801 // BufferItem's that weren't actually queued. This can happen in single
1802 // buffer mode.
1803 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001804 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001805 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001806 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001807 if (updateResult == BufferQueue::PRESENT_LATER) {
1808 // Producer doesn't want buffer to be displayed yet. Signal a
1809 // layer update so we check again at the next opportunity.
1810 mFlinger->signalLayerUpdate();
1811 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001812 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1813 // If the buffer has been rejected, remove it from the shadow queue
1814 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001815 if (queuedBuffer) {
1816 Mutex::Autolock lock(mQueueItemLock);
1817 mQueueItems.removeAt(0);
1818 android_atomic_dec(&mQueuedFrames);
1819 }
Dan Stozaecc50402015-04-28 14:42:06 -07001820 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001821 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1822 // This can occur if something goes wrong when trying to create the
1823 // EGLImage for this buffer. If this happens, the buffer has already
1824 // been released, so we need to clean up the queue and bug out
1825 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001826 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001827 Mutex::Autolock lock(mQueueItemLock);
1828 mQueueItems.clear();
1829 android_atomic_and(0, &mQueuedFrames);
1830 }
1831
1832 // Once we have hit this state, the shadow queue may no longer
1833 // correctly reflect the incoming BufferQueue's contents, so even if
1834 // updateTexImage starts working, the only safe course of action is
1835 // to continue to ignore updates.
1836 mUpdateTexImageFailed = true;
1837
1838 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001839 }
1840
Pablo Ceballos06312182015-10-07 16:32:12 -07001841 if (queuedBuffer) {
1842 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001843 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1844
Dan Stoza6b9454d2014-11-07 16:00:59 -08001845 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001846
1847 // Remove any stale buffers that have been dropped during
1848 // updateTexImage
1849 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1850 mQueueItems.removeAt(0);
1851 android_atomic_dec(&mQueuedFrames);
1852 }
1853
Dan Stoza6b9454d2014-11-07 16:00:59 -08001854 mQueueItems.removeAt(0);
1855 }
1856
Dan Stozaecc50402015-04-28 14:42:06 -07001857
Andy McFadden1585c4d2013-06-28 13:52:40 -07001858 // Decrement the queued-frames count. Signal another event if we
1859 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001860 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001861 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001862 mFlinger->signalLayerUpdate();
1863 }
1864
1865 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001866 // something happened!
1867 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001868 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001869 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001870
Jamie Gennis351a5132011-09-14 18:23:37 -07001871 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001872 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001873 if (mActiveBuffer == NULL) {
1874 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001875 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001876 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001877
Mathias Agopian4824d402012-06-04 18:16:30 -07001878 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001879 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001880 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001881 // the first time we receive a buffer, we need to trigger a
1882 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001883 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001884 }
1885
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001886 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1887 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1888 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001889 if ((crop != mCurrentCrop) ||
1890 (transform != mCurrentTransform) ||
1891 (scalingMode != mCurrentScalingMode))
1892 {
1893 mCurrentCrop = crop;
1894 mCurrentTransform = transform;
1895 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001896 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001897 }
1898
1899 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001900 uint32_t bufWidth = mActiveBuffer->getWidth();
1901 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001902 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1903 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001904 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001905 }
1906 }
1907
1908 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001909 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001910 recomputeVisibleRegions = true;
1911 }
1912
Dan Stozacac35382016-01-27 12:21:06 -08001913 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1914
1915 // Remove any sync points corresponding to the buffer which was just
1916 // latched
1917 {
1918 Mutex::Autolock lock(mLocalSyncPointMutex);
1919 auto point = mLocalSyncPoints.begin();
1920 while (point != mLocalSyncPoints.end()) {
1921 if (!(*point)->frameIsAvailable() ||
1922 !(*point)->transactionIsApplied()) {
1923 // This sync point must have been added since we started
1924 // latching. Don't drop it yet.
1925 ++point;
1926 continue;
1927 }
1928
1929 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1930 point = mLocalSyncPoints.erase(point);
1931 } else {
1932 ++point;
1933 }
1934 }
1935 }
1936
Mathias Agopian4fec8732012-06-29 14:12:52 -07001937 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001938 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001939
1940 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001941 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001942 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001943 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001944}
1945
Mathias Agopiana67932f2011-04-20 14:20:59 -07001946uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001947{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001948 // TODO: should we do something special if mSecure is set?
1949 if (mProtectedByApp) {
1950 // need a hardware-protected path to external video sink
1951 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001952 }
Riley Andrews03414a12014-07-01 14:22:59 -07001953 if (mPotentialCursor) {
1954 usage |= GraphicBuffer::USAGE_CURSOR;
1955 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001956 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001957 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001958}
1959
Mathias Agopian84300952012-11-21 16:02:13 -08001960void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001961 uint32_t orientation = 0;
1962 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001963 // The transform hint is used to improve performance, but we can
1964 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001965 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001966 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001967 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001968 if (orientation & Transform::ROT_INVALID) {
1969 orientation = 0;
1970 }
1971 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001972 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001973}
1974
Mathias Agopian13127d82013-03-05 17:47:11 -08001975// ----------------------------------------------------------------------------
1976// debugging
1977// ----------------------------------------------------------------------------
1978
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001979void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001980{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001981 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001982
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001983 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001984 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001985 "+ %s %p (%s)\n",
1986 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001987 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001988
Mathias Agopian2ca79392013-04-02 18:30:32 -07001989 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001990 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001991 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001992 sp<Client> client(mClientRef.promote());
1993
Mathias Agopian74d211a2013-04-22 16:55:35 +02001994 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001995 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1996 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08001997#ifdef USE_HWC2
1998 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1999#else
Mathias Agopian13127d82013-03-05 17:47:11 -08002000 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08002001#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002002 " client=%p\n",
2003 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
2004 s.active.crop.left, s.active.crop.top,
2005 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002006 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002007 s.alpha, s.flags,
2008 s.transform[0][0], s.transform[0][1],
2009 s.transform[1][0], s.transform[1][1],
2010 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002011
2012 sp<const GraphicBuffer> buf0(mActiveBuffer);
2013 uint32_t w0=0, h0=0, s0=0, f0=0;
2014 if (buf0 != 0) {
2015 w0 = buf0->getWidth();
2016 h0 = buf0->getHeight();
2017 s0 = buf0->getStride();
2018 f0 = buf0->format;
2019 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002020 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002021 " "
2022 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2023 " queued-frames=%d, mRefreshPending=%d\n",
2024 mFormat, w0, h0, s0,f0,
2025 mQueuedFrames, mRefreshPending);
2026
Mathias Agopian13127d82013-03-05 17:47:11 -08002027 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002028 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002029 }
2030}
2031
Svetoslavd85084b2014-03-20 10:28:31 -07002032void Layer::dumpFrameStats(String8& result) const {
2033 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002034}
2035
Svetoslavd85084b2014-03-20 10:28:31 -07002036void Layer::clearFrameStats() {
2037 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002038}
2039
Jamie Gennis6547ff42013-07-16 20:12:42 -07002040void Layer::logFrameStats() {
2041 mFrameTracker.logAndResetStats(mName);
2042}
2043
Svetoslavd85084b2014-03-20 10:28:31 -07002044void Layer::getFrameStats(FrameStats* outStats) const {
2045 mFrameTracker.getStats(outStats);
2046}
2047
Mathias Agopian13127d82013-03-05 17:47:11 -08002048// ---------------------------------------------------------------------------
2049
2050Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2051 const sp<Layer>& layer)
2052 : mFlinger(flinger), mLayer(layer) {
2053}
2054
2055Layer::LayerCleaner::~LayerCleaner() {
2056 // destroy client resources
2057 mFlinger->onLayerDestroyed(mLayer);
2058}
2059
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002060// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002061}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002062
2063#if defined(__gl_h_)
2064#error "don't include gl/gl.h in this file"
2065#endif
2066
2067#if defined(__gl2_h_)
2068#error "don't include gl2/gl2.h in this file"
2069#endif