blob: 99f0f0b725d21b1d5f5340e7fff633917a05310d [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;
Robert Carr3dcabfa2016-03-01 18:36:58 -0800119 mCurrentState.active.transform.set(0, 0);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700120 mCurrentState.active.crop.makeInvalid();
121 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800122#ifdef USE_HWC2
123 mCurrentState.alpha = 1.0f;
124#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700125 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800126#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700127 mCurrentState.layerStack = 0;
128 mCurrentState.flags = layerFlags;
129 mCurrentState.sequence = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700130 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() {
Pablo Ceballos8ea4e7b2016-03-03 15:20:02 -0800168 sp<Client> c(mClientRef.promote());
169 if (c != 0) {
170 c->detachLayer(this);
171 }
172
Dan Stozacac35382016-01-27 12:21:06 -0800173 for (auto& point : mRemoteSyncPoints) {
174 point->setTransactionApplied();
175 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700176 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700177 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700178}
179
Mathias Agopian13127d82013-03-05 17:47:11 -0800180// ---------------------------------------------------------------------------
181// callbacks
182// ---------------------------------------------------------------------------
183
Dan Stoza9e56aa02015-11-02 13:00:03 -0800184#ifdef USE_HWC2
185void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
186 if (mHwcLayers.empty()) {
187 return;
188 }
189 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
190}
191#else
Dan Stozac7014012014-02-14 15:03:43 -0800192void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800193 HWComposer::HWCLayerInterface* layer) {
194 if (layer) {
195 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700196 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800197 }
198}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800199#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800200
Dan Stoza6b9454d2014-11-07 16:00:59 -0800201void Layer::onFrameAvailable(const BufferItem& item) {
202 // Add this buffer from our internal queue tracker
203 { // Autolock scope
204 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700205
206 // Reset the frame number tracker when we receive the first buffer after
207 // a frame number reset
208 if (item.mFrameNumber == 1) {
209 mLastFrameNumberReceived = 0;
210 }
211
212 // Ensure that callbacks are handled in order
213 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
214 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
215 ms2ns(500));
216 if (result != NO_ERROR) {
217 ALOGE("[%s] Timed out waiting on callback", mName.string());
218 }
219 }
220
Dan Stoza6b9454d2014-11-07 16:00:59 -0800221 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700222 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700223
224 // Wake up any pending callbacks
225 mLastFrameNumberReceived = item.mFrameNumber;
226 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800227 }
228
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800229 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700230}
231
Dan Stoza6b9454d2014-11-07 16:00:59 -0800232void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700233 { // Autolock scope
234 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700235
Dan Stoza7dde5992015-05-22 09:51:44 -0700236 // Ensure that callbacks are handled in order
237 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
238 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
239 ms2ns(500));
240 if (result != NO_ERROR) {
241 ALOGE("[%s] Timed out waiting on callback", mName.string());
242 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700243 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700244
245 if (mQueueItems.empty()) {
246 ALOGE("Can't replace a frame on an empty queue");
247 return;
248 }
249 mQueueItems.editItemAt(0) = item;
250
251 // Wake up any pending callbacks
252 mLastFrameNumberReceived = item.mFrameNumber;
253 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700254 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800255}
256
Jesse Hall399184a2014-03-03 15:42:54 -0800257void Layer::onSidebandStreamChanged() {
258 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
259 // mSidebandStreamChanged was false
260 mFlinger->signalLayerUpdate();
261 }
262}
263
Mathias Agopian67106042013-03-14 19:18:13 -0700264// called with SurfaceFlinger::mStateLock from the drawing thread after
265// the layer has been remove from the current state list (and just before
266// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800267void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800268 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700269}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700270
Mathias Agopian13127d82013-03-05 17:47:11 -0800271// ---------------------------------------------------------------------------
272// set-up
273// ---------------------------------------------------------------------------
274
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700275const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800276 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800277}
278
Mathias Agopianf9d93272009-06-19 17:00:27 -0700279status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800280 PixelFormat format, uint32_t flags)
281{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700282 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700283 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700284
285 // never allow a surface larger than what our underlying GL implementation
286 // can handle.
287 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800288 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700289 return BAD_VALUE;
290 }
291
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700292 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700293
Riley Andrews03414a12014-07-01 14:22:59 -0700294 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700295 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700296 mCurrentOpacity = getOpacityForFormat(format);
297
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800298 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
299 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
300 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700301
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800302 return NO_ERROR;
303}
304
Dan Stoza7dde5992015-05-22 09:51:44 -0700305/*
306 * The layer handle is just a BBinder object passed to the client
307 * (remote process) -- we don't keep any reference on our side such that
308 * the dtor is called when the remote side let go of its reference.
309 *
310 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
311 * this layer when the handle is destroyed.
312 */
313class Layer::Handle : public BBinder, public LayerCleaner {
314 public:
315 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
316 : LayerCleaner(flinger, layer), owner(layer) {}
317
318 wp<Layer> owner;
319};
320
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700321sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800322 Mutex::Autolock _l(mLock);
323
324 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700325 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800326
327 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700328
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700329 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800330}
331
Dan Stozab9b08832014-03-13 11:55:57 -0700332sp<IGraphicBufferProducer> Layer::getProducer() const {
333 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700334}
335
Mathias Agopian13127d82013-03-05 17:47:11 -0800336// ---------------------------------------------------------------------------
337// h/w composer set-up
338// ---------------------------------------------------------------------------
339
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800340Rect Layer::getContentCrop() const {
341 // this is the crop rectangle that applies to the buffer
342 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700343 Rect crop;
344 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800345 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700346 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800347 } else if (mActiveBuffer != NULL) {
348 // otherwise we use the whole buffer
349 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700350 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800351 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700352 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700353 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700354 return crop;
355}
356
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700357static Rect reduce(const Rect& win, const Region& exclude) {
358 if (CC_LIKELY(exclude.isEmpty())) {
359 return win;
360 }
361 if (exclude.isRect()) {
362 return win.reduce(exclude.getBounds());
363 }
364 return Region(win).subtract(exclude).getBounds();
365}
366
Mathias Agopian13127d82013-03-05 17:47:11 -0800367Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700368 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700369 return computeBounds(s.activeTransparentRegion);
370}
371
372Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
373 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800374 Rect win(s.active.w, s.active.h);
375 if (!s.active.crop.isEmpty()) {
376 win.intersect(s.active.crop, &win);
377 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700378 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700379 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800380}
381
Mathias Agopian6b442672013-07-09 21:24:52 -0700382FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800383 // the content crop is the area of the content that gets scaled to the
384 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700385 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800386
387 // the active.crop is the area of the window that gets cropped, but not
388 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700389 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800390
391 // apply the projection's clipping to the window crop in
392 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700393 // if there are no window scaling involved, this operation will map to full
394 // pixels in the buffer.
395 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
396 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700397
398 Rect activeCrop(s.active.w, s.active.h);
399 if (!s.active.crop.isEmpty()) {
400 activeCrop = s.active.crop;
401 }
402
Robert Carr3dcabfa2016-03-01 18:36:58 -0800403 activeCrop = s.active.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800404 activeCrop.intersect(hw->getViewport(), &activeCrop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800405 activeCrop = s.active.transform.inverse().transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800406
Michael Lentine28ea2172014-11-19 18:32:37 -0800407 // This needs to be here as transform.transform(Rect) computes the
408 // transformed rect and then takes the bounding box of the result before
409 // returning. This means
410 // transform.inverse().transform(transform.transform(Rect)) != Rect
411 // in which case we need to make sure the final rect is clipped to the
412 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800413 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
414
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700415 // subtract the transparent region and snap to the bounds
416 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
417
Mathias Agopian13127d82013-03-05 17:47:11 -0800418 if (!activeCrop.isEmpty()) {
419 // Transform the window crop to match the buffer coordinate system,
420 // which means using the inverse of the current transform set on the
421 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700422 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700423 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
424 /*
425 * the code below applies the display's inverse transform to the buffer
426 */
427 uint32_t invTransformOrient = hw->getOrientationTransform();
428 // calculate the inverse transform
429 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
430 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
431 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700432 // If the transform has been rotated the axis of flip has been swapped
433 // so we need to swap which flip operations we are performing
434 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
435 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
436 if (is_h_flipped != is_v_flipped) {
437 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
438 NATIVE_WINDOW_TRANSFORM_FLIP_H;
439 }
Michael Lentinef7551402014-08-18 16:35:43 -0700440 }
441 // and apply to the current transform
442 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
443 }
444
Mathias Agopian13127d82013-03-05 17:47:11 -0800445 int winWidth = s.active.w;
446 int winHeight = s.active.h;
447 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700448 // If the activeCrop has been rotate the ends are rotated but not
449 // the space itself so when transforming ends back we can't rely on
450 // a modification of the axes of rotation. To account for this we
451 // need to reorient the inverse rotation in terms of the current
452 // axes of rotation.
453 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
454 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
455 if (is_h_flipped == is_v_flipped) {
456 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
457 NATIVE_WINDOW_TRANSFORM_FLIP_H;
458 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800459 winWidth = s.active.h;
460 winHeight = s.active.w;
461 }
462 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700463 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800464
Mathias Agopian6b442672013-07-09 21:24:52 -0700465 // below, crop is intersected with winCrop expressed in crop's coordinate space
466 float xScale = crop.getWidth() / float(winWidth);
467 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800468
Michael Lentinef7551402014-08-18 16:35:43 -0700469 float insetL = winCrop.left * xScale;
470 float insetT = winCrop.top * yScale;
471 float insetR = (winWidth - winCrop.right ) * xScale;
472 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800473
474 crop.left += insetL;
475 crop.top += insetT;
476 crop.right -= insetR;
477 crop.bottom -= insetB;
478 }
479 return crop;
480}
481
Dan Stoza9e56aa02015-11-02 13:00:03 -0800482#ifdef USE_HWC2
483void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
484#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700485void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700486 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700487 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800488#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700489{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800490#ifdef USE_HWC2
491 const auto hwcId = displayDevice->getHwcDisplayId();
492 auto& hwcInfo = mHwcLayers[hwcId];
493#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800494 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800495#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700496
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700497 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800498#ifdef USE_HWC2
499 hwcInfo.forceClientComposition = false;
500
501 if (isSecure() && !displayDevice->isSecure()) {
502 hwcInfo.forceClientComposition = true;
503 }
504
505 auto& hwcLayer = hwcInfo.layer;
506#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700507 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700508
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700509 if (isSecure() && !hw->isSecure()) {
510 layer.setSkip(true);
511 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800512#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700513
Mathias Agopian13127d82013-03-05 17:47:11 -0800514 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700515 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800516#ifdef USE_HWC2
517 if (!isOpaque(s) || s.alpha != 1.0f) {
518 auto blendMode = mPremultipliedAlpha ?
519 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
520 auto error = hwcLayer->setBlendMode(blendMode);
521 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
522 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
523 to_string(error).c_str(), static_cast<int32_t>(error));
524 }
525#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800526 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800527 layer.setBlending(mPremultipliedAlpha ?
528 HWC_BLENDING_PREMULT :
529 HWC_BLENDING_COVERAGE);
530 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800531#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800532
533 // apply the layer's transform, followed by the display's global transform
534 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700535 Region activeTransparentRegion(s.activeTransparentRegion);
536 if (!s.active.crop.isEmpty()) {
537 Rect activeCrop(s.active.crop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800538 activeCrop = s.active.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800539#ifdef USE_HWC2
540 activeCrop.intersect(displayDevice->getViewport(), &activeCrop);
541#else
Michael Lentine6c925ed2014-09-26 17:55:01 -0700542 activeCrop.intersect(hw->getViewport(), &activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800543#endif
Robert Carr3dcabfa2016-03-01 18:36:58 -0800544 activeCrop = s.active.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800545 // This needs to be here as transform.transform(Rect) computes the
546 // transformed rect and then takes the bounding box of the result before
547 // returning. This means
548 // transform.inverse().transform(transform.transform(Rect)) != Rect
549 // in which case we need to make sure the final rect is clipped to the
550 // display bounds.
551 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700552 // mark regions outside the crop as transparent
553 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
554 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
555 s.active.w, s.active.h));
556 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
557 activeCrop.left, activeCrop.bottom));
558 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
559 s.active.w, activeCrop.bottom));
560 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800561 Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800562#ifdef USE_HWC2
563 frame.intersect(displayDevice->getViewport(), &frame);
564 const Transform& tr(displayDevice->getTransform());
565 Rect transformedFrame = tr.transform(frame);
566 auto error = hwcLayer->setDisplayFrame(transformedFrame);
567 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
568 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
569 transformedFrame.top, transformedFrame.right,
570 transformedFrame.bottom, to_string(error).c_str(),
571 static_cast<int32_t>(error));
572
573 FloatRect sourceCrop = computeCrop(displayDevice);
574 error = hwcLayer->setSourceCrop(sourceCrop);
575 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
576 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
577 sourceCrop.left, sourceCrop.top, sourceCrop.right,
578 sourceCrop.bottom, to_string(error).c_str(),
579 static_cast<int32_t>(error));
580
581 error = hwcLayer->setPlaneAlpha(s.alpha);
582 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
583 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
584 static_cast<int32_t>(error));
585
586 error = hwcLayer->setZOrder(s.z);
587 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
588 mName.string(), s.z, to_string(error).c_str(),
589 static_cast<int32_t>(error));
590#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800591 frame.intersect(hw->getViewport(), &frame);
592 const Transform& tr(hw->getTransform());
593 layer.setFrame(tr.transform(frame));
594 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800595 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800596#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800597
Mathias Agopian29a367b2011-07-12 14:51:45 -0700598 /*
599 * Transformations are applied in this order:
600 * 1) buffer orientation/flip/mirror
601 * 2) state transformation (window manager)
602 * 3) layer orientation (screen orientation)
603 * (NOTE: the matrices are multiplied in reverse order)
604 */
605
606 const Transform bufferOrientation(mCurrentTransform);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800607 Transform transform(tr * s.active.transform * bufferOrientation);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700608
609 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
610 /*
611 * the code below applies the display's inverse transform to the buffer
612 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800613#ifdef USE_HWC2
614 uint32_t invTransform = displayDevice->getOrientationTransform();
615#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700616 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800617#endif
Michael Lentine14409632014-08-19 11:27:30 -0700618 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700619 // calculate the inverse transform
620 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
621 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
622 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700623 // If the transform has been rotated the axis of flip has been swapped
624 // so we need to swap which flip operations we are performing
625 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
626 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
627 if (is_h_flipped != is_v_flipped) {
628 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
629 NATIVE_WINDOW_TRANSFORM_FLIP_H;
630 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700631 }
632 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700633 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700634 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700635
636 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800637 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800638#ifdef USE_HWC2
639 if (orientation & Transform::ROT_INVALID) {
640 // we can only handle simple transformation
641 hwcInfo.forceClientComposition = true;
642 } else {
643 auto transform = static_cast<HWC2::Transform>(orientation);
644 auto error = hwcLayer->setTransform(transform);
645 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
646 "%s (%d)", mName.string(), to_string(transform).c_str(),
647 to_string(error).c_str(), static_cast<int32_t>(error));
648 }
649#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800650 if (orientation & Transform::ROT_INVALID) {
651 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700652 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700653 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800654 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700655 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800656#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700657}
658
Dan Stoza9e56aa02015-11-02 13:00:03 -0800659#ifdef USE_HWC2
660void Layer::forceClientComposition(int32_t hwcId) {
661 if (mHwcLayers.count(hwcId) == 0) {
662 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
663 return;
664 }
665
666 mHwcLayers[hwcId].forceClientComposition = true;
667}
668#endif
669
670#ifdef USE_HWC2
671void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
672 // Apply this display's projection's viewport to the visible region
673 // before giving it to the HWC HAL.
674 const Transform& tr = displayDevice->getTransform();
675 const auto& viewport = displayDevice->getViewport();
676 Region visible = tr.transform(visibleRegion.intersect(viewport));
677 auto hwcId = displayDevice->getHwcDisplayId();
678 auto& hwcLayer = mHwcLayers[hwcId].layer;
679 auto error = hwcLayer->setVisibleRegion(visible);
680 if (error != HWC2::Error::None) {
681 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
682 to_string(error).c_str(), static_cast<int32_t>(error));
683 visible.dump(LOG_TAG);
684 }
685
686 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
687 if (error != HWC2::Error::None) {
688 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
689 to_string(error).c_str(), static_cast<int32_t>(error));
690 surfaceDamageRegion.dump(LOG_TAG);
691 }
692
693 auto compositionType = HWC2::Composition::Invalid;
694 if (mSidebandStream.get()) {
695 compositionType = HWC2::Composition::Sideband;
696 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
697 if (error != HWC2::Error::None) {
698 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
699 mName.string(), mSidebandStream->handle(),
700 to_string(error).c_str(), static_cast<int32_t>(error));
701 return;
702 }
703 } else {
704 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
705 compositionType = HWC2::Composition::Client;
706 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
707 if (error != HWC2::Error::None) {
708 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
709 to_string(error).c_str(), static_cast<int32_t>(error));
710 return;
711 }
712 } else {
713 if (mPotentialCursor) {
714 compositionType = HWC2::Composition::Cursor;
715 }
716 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
717 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
718 acquireFence);
719 if (error != HWC2::Error::None) {
720 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
721 mActiveBuffer->handle, to_string(error).c_str(),
722 static_cast<int32_t>(error));
723 return;
724 }
725 // If it's not a cursor, default to device composition
726 }
727 }
728
729 if (mHwcLayers[hwcId].forceClientComposition) {
730 ALOGV("[%s] Forcing Client composition", mName.string());
731 setCompositionType(hwcId, HWC2::Composition::Client);
732 } else if (compositionType != HWC2::Composition::Invalid) {
733 ALOGV("[%s] Requesting %s composition", mName.string(),
734 to_string(compositionType).c_str());
735 setCompositionType(hwcId, compositionType);
736 } else {
737 ALOGV("[%s] Requesting Device composition", mName.string());
738 setCompositionType(hwcId, HWC2::Composition::Device);
739 }
740}
741#else
Mathias Agopian42977342012-08-05 00:40:46 -0700742void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700743 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800744 // we have to set the visible region on every frame because
745 // we currently free it during onLayerDisplayed(), which is called
746 // after HWComposer::commit() -- every frame.
747 // Apply this display's projection's viewport to the visible region
748 // before giving it to the HWC HAL.
749 const Transform& tr = hw->getTransform();
750 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
751 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700752 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700753
Jesse Hall399184a2014-03-03 15:42:54 -0800754 if (mSidebandStream.get()) {
755 layer.setSidebandStream(mSidebandStream);
756 } else {
757 // NOTE: buffer can be NULL if the client never drew into this
758 // layer yet, or if we ran out of memory
759 layer.setBuffer(mActiveBuffer);
760 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700761}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800762#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700763
Dan Stoza9e56aa02015-11-02 13:00:03 -0800764#ifdef USE_HWC2
765void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
766 auto hwcId = displayDevice->getHwcDisplayId();
767 if (mHwcLayers.count(hwcId) == 0 ||
768 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
769 return;
770 }
771
772 // This gives us only the "orientation" component of the transform
773 const State& s(getCurrentState());
774
775 // Apply the layer's transform, followed by the display's global transform
776 // Here we're guaranteed that the layer's transform preserves rects
777 Rect win(s.active.w, s.active.h);
778 if (!s.active.crop.isEmpty()) {
779 win.intersect(s.active.crop, &win);
780 }
781 // Subtract the transparent region and snap to the bounds
782 Rect bounds = reduce(win, s.activeTransparentRegion);
783 Rect frame(s.transform.transform(bounds));
784 frame.intersect(displayDevice->getViewport(), &frame);
785 auto& displayTransform(displayDevice->getTransform());
786 auto position = displayTransform.transform(frame);
787
788 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
789 position.top);
790 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
791 "to (%d, %d): %s (%d)", mName.string(), position.left,
792 position.top, to_string(error).c_str(),
793 static_cast<int32_t>(error));
794}
795#else
Dan Stozac7014012014-02-14 15:03:43 -0800796void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700797 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700798 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700799
800 // TODO: there is a possible optimization here: we only need to set the
801 // acquire fence the first time a new buffer is acquired on EACH display.
802
Riley Andrews03414a12014-07-01 14:22:59 -0700803 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800804 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800805 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700806 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700807 if (fenceFd == -1) {
808 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
809 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700810 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700811 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700812 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700813}
814
Riley Andrews03414a12014-07-01 14:22:59 -0700815Rect Layer::getPosition(
816 const sp<const DisplayDevice>& hw)
817{
818 // this gives us only the "orientation" component of the transform
819 const State& s(getCurrentState());
820
821 // apply the layer's transform, followed by the display's global transform
822 // here we're guaranteed that the layer's transform preserves rects
823 Rect win(s.active.w, s.active.h);
824 if (!s.active.crop.isEmpty()) {
825 win.intersect(s.active.crop, &win);
826 }
827 // subtract the transparent region and snap to the bounds
828 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800829 Rect frame(s.active.transform.transform(bounds));
Riley Andrews03414a12014-07-01 14:22:59 -0700830 frame.intersect(hw->getViewport(), &frame);
831 const Transform& tr(hw->getTransform());
832 return Rect(tr.transform(frame));
833}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800834#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700835
Mathias Agopian13127d82013-03-05 17:47:11 -0800836// ---------------------------------------------------------------------------
837// drawing...
838// ---------------------------------------------------------------------------
839
840void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800841 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800842}
843
Dan Stozac7014012014-02-14 15:03:43 -0800844void Layer::draw(const sp<const DisplayDevice>& hw,
845 bool useIdentityTransform) const {
846 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800847}
848
Dan Stozac7014012014-02-14 15:03:43 -0800849void Layer::draw(const sp<const DisplayDevice>& hw) const {
850 onDraw(hw, Region(hw->bounds()), false);
851}
852
853void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
854 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800855{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800856 ATRACE_CALL();
857
Mathias Agopiana67932f2011-04-20 14:20:59 -0700858 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800859 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700860 // in fact never been drawn into. This happens frequently with
861 // SurfaceView because the WindowManager can't know when the client
862 // has drawn the first time.
863
864 // If there is nothing under us, we paint the screen in black, otherwise
865 // we just skip this update.
866
867 // figure out if there is something below us
868 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700869 const SurfaceFlinger::LayerVector& drawingLayers(
870 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700871 const size_t count = drawingLayers.size();
872 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800873 const sp<Layer>& layer(drawingLayers[i]);
874 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700875 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700876 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700877 }
878 // if not everything below us is covered, we plug the holes!
879 Region holes(clip.subtract(under));
880 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700881 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700882 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800883 return;
884 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700885
Andy McFadden97eba892012-12-11 15:21:45 -0800886 // Bind the current buffer to the GL texture, and wait for it to be
887 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800888 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
889 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800890 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700891 // Go ahead and draw the buffer anyway; no matter what we do the screen
892 // is probably going to have something visibly wrong.
893 }
894
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700895 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
896
Mathias Agopian875d8e12013-06-07 15:35:48 -0700897 RenderEngine& engine(mFlinger->getRenderEngine());
898
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700899 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700900 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700901 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700902
903 // Query the texture matrix given our current filtering mode.
904 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800905 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
906 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700907
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700908 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
909
910 /*
911 * the code below applies the display's inverse transform to the texture transform
912 */
913
914 // create a 4x4 transform matrix from the display transform flags
915 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
916 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
917 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
918
919 mat4 tr;
920 uint32_t transform = hw->getOrientationTransform();
921 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
922 tr = tr * rot90;
923 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
924 tr = tr * flipH;
925 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
926 tr = tr * flipV;
927
928 // calculate the inverse
929 tr = inverse(tr);
930
931 // and finally apply it to the original texture matrix
932 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
933 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
934 }
935
Jamie Genniscbb1a952012-05-08 17:05:52 -0700936 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700937 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
938 mTexture.setFiltering(useFiltering);
939 mTexture.setMatrix(textureMatrix);
940
941 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700942 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700943 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700944 }
Dan Stozac7014012014-02-14 15:03:43 -0800945 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700946 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800947}
948
Mathias Agopian13127d82013-03-05 17:47:11 -0800949
Dan Stozac7014012014-02-14 15:03:43 -0800950void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
951 const Region& /* clip */, float red, float green, float blue,
952 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800953{
Mathias Agopian19733a32013-08-28 18:13:56 -0700954 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800955 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700956 engine.setupFillWithColor(red, green, blue, alpha);
957 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800958}
959
960void Layer::clearWithOpenGL(
961 const sp<const DisplayDevice>& hw, const Region& clip) const {
962 clearWithOpenGL(hw, clip, 0,0,0,0);
963}
964
Dan Stozac7014012014-02-14 15:03:43 -0800965void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
966 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700967 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800968
Dan Stozac7014012014-02-14 15:03:43 -0800969 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800970
Mathias Agopian13127d82013-03-05 17:47:11 -0800971 /*
972 * NOTE: the way we compute the texture coordinates here produces
973 * different results than when we take the HWC path -- in the later case
974 * the "source crop" is rounded to texel boundaries.
975 * This can produce significantly different results when the texture
976 * is scaled by a large amount.
977 *
978 * The GL code below is more logical (imho), and the difference with
979 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700980 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800981 * GL composition when a buffer scaling is applied (maybe with some
982 * minimal value)? Or, we could make GL behave like HWC -- but this feel
983 * like more of a hack.
984 */
985 const Rect win(computeBounds());
986
Mathias Agopian3f844832013-08-07 21:24:32 -0700987 float left = float(win.left) / float(s.active.w);
988 float top = float(win.top) / float(s.active.h);
989 float right = float(win.right) / float(s.active.w);
990 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800991
Mathias Agopian875d8e12013-06-07 15:35:48 -0700992 // TODO: we probably want to generate the texture coords with the mesh
993 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700994 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
995 texCoords[0] = vec2(left, 1.0f - top);
996 texCoords[1] = vec2(left, 1.0f - bottom);
997 texCoords[2] = vec2(right, 1.0f - bottom);
998 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800999
Mathias Agopian875d8e12013-06-07 15:35:48 -07001000 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -08001001 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001002 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001003 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001004}
1005
Dan Stoza9e56aa02015-11-02 13:00:03 -08001006#ifdef USE_HWC2
1007void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1008 bool callIntoHwc) {
1009 if (mHwcLayers.count(hwcId) == 0) {
1010 ALOGE("setCompositionType called without a valid HWC layer");
1011 return;
1012 }
1013 auto& hwcInfo = mHwcLayers[hwcId];
1014 auto& hwcLayer = hwcInfo.layer;
1015 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1016 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1017 if (hwcInfo.compositionType != type) {
1018 ALOGV(" actually setting");
1019 hwcInfo.compositionType = type;
1020 if (callIntoHwc) {
1021 auto error = hwcLayer->setCompositionType(type);
1022 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1023 "composition type %s: %s (%d)", mName.string(),
1024 to_string(type).c_str(), to_string(error).c_str(),
1025 static_cast<int32_t>(error));
1026 }
1027 }
1028}
1029
1030HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1031 if (mHwcLayers.count(hwcId) == 0) {
1032 ALOGE("getCompositionType called without a valid HWC layer");
1033 return HWC2::Composition::Invalid;
1034 }
1035 return mHwcLayers.at(hwcId).compositionType;
1036}
1037
1038void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1039 if (mHwcLayers.count(hwcId) == 0) {
1040 ALOGE("setClearClientTarget called without a valid HWC layer");
1041 return;
1042 }
1043 mHwcLayers[hwcId].clearClientTarget = clear;
1044}
1045
1046bool Layer::getClearClientTarget(int32_t hwcId) const {
1047 if (mHwcLayers.count(hwcId) == 0) {
1048 ALOGE("getClearClientTarget called without a valid HWC layer");
1049 return false;
1050 }
1051 return mHwcLayers.at(hwcId).clearClientTarget;
1052}
1053#endif
1054
Ruben Brunk1681d952014-06-27 15:51:55 -07001055uint32_t Layer::getProducerStickyTransform() const {
1056 int producerStickyTransform = 0;
1057 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1058 if (ret != OK) {
1059 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1060 strerror(-ret), ret);
1061 return 0;
1062 }
1063 return static_cast<uint32_t>(producerStickyTransform);
1064}
1065
Dan Stozacac35382016-01-27 12:21:06 -08001066uint64_t Layer::getHeadFrameNumber() const {
1067 Mutex::Autolock lock(mQueueItemLock);
1068 if (!mQueueItems.empty()) {
1069 return mQueueItems[0].mFrameNumber;
1070 } else {
1071 return mCurrentFrameNumber;
1072 }
1073}
1074
1075bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1076 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1077 // Don't bother with a SyncPoint, since we've already latched the
1078 // relevant frame
1079 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001080 }
1081
Dan Stozacac35382016-01-27 12:21:06 -08001082 Mutex::Autolock lock(mLocalSyncPointMutex);
1083 mLocalSyncPoints.push_back(point);
1084 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001085}
1086
Mathias Agopian13127d82013-03-05 17:47:11 -08001087void Layer::setFiltering(bool filtering) {
1088 mFiltering = filtering;
1089}
1090
1091bool Layer::getFiltering() const {
1092 return mFiltering;
1093}
1094
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001095// As documented in libhardware header, formats in the range
1096// 0x100 - 0x1FF are specific to the HAL implementation, and
1097// are known to have no alpha channel
1098// TODO: move definition for device-specific range into
1099// hardware.h, instead of using hard-coded values here.
1100#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1101
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001102bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001103 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1104 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001105 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001106 switch (format) {
1107 case HAL_PIXEL_FORMAT_RGBA_8888:
1108 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001109 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001110 }
1111 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001112 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001113}
1114
Mathias Agopian13127d82013-03-05 17:47:11 -08001115// ----------------------------------------------------------------------------
1116// local state
1117// ----------------------------------------------------------------------------
1118
Dan Stozac7014012014-02-14 15:03:43 -08001119void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1120 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001121{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001122 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -08001123 const Transform tr(useIdentityTransform ?
Robert Carr3dcabfa2016-03-01 18:36:58 -08001124 hw->getTransform() : hw->getTransform() * s.active.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -08001125 const uint32_t hw_h = hw->getHeight();
1126 Rect win(s.active.w, s.active.h);
1127 if (!s.active.crop.isEmpty()) {
1128 win.intersect(s.active.crop, &win);
1129 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001130 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001131 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001132
Mathias Agopianff2ed702013-09-01 21:36:12 -07001133 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1134 position[0] = tr.transform(win.left, win.top);
1135 position[1] = tr.transform(win.left, win.bottom);
1136 position[2] = tr.transform(win.right, win.bottom);
1137 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -07001138 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001139 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001140 }
1141}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001142
Andy McFadden4125a4f2014-01-29 17:17:11 -08001143bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001144{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001145 // if we don't have a buffer yet, we're translucent regardless of the
1146 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001147 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001148 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001149 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001150
1151 // if the layer has the opaque flag, then we're always opaque,
1152 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001153 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001154}
1155
Dan Stoza23116082015-06-18 14:58:39 -07001156bool Layer::isSecure() const
1157{
1158 const Layer::State& s(mDrawingState);
1159 return (s.flags & layer_state_t::eLayerSecure);
1160}
1161
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001162bool Layer::isProtected() const
1163{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001164 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001165 return (activeBuffer != 0) &&
1166 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1167}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001168
Mathias Agopian13127d82013-03-05 17:47:11 -08001169bool Layer::isFixedSize() const {
1170 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1171}
1172
1173bool Layer::isCropped() const {
1174 return !mCurrentCrop.isEmpty();
1175}
1176
1177bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1178 return mNeedsFiltering || hw->needsFiltering();
1179}
1180
1181void Layer::setVisibleRegion(const Region& visibleRegion) {
1182 // always called from main thread
1183 this->visibleRegion = visibleRegion;
1184}
1185
1186void Layer::setCoveredRegion(const Region& coveredRegion) {
1187 // always called from main thread
1188 this->coveredRegion = coveredRegion;
1189}
1190
1191void Layer::setVisibleNonTransparentRegion(const Region&
1192 setVisibleNonTransparentRegion) {
1193 // always called from main thread
1194 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1195}
1196
1197// ----------------------------------------------------------------------------
1198// transaction
1199// ----------------------------------------------------------------------------
1200
Dan Stoza7dde5992015-05-22 09:51:44 -07001201void Layer::pushPendingState() {
1202 if (!mCurrentState.modified) {
1203 return;
1204 }
1205
Dan Stoza7dde5992015-05-22 09:51:44 -07001206 // If this transaction is waiting on the receipt of a frame, generate a sync
1207 // point and send it to the remote layer.
1208 if (mCurrentState.handle != nullptr) {
1209 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1210 sp<Layer> handleLayer = handle->owner.promote();
1211 if (handleLayer == nullptr) {
1212 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1213 // If we can't promote the layer we are intended to wait on,
1214 // then it is expired or otherwise invalid. Allow this transaction
1215 // to be applied as per normal (no synchronization).
1216 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001217 } else {
1218 auto syncPoint = std::make_shared<SyncPoint>(
1219 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001220 if (handleLayer->addSyncPoint(syncPoint)) {
1221 mRemoteSyncPoints.push_back(std::move(syncPoint));
1222 } else {
1223 // We already missed the frame we're supposed to synchronize
1224 // on, so go ahead and apply the state update
1225 mCurrentState.handle = nullptr;
1226 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001227 }
1228
Dan Stoza7dde5992015-05-22 09:51:44 -07001229 // Wake us up to check if the frame has been received
1230 setTransactionFlags(eTransactionNeeded);
1231 }
1232 mPendingStates.push_back(mCurrentState);
1233}
1234
1235void Layer::popPendingState() {
1236 auto oldFlags = mCurrentState.flags;
1237 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001238 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001239 (mCurrentState.flags & mCurrentState.mask);
1240
1241 mPendingStates.removeAt(0);
1242}
1243
1244bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001245 bool stateUpdateAvailable = false;
1246 while (!mPendingStates.empty()) {
1247 if (mPendingStates[0].handle != nullptr) {
1248 if (mRemoteSyncPoints.empty()) {
1249 // If we don't have a sync point for this, apply it anyway. It
1250 // will be visually wrong, but it should keep us from getting
1251 // into too much trouble.
1252 ALOGE("[%s] No local sync point found", mName.string());
1253 popPendingState();
1254 stateUpdateAvailable = true;
1255 continue;
1256 }
1257
Dan Stozacac35382016-01-27 12:21:06 -08001258 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1259 mPendingStates[0].frameNumber) {
1260 ALOGE("[%s] Unexpected sync point frame number found",
1261 mName.string());
1262
1263 // Signal our end of the sync point and then dispose of it
1264 mRemoteSyncPoints.front()->setTransactionApplied();
1265 mRemoteSyncPoints.pop_front();
1266 continue;
1267 }
1268
Dan Stoza7dde5992015-05-22 09:51:44 -07001269 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1270 // Apply the state update
1271 popPendingState();
1272 stateUpdateAvailable = true;
1273
1274 // Signal our end of the sync point and then dispose of it
1275 mRemoteSyncPoints.front()->setTransactionApplied();
1276 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001277 } else {
1278 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001279 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001280 } else {
1281 popPendingState();
1282 stateUpdateAvailable = true;
1283 }
1284 }
1285
1286 // If we still have pending updates, wake SurfaceFlinger back up and point
1287 // it at this layer so we can process them
1288 if (!mPendingStates.empty()) {
1289 setTransactionFlags(eTransactionNeeded);
1290 mFlinger->setTransactionFlags(eTraversalNeeded);
1291 }
1292
1293 mCurrentState.modified = false;
1294 return stateUpdateAvailable;
1295}
1296
1297void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001298 auto headFrameNumber = getHeadFrameNumber();
1299 Mutex::Autolock lock(mLocalSyncPointMutex);
1300 for (auto& point : mLocalSyncPoints) {
1301 if (headFrameNumber >= point->getFrameNumber()) {
1302 point->setFrameAvailable();
1303 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001304 }
1305}
1306
Mathias Agopian13127d82013-03-05 17:47:11 -08001307uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001308 ATRACE_CALL();
1309
Dan Stoza7dde5992015-05-22 09:51:44 -07001310 pushPendingState();
1311 if (!applyPendingStates()) {
1312 return 0;
1313 }
1314
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001315 const Layer::State& s(getDrawingState());
1316 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001317
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001318 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1319 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001320
1321 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001322 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001323 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001324 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001325 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1326 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1327 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1328 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001329 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1330 c.active.w, c.active.h,
1331 c.active.crop.left,
1332 c.active.crop.top,
1333 c.active.crop.right,
1334 c.active.crop.bottom,
1335 c.active.crop.getWidth(),
1336 c.active.crop.getHeight(),
1337 c.requested.w, c.requested.h,
1338 c.requested.crop.left,
1339 c.requested.crop.top,
1340 c.requested.crop.right,
1341 c.requested.crop.bottom,
1342 c.requested.crop.getWidth(),
1343 c.requested.crop.getHeight(),
1344 s.active.w, s.active.h,
1345 s.active.crop.left,
1346 s.active.crop.top,
1347 s.active.crop.right,
1348 s.active.crop.bottom,
1349 s.active.crop.getWidth(),
1350 s.active.crop.getHeight(),
1351 s.requested.w, s.requested.h,
1352 s.requested.crop.left,
1353 s.requested.crop.top,
1354 s.requested.crop.right,
1355 s.requested.crop.bottom,
1356 s.requested.crop.getWidth(),
1357 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001358
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001359 // record the new size, form this point on, when the client request
1360 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001361 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001362 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001363 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001364
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001365 if (!isFixedSize()) {
1366
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001367 const bool resizePending = (c.requested.w != c.active.w) ||
1368 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001369
Dan Stoza9e9b0442015-04-22 14:59:08 -07001370 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001371 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001372 // if we have a pending resize, unless we are in fixed-size mode.
1373 // the drawing state will be updated only once we receive a buffer
1374 // with the correct size.
1375 //
1376 // in particular, we want to make sure the clip (which is part
1377 // of the geometry state) is latched together with the size but is
1378 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001379 //
1380 // If a sideband stream is attached, however, we want to skip this
1381 // optimization so that transactions aren't missed when a buffer
1382 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001383
1384 flags |= eDontUpdateGeometryState;
1385 }
1386 }
1387
Mathias Agopian13127d82013-03-05 17:47:11 -08001388 // always set active to requested, unless we're asked not to
1389 // this is used by Layer, which special cases resizes.
1390 if (flags & eDontUpdateGeometryState) {
1391 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001392 Layer::State& editCurrentState(getCurrentState());
1393 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001394 }
1395
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001396 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001397 // invalidate and recompute the visible regions if needed
1398 flags |= Layer::eVisibleRegion;
1399 }
1400
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001401 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001402 // invalidate and recompute the visible regions if needed
1403 flags |= eVisibleRegion;
1404 this->contentDirty = true;
1405
1406 // we may use linear filtering, if the matrix scales us
Robert Carr3dcabfa2016-03-01 18:36:58 -08001407 const uint8_t type = c.active.transform.getType();
1408 mNeedsFiltering = (!c.active.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001409 (type >= Transform::SCALE));
1410 }
1411
1412 // Commit the transaction
1413 commitTransaction();
1414 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001415}
1416
Mathias Agopian13127d82013-03-05 17:47:11 -08001417void Layer::commitTransaction() {
1418 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001419}
1420
Mathias Agopian13127d82013-03-05 17:47:11 -08001421uint32_t Layer::getTransactionFlags(uint32_t flags) {
1422 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1423}
1424
1425uint32_t Layer::setTransactionFlags(uint32_t flags) {
1426 return android_atomic_or(flags, &mTransactionFlags);
1427}
1428
1429bool Layer::setPosition(float x, float y) {
Robert Carr3dcabfa2016-03-01 18:36:58 -08001430 if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
Mathias Agopian13127d82013-03-05 17:47:11 -08001431 return false;
1432 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001433 mCurrentState.requested.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001434 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001435 setTransactionFlags(eTransactionNeeded);
1436 return true;
1437}
1438bool Layer::setLayer(uint32_t z) {
1439 if (mCurrentState.z == z)
1440 return false;
1441 mCurrentState.sequence++;
1442 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001443 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001444 setTransactionFlags(eTransactionNeeded);
1445 return true;
1446}
1447bool Layer::setSize(uint32_t w, uint32_t h) {
1448 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1449 return false;
1450 mCurrentState.requested.w = w;
1451 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001452 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001453 setTransactionFlags(eTransactionNeeded);
1454 return true;
1455}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001456#ifdef USE_HWC2
1457bool Layer::setAlpha(float alpha) {
1458#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001459bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001460#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001461 if (mCurrentState.alpha == alpha)
1462 return false;
1463 mCurrentState.sequence++;
1464 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001465 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001466 setTransactionFlags(eTransactionNeeded);
1467 return true;
1468}
1469bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1470 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001471 mCurrentState.requested.transform.set(
Mathias Agopian13127d82013-03-05 17:47:11 -08001472 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001473 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001474 setTransactionFlags(eTransactionNeeded);
1475 return true;
1476}
1477bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001478 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001479 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001480 setTransactionFlags(eTransactionNeeded);
1481 return true;
1482}
1483bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1484 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1485 if (mCurrentState.flags == newFlags)
1486 return false;
1487 mCurrentState.sequence++;
1488 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001489 mCurrentState.mask = mask;
1490 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001491 setTransactionFlags(eTransactionNeeded);
1492 return true;
1493}
1494bool Layer::setCrop(const Rect& crop) {
1495 if (mCurrentState.requested.crop == crop)
1496 return false;
1497 mCurrentState.sequence++;
1498 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001499 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001500 setTransactionFlags(eTransactionNeeded);
1501 return true;
1502}
1503
1504bool Layer::setLayerStack(uint32_t layerStack) {
1505 if (mCurrentState.layerStack == layerStack)
1506 return false;
1507 mCurrentState.sequence++;
1508 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001509 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001510 setTransactionFlags(eTransactionNeeded);
1511 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001512}
1513
Dan Stoza7dde5992015-05-22 09:51:44 -07001514void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1515 uint64_t frameNumber) {
1516 mCurrentState.handle = handle;
1517 mCurrentState.frameNumber = frameNumber;
1518 // We don't set eTransactionNeeded, because just receiving a deferral
1519 // request without any other state updates shouldn't actually induce a delay
1520 mCurrentState.modified = true;
1521 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001522 mCurrentState.handle = nullptr;
1523 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001524 mCurrentState.modified = false;
1525}
1526
Dan Stozaee44edd2015-03-23 15:50:23 -07001527void Layer::useSurfaceDamage() {
1528 if (mFlinger->mForceFullDamage) {
1529 surfaceDamageRegion = Region::INVALID_REGION;
1530 } else {
1531 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1532 }
1533}
1534
1535void Layer::useEmptyDamage() {
1536 surfaceDamageRegion.clear();
1537}
1538
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001539// ----------------------------------------------------------------------------
1540// pageflip handling...
1541// ----------------------------------------------------------------------------
1542
Dan Stoza6b9454d2014-11-07 16:00:59 -08001543bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001544 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001545 return true;
1546 }
1547
Dan Stoza6b9454d2014-11-07 16:00:59 -08001548 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001549 if (mQueueItems.empty()) {
1550 return false;
1551 }
1552 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001553 nsecs_t expectedPresent =
1554 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001555
1556 // Ignore timestamps more than a second in the future
1557 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1558 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1559 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1560 expectedPresent);
1561
1562 bool isDue = timestamp < expectedPresent;
1563 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001564}
1565
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001566bool Layer::onPreComposition() {
1567 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001568 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001569}
1570
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001571void Layer::onPostComposition() {
1572 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001573 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001574 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1575
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001576 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001577 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001578 mFrameTracker.setFrameReadyFence(frameReadyFence);
1579 } else {
1580 // There was no fence for this frame, so assume that it was ready
1581 // to be presented at the desired present time.
1582 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1583 }
1584
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001585 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001586#ifdef USE_HWC2
1587 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1588#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001589 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001590#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001591 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001592 mFrameTracker.setActualPresentFence(presentFence);
1593 } else {
1594 // The HWC doesn't support present fences, so use the refresh
1595 // timestamp instead.
1596 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1597 mFrameTracker.setActualPresentTime(presentTime);
1598 }
1599
1600 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001601 mFrameLatencyNeeded = false;
1602 }
1603}
1604
Dan Stoza9e56aa02015-11-02 13:00:03 -08001605#ifdef USE_HWC2
1606void Layer::releasePendingBuffer() {
1607 mSurfaceFlingerConsumer->releasePendingBuffer();
1608}
1609#endif
1610
Mathias Agopianda27af92012-09-13 18:17:13 -07001611bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001612 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001613#ifdef USE_HWC2
1614 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1615 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1616#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001617 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001618 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001619#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001620}
1621
Mathias Agopian4fec8732012-06-29 14:12:52 -07001622Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001623{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001624 ATRACE_CALL();
1625
Jesse Hall399184a2014-03-03 15:42:54 -08001626 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1627 // mSidebandStreamChanged was true
1628 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001629 if (mSidebandStream != NULL) {
1630 setTransactionFlags(eTransactionNeeded);
1631 mFlinger->setTransactionFlags(eTraversalNeeded);
1632 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001633 recomputeVisibleRegions = true;
1634
1635 const State& s(getDrawingState());
Robert Carr3dcabfa2016-03-01 18:36:58 -08001636 return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001637 }
1638
Mathias Agopian4fec8732012-06-29 14:12:52 -07001639 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001640 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001641
1642 // if we've already called updateTexImage() without going through
1643 // a composition step, we have to skip this layer at this point
1644 // because we cannot call updateTeximage() without a corresponding
1645 // compositionComplete() call.
1646 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001647 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001648 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001649 }
1650
Jamie Gennis351a5132011-09-14 18:23:37 -07001651 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001652 const State& s(getDrawingState());
1653 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001654 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001655
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001656 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001657 Layer::State& front;
1658 Layer::State& current;
1659 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001660 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001661 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001662 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001663 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001664 recomputeVisibleRegions(recomputeVisibleRegions),
1665 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001666 }
1667
1668 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001669 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001670 if (buf == NULL) {
1671 return false;
1672 }
1673
1674 uint32_t bufWidth = buf->getWidth();
1675 uint32_t bufHeight = buf->getHeight();
1676
1677 // check that we received a buffer of the right size
1678 // (Take the buffer's orientation into account)
1679 if (item.mTransform & Transform::ROT_90) {
1680 swap(bufWidth, bufHeight);
1681 }
1682
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001683 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1684 if (front.active != front.requested) {
1685
1686 if (isFixedSize ||
1687 (bufWidth == front.requested.w &&
1688 bufHeight == front.requested.h))
1689 {
1690 // Here we pretend the transaction happened by updating the
1691 // current and drawing states. Drawing state is only accessed
1692 // in this thread, no need to have it locked
1693 front.active = front.requested;
1694
1695 // We also need to update the current state so that
1696 // we don't end-up overwriting the drawing state with
1697 // this stale current state during the next transaction
1698 //
1699 // NOTE: We don't need to hold the transaction lock here
1700 // because State::active is only accessed from this thread.
1701 current.active = front.active;
1702
1703 // recompute visible region
1704 recomputeVisibleRegions = true;
1705 }
1706
1707 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001708 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001709 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1710 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001711 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001712 front.active.w, front.active.h,
1713 front.active.crop.left,
1714 front.active.crop.top,
1715 front.active.crop.right,
1716 front.active.crop.bottom,
1717 front.active.crop.getWidth(),
1718 front.active.crop.getHeight(),
1719 front.requested.w, front.requested.h,
1720 front.requested.crop.left,
1721 front.requested.crop.top,
1722 front.requested.crop.right,
1723 front.requested.crop.bottom,
1724 front.requested.crop.getWidth(),
1725 front.requested.crop.getHeight());
1726 }
1727
Ruben Brunk1681d952014-06-27 15:51:55 -07001728 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001729 if (front.active.w != bufWidth ||
1730 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001731 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001732 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1733 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001734 return true;
1735 }
1736 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001737
1738 // if the transparent region has changed (this test is
1739 // conservative, but that's fine, worst case we're doing
1740 // a bit of extra work), we latch the new one and we
1741 // trigger a visible-region recompute.
1742 if (!front.activeTransparentRegion.isTriviallyEqual(
1743 front.requestedTransparentRegion)) {
1744 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001745
1746 // We also need to update the current state so that
1747 // we don't end-up overwriting the drawing state with
1748 // this stale current state during the next transaction
1749 //
1750 // NOTE: We don't need to hold the transaction lock here
1751 // because State::active is only accessed from this thread.
1752 current.activeTransparentRegion = front.activeTransparentRegion;
1753
1754 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001755 recomputeVisibleRegions = true;
1756 }
1757
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001758 return false;
1759 }
1760 };
1761
Ruben Brunk1681d952014-06-27 15:51:55 -07001762 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1763 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001764
Dan Stozacac35382016-01-27 12:21:06 -08001765
1766 // Check all of our local sync points to ensure that all transactions
1767 // which need to have been applied prior to the frame which is about to
1768 // be latched have signaled
1769
1770 auto headFrameNumber = getHeadFrameNumber();
1771 bool matchingFramesFound = false;
1772 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001773 {
Dan Stozacac35382016-01-27 12:21:06 -08001774 Mutex::Autolock lock(mLocalSyncPointMutex);
1775 for (auto& point : mLocalSyncPoints) {
1776 if (point->getFrameNumber() > headFrameNumber) {
1777 break;
1778 }
1779
1780 matchingFramesFound = true;
1781
1782 if (!point->frameIsAvailable()) {
1783 // We haven't notified the remote layer that the frame for
1784 // this point is available yet. Notify it now, and then
1785 // abort this attempt to latch.
1786 point->setFrameAvailable();
1787 allTransactionsApplied = false;
1788 break;
1789 }
1790
1791 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001792 }
1793 }
1794
Dan Stozacac35382016-01-27 12:21:06 -08001795 if (matchingFramesFound && !allTransactionsApplied) {
1796 mFlinger->signalLayerUpdate();
1797 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001798 }
1799
Pablo Ceballos06312182015-10-07 16:32:12 -07001800 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1801 // of the buffer queue isn't modified when the buffer queue is returning
1802 // BufferItem's that weren't actually queued. This can happen in single
1803 // buffer mode.
1804 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001805 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001806 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001807 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001808 if (updateResult == BufferQueue::PRESENT_LATER) {
1809 // Producer doesn't want buffer to be displayed yet. Signal a
1810 // layer update so we check again at the next opportunity.
1811 mFlinger->signalLayerUpdate();
1812 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001813 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1814 // If the buffer has been rejected, remove it from the shadow queue
1815 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001816 if (queuedBuffer) {
1817 Mutex::Autolock lock(mQueueItemLock);
1818 mQueueItems.removeAt(0);
1819 android_atomic_dec(&mQueuedFrames);
1820 }
Dan Stozaecc50402015-04-28 14:42:06 -07001821 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001822 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1823 // This can occur if something goes wrong when trying to create the
1824 // EGLImage for this buffer. If this happens, the buffer has already
1825 // been released, so we need to clean up the queue and bug out
1826 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001827 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001828 Mutex::Autolock lock(mQueueItemLock);
1829 mQueueItems.clear();
1830 android_atomic_and(0, &mQueuedFrames);
1831 }
1832
1833 // Once we have hit this state, the shadow queue may no longer
1834 // correctly reflect the incoming BufferQueue's contents, so even if
1835 // updateTexImage starts working, the only safe course of action is
1836 // to continue to ignore updates.
1837 mUpdateTexImageFailed = true;
1838
1839 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001840 }
1841
Pablo Ceballos06312182015-10-07 16:32:12 -07001842 if (queuedBuffer) {
1843 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001844 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1845
Dan Stoza6b9454d2014-11-07 16:00:59 -08001846 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001847
1848 // Remove any stale buffers that have been dropped during
1849 // updateTexImage
1850 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1851 mQueueItems.removeAt(0);
1852 android_atomic_dec(&mQueuedFrames);
1853 }
1854
Dan Stoza6b9454d2014-11-07 16:00:59 -08001855 mQueueItems.removeAt(0);
1856 }
1857
Dan Stozaecc50402015-04-28 14:42:06 -07001858
Andy McFadden1585c4d2013-06-28 13:52:40 -07001859 // Decrement the queued-frames count. Signal another event if we
1860 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001861 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001862 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001863 mFlinger->signalLayerUpdate();
1864 }
1865
1866 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001867 // something happened!
1868 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001869 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001870 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001871
Jamie Gennis351a5132011-09-14 18:23:37 -07001872 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001873 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001874 if (mActiveBuffer == NULL) {
1875 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001876 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001877 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001878
Mathias Agopian4824d402012-06-04 18:16:30 -07001879 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001880 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001881 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001882 // the first time we receive a buffer, we need to trigger a
1883 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001884 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001885 }
1886
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001887 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1888 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1889 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001890 if ((crop != mCurrentCrop) ||
1891 (transform != mCurrentTransform) ||
1892 (scalingMode != mCurrentScalingMode))
1893 {
1894 mCurrentCrop = crop;
1895 mCurrentTransform = transform;
1896 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001897 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001898 }
1899
1900 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001901 uint32_t bufWidth = mActiveBuffer->getWidth();
1902 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001903 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1904 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001905 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001906 }
1907 }
1908
1909 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001910 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001911 recomputeVisibleRegions = true;
1912 }
1913
Dan Stozacac35382016-01-27 12:21:06 -08001914 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1915
1916 // Remove any sync points corresponding to the buffer which was just
1917 // latched
1918 {
1919 Mutex::Autolock lock(mLocalSyncPointMutex);
1920 auto point = mLocalSyncPoints.begin();
1921 while (point != mLocalSyncPoints.end()) {
1922 if (!(*point)->frameIsAvailable() ||
1923 !(*point)->transactionIsApplied()) {
1924 // This sync point must have been added since we started
1925 // latching. Don't drop it yet.
1926 ++point;
1927 continue;
1928 }
1929
1930 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1931 point = mLocalSyncPoints.erase(point);
1932 } else {
1933 ++point;
1934 }
1935 }
1936 }
1937
Mathias Agopian4fec8732012-06-29 14:12:52 -07001938 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001939 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001940
1941 // transform the dirty region to window-manager space
Robert Carr3dcabfa2016-03-01 18:36:58 -08001942 outDirtyRegion = (s.active.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001943 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001944 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001945}
1946
Mathias Agopiana67932f2011-04-20 14:20:59 -07001947uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001948{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001949 // TODO: should we do something special if mSecure is set?
1950 if (mProtectedByApp) {
1951 // need a hardware-protected path to external video sink
1952 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001953 }
Riley Andrews03414a12014-07-01 14:22:59 -07001954 if (mPotentialCursor) {
1955 usage |= GraphicBuffer::USAGE_CURSOR;
1956 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001957 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001958 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001959}
1960
Mathias Agopian84300952012-11-21 16:02:13 -08001961void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001962 uint32_t orientation = 0;
1963 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001964 // The transform hint is used to improve performance, but we can
1965 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001966 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001967 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001968 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001969 if (orientation & Transform::ROT_INVALID) {
1970 orientation = 0;
1971 }
1972 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001973 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001974}
1975
Mathias Agopian13127d82013-03-05 17:47:11 -08001976// ----------------------------------------------------------------------------
1977// debugging
1978// ----------------------------------------------------------------------------
1979
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001980void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001981{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001982 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001983
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001984 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001985 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001986 "+ %s %p (%s)\n",
1987 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001988 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001989
Mathias Agopian2ca79392013-04-02 18:30:32 -07001990 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001991 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001992 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001993 sp<Client> client(mClientRef.promote());
1994
Mathias Agopian74d211a2013-04-22 16:55:35 +02001995 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001996 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1997 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08001998#ifdef USE_HWC2
1999 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
2000#else
Mathias Agopian13127d82013-03-05 17:47:11 -08002001 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08002002#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002003 " client=%p\n",
Robert Carr3dcabfa2016-03-01 18:36:58 -08002004 s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
Mathias Agopian13127d82013-03-05 17:47:11 -08002005 s.active.crop.left, s.active.crop.top,
2006 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002007 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002008 s.alpha, s.flags,
Robert Carr3dcabfa2016-03-01 18:36:58 -08002009 s.active.transform[0][0], s.active.transform[0][1],
2010 s.active.transform[1][0], s.active.transform[1][1],
Mathias Agopian13127d82013-03-05 17:47:11 -08002011 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002012
2013 sp<const GraphicBuffer> buf0(mActiveBuffer);
2014 uint32_t w0=0, h0=0, s0=0, f0=0;
2015 if (buf0 != 0) {
2016 w0 = buf0->getWidth();
2017 h0 = buf0->getHeight();
2018 s0 = buf0->getStride();
2019 f0 = buf0->format;
2020 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002021 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002022 " "
2023 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2024 " queued-frames=%d, mRefreshPending=%d\n",
2025 mFormat, w0, h0, s0,f0,
2026 mQueuedFrames, mRefreshPending);
2027
Mathias Agopian13127d82013-03-05 17:47:11 -08002028 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002029 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002030 }
2031}
2032
Svetoslavd85084b2014-03-20 10:28:31 -07002033void Layer::dumpFrameStats(String8& result) const {
2034 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002035}
2036
Svetoslavd85084b2014-03-20 10:28:31 -07002037void Layer::clearFrameStats() {
2038 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002039}
2040
Jamie Gennis6547ff42013-07-16 20:12:42 -07002041void Layer::logFrameStats() {
2042 mFrameTracker.logAndResetStats(mName);
2043}
2044
Svetoslavd85084b2014-03-20 10:28:31 -07002045void Layer::getFrameStats(FrameStats* outStats) const {
2046 mFrameTracker.getStats(outStats);
2047}
2048
Mathias Agopian13127d82013-03-05 17:47:11 -08002049// ---------------------------------------------------------------------------
2050
2051Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2052 const sp<Layer>& layer)
2053 : mFlinger(flinger), mLayer(layer) {
2054}
2055
2056Layer::LayerCleaner::~LayerCleaner() {
2057 // destroy client resources
2058 mFlinger->onLayerDestroyed(mLayer);
2059}
2060
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002061// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002062}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002063
2064#if defined(__gl_h_)
2065#error "don't include gl/gl.h in this file"
2066#endif
2067
2068#if defined(__gl2_h_)
2069#error "don't include gl2/gl2.h in this file"
2070#endif