blob: cde92e9322e693b21222121dcd20eeb1ddc43d7d [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),
Pablo Ceballos40845df2016-01-25 17:41:15 -080085#ifndef USE_HWC2
86 mIsGlesComposition(false),
87#endif
Mathias Agopian13127d82013-03-05 17:47:11 -080088 mProtectedByApp(false),
89 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070090 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070091 mPotentialCursor(false),
92 mQueueItemLock(),
93 mQueueItemCondition(),
94 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070095 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080096 mUpdateTexImageFailed(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080097 mAutoRefresh(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080098{
Dan Stoza9e56aa02015-11-02 13:00:03 -080099#ifdef USE_HWC2
100 ALOGV("Creating Layer %s", name.string());
101#endif
102
Mathias Agopiana67932f2011-04-20 14:20:59 -0700103 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -0700104 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -0700105 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700106
107 uint32_t layerFlags = 0;
108 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -0800109 layerFlags |= layer_state_t::eLayerHidden;
110 if (flags & ISurfaceComposerClient::eOpaque)
111 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700112 if (flags & ISurfaceComposerClient::eSecure)
113 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700114
115 if (flags & ISurfaceComposerClient::eNonPremultiplied)
116 mPremultipliedAlpha = false;
117
118 mName = name;
119
120 mCurrentState.active.w = w;
121 mCurrentState.active.h = h;
Robert Carr3dcabfa2016-03-01 18:36:58 -0800122 mCurrentState.active.transform.set(0, 0);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700123 mCurrentState.active.crop.makeInvalid();
124 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800125#ifdef USE_HWC2
126 mCurrentState.alpha = 1.0f;
127#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700128 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800129#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700130 mCurrentState.layerStack = 0;
131 mCurrentState.flags = layerFlags;
132 mCurrentState.sequence = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700133 mCurrentState.requested = mCurrentState.active;
134
135 // drawing state & current state are identical
136 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700137
Dan Stoza9e56aa02015-11-02 13:00:03 -0800138#ifdef USE_HWC2
139 const auto& hwc = flinger->getHwComposer();
140 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
141 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
142#else
Jamie Gennis6547ff42013-07-16 20:12:42 -0700143 nsecs_t displayPeriod =
144 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800145#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700146 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800147}
148
Mathias Agopian3f844832013-08-07 21:24:32 -0700149void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800150 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700151 sp<IGraphicBufferProducer> producer;
152 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700153 BufferQueue::createBufferQueue(&producer, &consumer);
154 mProducer = new MonitoredProducer(producer, mFlinger);
155 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800156 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800157 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700158 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800159
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700160#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
161#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700162#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700163 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800164#endif
Andy McFadden69052052012-09-14 16:10:11 -0700165
Mathias Agopian84300952012-11-21 16:02:13 -0800166 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
167 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700168}
169
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700170Layer::~Layer() {
Pablo Ceballos8ea4e7b2016-03-03 15:20:02 -0800171 sp<Client> c(mClientRef.promote());
172 if (c != 0) {
173 c->detachLayer(this);
174 }
175
Dan Stozacac35382016-01-27 12:21:06 -0800176 for (auto& point : mRemoteSyncPoints) {
177 point->setTransactionApplied();
178 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700179 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700180 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700181}
182
Mathias Agopian13127d82013-03-05 17:47:11 -0800183// ---------------------------------------------------------------------------
184// callbacks
185// ---------------------------------------------------------------------------
186
Dan Stoza9e56aa02015-11-02 13:00:03 -0800187#ifdef USE_HWC2
188void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
189 if (mHwcLayers.empty()) {
190 return;
191 }
192 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
193}
194#else
Dan Stozac7014012014-02-14 15:03:43 -0800195void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800196 HWComposer::HWCLayerInterface* layer) {
197 if (layer) {
198 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700199 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800200 }
201}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800202#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800203
Dan Stoza6b9454d2014-11-07 16:00:59 -0800204void Layer::onFrameAvailable(const BufferItem& item) {
205 // Add this buffer from our internal queue tracker
206 { // Autolock scope
207 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700208
209 // Reset the frame number tracker when we receive the first buffer after
210 // a frame number reset
211 if (item.mFrameNumber == 1) {
212 mLastFrameNumberReceived = 0;
213 }
214
215 // Ensure that callbacks are handled in order
216 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
217 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
218 ms2ns(500));
219 if (result != NO_ERROR) {
220 ALOGE("[%s] Timed out waiting on callback", mName.string());
221 }
222 }
223
Dan Stoza6b9454d2014-11-07 16:00:59 -0800224 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700225 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700226
227 // Wake up any pending callbacks
228 mLastFrameNumberReceived = item.mFrameNumber;
229 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800230 }
231
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800232 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700233}
234
Dan Stoza6b9454d2014-11-07 16:00:59 -0800235void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700236 { // Autolock scope
237 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700238
Dan Stoza7dde5992015-05-22 09:51:44 -0700239 // Ensure that callbacks are handled in order
240 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
241 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
242 ms2ns(500));
243 if (result != NO_ERROR) {
244 ALOGE("[%s] Timed out waiting on callback", mName.string());
245 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700246 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700247
248 if (mQueueItems.empty()) {
249 ALOGE("Can't replace a frame on an empty queue");
250 return;
251 }
252 mQueueItems.editItemAt(0) = item;
253
254 // Wake up any pending callbacks
255 mLastFrameNumberReceived = item.mFrameNumber;
256 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700257 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800258}
259
Jesse Hall399184a2014-03-03 15:42:54 -0800260void Layer::onSidebandStreamChanged() {
261 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
262 // mSidebandStreamChanged was false
263 mFlinger->signalLayerUpdate();
264 }
265}
266
Mathias Agopian67106042013-03-14 19:18:13 -0700267// called with SurfaceFlinger::mStateLock from the drawing thread after
268// the layer has been remove from the current state list (and just before
269// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800270void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800271 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700272}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700273
Mathias Agopian13127d82013-03-05 17:47:11 -0800274// ---------------------------------------------------------------------------
275// set-up
276// ---------------------------------------------------------------------------
277
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700278const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800279 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800280}
281
Mathias Agopianf9d93272009-06-19 17:00:27 -0700282status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800283 PixelFormat format, uint32_t flags)
284{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700285 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700286 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700287
288 // never allow a surface larger than what our underlying GL implementation
289 // can handle.
290 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800291 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700292 return BAD_VALUE;
293 }
294
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700295 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700296
Riley Andrews03414a12014-07-01 14:22:59 -0700297 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700298 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700299 mCurrentOpacity = getOpacityForFormat(format);
300
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800301 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
302 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
303 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700304
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800305 return NO_ERROR;
306}
307
Dan Stoza7dde5992015-05-22 09:51:44 -0700308/*
309 * The layer handle is just a BBinder object passed to the client
310 * (remote process) -- we don't keep any reference on our side such that
311 * the dtor is called when the remote side let go of its reference.
312 *
313 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
314 * this layer when the handle is destroyed.
315 */
316class Layer::Handle : public BBinder, public LayerCleaner {
317 public:
318 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
319 : LayerCleaner(flinger, layer), owner(layer) {}
320
321 wp<Layer> owner;
322};
323
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700324sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800325 Mutex::Autolock _l(mLock);
326
327 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700328 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800329
330 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700331
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700332 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800333}
334
Dan Stozab9b08832014-03-13 11:55:57 -0700335sp<IGraphicBufferProducer> Layer::getProducer() const {
336 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700337}
338
Mathias Agopian13127d82013-03-05 17:47:11 -0800339// ---------------------------------------------------------------------------
340// h/w composer set-up
341// ---------------------------------------------------------------------------
342
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800343Rect Layer::getContentCrop() const {
344 // this is the crop rectangle that applies to the buffer
345 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700346 Rect crop;
347 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800348 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700349 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800350 } else if (mActiveBuffer != NULL) {
351 // otherwise we use the whole buffer
352 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700353 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800354 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700355 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700356 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700357 return crop;
358}
359
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700360static Rect reduce(const Rect& win, const Region& exclude) {
361 if (CC_LIKELY(exclude.isEmpty())) {
362 return win;
363 }
364 if (exclude.isRect()) {
365 return win.reduce(exclude.getBounds());
366 }
367 return Region(win).subtract(exclude).getBounds();
368}
369
Mathias Agopian13127d82013-03-05 17:47:11 -0800370Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700371 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700372 return computeBounds(s.activeTransparentRegion);
373}
374
375Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
376 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800377 Rect win(s.active.w, s.active.h);
378 if (!s.active.crop.isEmpty()) {
379 win.intersect(s.active.crop, &win);
380 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700381 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700382 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800383}
384
Mathias Agopian6b442672013-07-09 21:24:52 -0700385FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800386 // the content crop is the area of the content that gets scaled to the
387 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700388 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800389
390 // the active.crop is the area of the window that gets cropped, but not
391 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700392 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800393
394 // apply the projection's clipping to the window crop in
395 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700396 // if there are no window scaling involved, this operation will map to full
397 // pixels in the buffer.
398 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
399 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700400
401 Rect activeCrop(s.active.w, s.active.h);
402 if (!s.active.crop.isEmpty()) {
403 activeCrop = s.active.crop;
404 }
405
Robert Carr3dcabfa2016-03-01 18:36:58 -0800406 activeCrop = s.active.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800407 activeCrop.intersect(hw->getViewport(), &activeCrop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800408 activeCrop = s.active.transform.inverse().transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800409
Michael Lentine28ea2172014-11-19 18:32:37 -0800410 // This needs to be here as transform.transform(Rect) computes the
411 // transformed rect and then takes the bounding box of the result before
412 // returning. This means
413 // transform.inverse().transform(transform.transform(Rect)) != Rect
414 // in which case we need to make sure the final rect is clipped to the
415 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800416 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
417
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700418 // subtract the transparent region and snap to the bounds
419 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
420
Mathias Agopian13127d82013-03-05 17:47:11 -0800421 if (!activeCrop.isEmpty()) {
422 // Transform the window crop to match the buffer coordinate system,
423 // which means using the inverse of the current transform set on the
424 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700425 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700426 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
427 /*
428 * the code below applies the display's inverse transform to the buffer
429 */
430 uint32_t invTransformOrient = hw->getOrientationTransform();
431 // calculate the inverse transform
432 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
433 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
434 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700435 // If the transform has been rotated the axis of flip has been swapped
436 // so we need to swap which flip operations we are performing
437 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
438 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
439 if (is_h_flipped != is_v_flipped) {
440 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
441 NATIVE_WINDOW_TRANSFORM_FLIP_H;
442 }
Michael Lentinef7551402014-08-18 16:35:43 -0700443 }
444 // and apply to the current transform
445 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
446 }
447
Mathias Agopian13127d82013-03-05 17:47:11 -0800448 int winWidth = s.active.w;
449 int winHeight = s.active.h;
450 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700451 // If the activeCrop has been rotate the ends are rotated but not
452 // the space itself so when transforming ends back we can't rely on
453 // a modification of the axes of rotation. To account for this we
454 // need to reorient the inverse rotation in terms of the current
455 // axes of rotation.
456 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
457 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
458 if (is_h_flipped == is_v_flipped) {
459 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
460 NATIVE_WINDOW_TRANSFORM_FLIP_H;
461 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800462 winWidth = s.active.h;
463 winHeight = s.active.w;
464 }
465 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700466 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800467
Mathias Agopian6b442672013-07-09 21:24:52 -0700468 // below, crop is intersected with winCrop expressed in crop's coordinate space
469 float xScale = crop.getWidth() / float(winWidth);
470 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800471
Michael Lentinef7551402014-08-18 16:35:43 -0700472 float insetL = winCrop.left * xScale;
473 float insetT = winCrop.top * yScale;
474 float insetR = (winWidth - winCrop.right ) * xScale;
475 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800476
477 crop.left += insetL;
478 crop.top += insetT;
479 crop.right -= insetR;
480 crop.bottom -= insetB;
481 }
482 return crop;
483}
484
Dan Stoza9e56aa02015-11-02 13:00:03 -0800485#ifdef USE_HWC2
486void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
487#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700488void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700489 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700490 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800491#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700492{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800493#ifdef USE_HWC2
494 const auto hwcId = displayDevice->getHwcDisplayId();
495 auto& hwcInfo = mHwcLayers[hwcId];
496#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800497 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800498#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700499
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700500 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800501#ifdef USE_HWC2
502 hwcInfo.forceClientComposition = false;
503
504 if (isSecure() && !displayDevice->isSecure()) {
505 hwcInfo.forceClientComposition = true;
506 }
507
508 auto& hwcLayer = hwcInfo.layer;
509#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700510 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700511
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700512 if (isSecure() && !hw->isSecure()) {
513 layer.setSkip(true);
514 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800515#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700516
Mathias Agopian13127d82013-03-05 17:47:11 -0800517 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700518 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800519#ifdef USE_HWC2
520 if (!isOpaque(s) || s.alpha != 1.0f) {
521 auto blendMode = mPremultipliedAlpha ?
522 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
523 auto error = hwcLayer->setBlendMode(blendMode);
524 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
525 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
526 to_string(error).c_str(), static_cast<int32_t>(error));
527 }
528#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800529 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800530 layer.setBlending(mPremultipliedAlpha ?
531 HWC_BLENDING_PREMULT :
532 HWC_BLENDING_COVERAGE);
533 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800534#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800535
536 // apply the layer's transform, followed by the display's global transform
537 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700538 Region activeTransparentRegion(s.activeTransparentRegion);
539 if (!s.active.crop.isEmpty()) {
540 Rect activeCrop(s.active.crop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800541 activeCrop = s.active.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800542#ifdef USE_HWC2
543 activeCrop.intersect(displayDevice->getViewport(), &activeCrop);
544#else
Michael Lentine6c925ed2014-09-26 17:55:01 -0700545 activeCrop.intersect(hw->getViewport(), &activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800546#endif
Robert Carr3dcabfa2016-03-01 18:36:58 -0800547 activeCrop = s.active.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800548 // This needs to be here as transform.transform(Rect) computes the
549 // transformed rect and then takes the bounding box of the result before
550 // returning. This means
551 // transform.inverse().transform(transform.transform(Rect)) != Rect
552 // in which case we need to make sure the final rect is clipped to the
553 // display bounds.
554 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700555 // mark regions outside the crop as transparent
556 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
557 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
558 s.active.w, s.active.h));
559 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
560 activeCrop.left, activeCrop.bottom));
561 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
562 s.active.w, activeCrop.bottom));
563 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800564 Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800565#ifdef USE_HWC2
566 frame.intersect(displayDevice->getViewport(), &frame);
567 const Transform& tr(displayDevice->getTransform());
568 Rect transformedFrame = tr.transform(frame);
569 auto error = hwcLayer->setDisplayFrame(transformedFrame);
570 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
571 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
572 transformedFrame.top, transformedFrame.right,
573 transformedFrame.bottom, to_string(error).c_str(),
574 static_cast<int32_t>(error));
575
576 FloatRect sourceCrop = computeCrop(displayDevice);
577 error = hwcLayer->setSourceCrop(sourceCrop);
578 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
579 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
580 sourceCrop.left, sourceCrop.top, sourceCrop.right,
581 sourceCrop.bottom, to_string(error).c_str(),
582 static_cast<int32_t>(error));
583
584 error = hwcLayer->setPlaneAlpha(s.alpha);
585 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
586 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
587 static_cast<int32_t>(error));
588
589 error = hwcLayer->setZOrder(s.z);
590 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
591 mName.string(), s.z, to_string(error).c_str(),
592 static_cast<int32_t>(error));
593#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800594 frame.intersect(hw->getViewport(), &frame);
595 const Transform& tr(hw->getTransform());
596 layer.setFrame(tr.transform(frame));
597 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800598 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800599#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800600
Mathias Agopian29a367b2011-07-12 14:51:45 -0700601 /*
602 * Transformations are applied in this order:
603 * 1) buffer orientation/flip/mirror
604 * 2) state transformation (window manager)
605 * 3) layer orientation (screen orientation)
606 * (NOTE: the matrices are multiplied in reverse order)
607 */
608
609 const Transform bufferOrientation(mCurrentTransform);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800610 Transform transform(tr * s.active.transform * bufferOrientation);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700611
612 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
613 /*
614 * the code below applies the display's inverse transform to the buffer
615 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800616#ifdef USE_HWC2
617 uint32_t invTransform = displayDevice->getOrientationTransform();
618#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700619 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800620#endif
Michael Lentine14409632014-08-19 11:27:30 -0700621 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700622 // calculate the inverse transform
623 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
624 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
625 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700626 // If the transform has been rotated the axis of flip has been swapped
627 // so we need to swap which flip operations we are performing
628 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
629 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
630 if (is_h_flipped != is_v_flipped) {
631 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
632 NATIVE_WINDOW_TRANSFORM_FLIP_H;
633 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700634 }
635 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700636 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700637 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700638
639 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800640 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800641#ifdef USE_HWC2
642 if (orientation & Transform::ROT_INVALID) {
643 // we can only handle simple transformation
644 hwcInfo.forceClientComposition = true;
645 } else {
646 auto transform = static_cast<HWC2::Transform>(orientation);
647 auto error = hwcLayer->setTransform(transform);
648 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
649 "%s (%d)", mName.string(), to_string(transform).c_str(),
650 to_string(error).c_str(), static_cast<int32_t>(error));
651 }
652#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800653 if (orientation & Transform::ROT_INVALID) {
654 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700655 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700656 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800657 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700658 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800659#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700660}
661
Dan Stoza9e56aa02015-11-02 13:00:03 -0800662#ifdef USE_HWC2
663void Layer::forceClientComposition(int32_t hwcId) {
664 if (mHwcLayers.count(hwcId) == 0) {
665 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
666 return;
667 }
668
669 mHwcLayers[hwcId].forceClientComposition = true;
670}
671#endif
672
673#ifdef USE_HWC2
674void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
675 // Apply this display's projection's viewport to the visible region
676 // before giving it to the HWC HAL.
677 const Transform& tr = displayDevice->getTransform();
678 const auto& viewport = displayDevice->getViewport();
679 Region visible = tr.transform(visibleRegion.intersect(viewport));
680 auto hwcId = displayDevice->getHwcDisplayId();
681 auto& hwcLayer = mHwcLayers[hwcId].layer;
682 auto error = hwcLayer->setVisibleRegion(visible);
683 if (error != HWC2::Error::None) {
684 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
685 to_string(error).c_str(), static_cast<int32_t>(error));
686 visible.dump(LOG_TAG);
687 }
688
689 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
690 if (error != HWC2::Error::None) {
691 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
692 to_string(error).c_str(), static_cast<int32_t>(error));
693 surfaceDamageRegion.dump(LOG_TAG);
694 }
695
696 auto compositionType = HWC2::Composition::Invalid;
697 if (mSidebandStream.get()) {
698 compositionType = HWC2::Composition::Sideband;
699 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
700 if (error != HWC2::Error::None) {
701 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
702 mName.string(), mSidebandStream->handle(),
703 to_string(error).c_str(), static_cast<int32_t>(error));
704 return;
705 }
706 } else {
707 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
708 compositionType = HWC2::Composition::Client;
709 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
710 if (error != HWC2::Error::None) {
711 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
712 to_string(error).c_str(), static_cast<int32_t>(error));
713 return;
714 }
715 } else {
716 if (mPotentialCursor) {
717 compositionType = HWC2::Composition::Cursor;
718 }
719 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
720 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
721 acquireFence);
722 if (error != HWC2::Error::None) {
723 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
724 mActiveBuffer->handle, to_string(error).c_str(),
725 static_cast<int32_t>(error));
726 return;
727 }
728 // If it's not a cursor, default to device composition
729 }
730 }
731
732 if (mHwcLayers[hwcId].forceClientComposition) {
733 ALOGV("[%s] Forcing Client composition", mName.string());
734 setCompositionType(hwcId, HWC2::Composition::Client);
735 } else if (compositionType != HWC2::Composition::Invalid) {
736 ALOGV("[%s] Requesting %s composition", mName.string(),
737 to_string(compositionType).c_str());
738 setCompositionType(hwcId, compositionType);
739 } else {
740 ALOGV("[%s] Requesting Device composition", mName.string());
741 setCompositionType(hwcId, HWC2::Composition::Device);
742 }
743}
744#else
Mathias Agopian42977342012-08-05 00:40:46 -0700745void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700746 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800747 // we have to set the visible region on every frame because
748 // we currently free it during onLayerDisplayed(), which is called
749 // after HWComposer::commit() -- every frame.
750 // Apply this display's projection's viewport to the visible region
751 // before giving it to the HWC HAL.
752 const Transform& tr = hw->getTransform();
753 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
754 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700755 layer.setSurfaceDamage(surfaceDamageRegion);
Pablo Ceballos40845df2016-01-25 17:41:15 -0800756 mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
Dan Stozaee44edd2015-03-23 15:50:23 -0700757
Jesse Hall399184a2014-03-03 15:42:54 -0800758 if (mSidebandStream.get()) {
759 layer.setSidebandStream(mSidebandStream);
760 } else {
761 // NOTE: buffer can be NULL if the client never drew into this
762 // layer yet, or if we ran out of memory
763 layer.setBuffer(mActiveBuffer);
764 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700765}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800766#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700767
Dan Stoza9e56aa02015-11-02 13:00:03 -0800768#ifdef USE_HWC2
769void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
770 auto hwcId = displayDevice->getHwcDisplayId();
771 if (mHwcLayers.count(hwcId) == 0 ||
772 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
773 return;
774 }
775
776 // This gives us only the "orientation" component of the transform
777 const State& s(getCurrentState());
778
779 // Apply the layer's transform, followed by the display's global transform
780 // Here we're guaranteed that the layer's transform preserves rects
781 Rect win(s.active.w, s.active.h);
782 if (!s.active.crop.isEmpty()) {
783 win.intersect(s.active.crop, &win);
784 }
785 // Subtract the transparent region and snap to the bounds
786 Rect bounds = reduce(win, s.activeTransparentRegion);
Dan Stozabaf416d2016-03-10 11:57:08 -0800787 Rect frame(s.active.transform.transform(bounds));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800788 frame.intersect(displayDevice->getViewport(), &frame);
789 auto& displayTransform(displayDevice->getTransform());
790 auto position = displayTransform.transform(frame);
791
792 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
793 position.top);
794 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
795 "to (%d, %d): %s (%d)", mName.string(), position.left,
796 position.top, to_string(error).c_str(),
797 static_cast<int32_t>(error));
798}
799#else
Dan Stozac7014012014-02-14 15:03:43 -0800800void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700801 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700802 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700803
804 // TODO: there is a possible optimization here: we only need to set the
805 // acquire fence the first time a new buffer is acquired on EACH display.
806
Riley Andrews03414a12014-07-01 14:22:59 -0700807 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800808 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800809 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700810 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700811 if (fenceFd == -1) {
812 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
813 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700814 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700815 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700816 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700817}
818
Riley Andrews03414a12014-07-01 14:22:59 -0700819Rect Layer::getPosition(
820 const sp<const DisplayDevice>& hw)
821{
822 // this gives us only the "orientation" component of the transform
823 const State& s(getCurrentState());
824
825 // apply the layer's transform, followed by the display's global transform
826 // here we're guaranteed that the layer's transform preserves rects
827 Rect win(s.active.w, s.active.h);
828 if (!s.active.crop.isEmpty()) {
829 win.intersect(s.active.crop, &win);
830 }
831 // subtract the transparent region and snap to the bounds
832 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800833 Rect frame(s.active.transform.transform(bounds));
Riley Andrews03414a12014-07-01 14:22:59 -0700834 frame.intersect(hw->getViewport(), &frame);
835 const Transform& tr(hw->getTransform());
836 return Rect(tr.transform(frame));
837}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800838#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700839
Mathias Agopian13127d82013-03-05 17:47:11 -0800840// ---------------------------------------------------------------------------
841// drawing...
842// ---------------------------------------------------------------------------
843
844void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800845 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800846}
847
Dan Stozac7014012014-02-14 15:03:43 -0800848void Layer::draw(const sp<const DisplayDevice>& hw,
849 bool useIdentityTransform) const {
850 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800851}
852
Dan Stozac7014012014-02-14 15:03:43 -0800853void Layer::draw(const sp<const DisplayDevice>& hw) const {
854 onDraw(hw, Region(hw->bounds()), false);
855}
856
857void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
858 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800859{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800860 ATRACE_CALL();
861
Mathias Agopiana67932f2011-04-20 14:20:59 -0700862 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800863 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700864 // in fact never been drawn into. This happens frequently with
865 // SurfaceView because the WindowManager can't know when the client
866 // has drawn the first time.
867
868 // If there is nothing under us, we paint the screen in black, otherwise
869 // we just skip this update.
870
871 // figure out if there is something below us
872 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700873 const SurfaceFlinger::LayerVector& drawingLayers(
874 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700875 const size_t count = drawingLayers.size();
876 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800877 const sp<Layer>& layer(drawingLayers[i]);
878 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700879 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700880 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700881 }
882 // if not everything below us is covered, we plug the holes!
883 Region holes(clip.subtract(under));
884 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700885 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700886 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800887 return;
888 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700889
Andy McFadden97eba892012-12-11 15:21:45 -0800890 // Bind the current buffer to the GL texture, and wait for it to be
891 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800892 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
893 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800894 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700895 // Go ahead and draw the buffer anyway; no matter what we do the screen
896 // is probably going to have something visibly wrong.
897 }
898
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700899 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
900
Mathias Agopian875d8e12013-06-07 15:35:48 -0700901 RenderEngine& engine(mFlinger->getRenderEngine());
902
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700903 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700904 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700905 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700906
907 // Query the texture matrix given our current filtering mode.
908 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800909 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
910 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700911
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700912 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
913
914 /*
915 * the code below applies the display's inverse transform to the texture transform
916 */
917
918 // create a 4x4 transform matrix from the display transform flags
919 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
920 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
921 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
922
923 mat4 tr;
924 uint32_t transform = hw->getOrientationTransform();
925 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
926 tr = tr * rot90;
927 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
928 tr = tr * flipH;
929 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
930 tr = tr * flipV;
931
932 // calculate the inverse
933 tr = inverse(tr);
934
935 // and finally apply it to the original texture matrix
936 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
937 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
938 }
939
Jamie Genniscbb1a952012-05-08 17:05:52 -0700940 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700941 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
942 mTexture.setFiltering(useFiltering);
943 mTexture.setMatrix(textureMatrix);
944
945 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700946 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700947 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700948 }
Dan Stozac7014012014-02-14 15:03:43 -0800949 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700950 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800951}
952
Mathias Agopian13127d82013-03-05 17:47:11 -0800953
Dan Stozac7014012014-02-14 15:03:43 -0800954void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
955 const Region& /* clip */, float red, float green, float blue,
956 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800957{
Mathias Agopian19733a32013-08-28 18:13:56 -0700958 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800959 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700960 engine.setupFillWithColor(red, green, blue, alpha);
961 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800962}
963
964void Layer::clearWithOpenGL(
965 const sp<const DisplayDevice>& hw, const Region& clip) const {
966 clearWithOpenGL(hw, clip, 0,0,0,0);
967}
968
Dan Stozac7014012014-02-14 15:03:43 -0800969void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
970 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700971 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800972
Dan Stozac7014012014-02-14 15:03:43 -0800973 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800974
Mathias Agopian13127d82013-03-05 17:47:11 -0800975 /*
976 * NOTE: the way we compute the texture coordinates here produces
977 * different results than when we take the HWC path -- in the later case
978 * the "source crop" is rounded to texel boundaries.
979 * This can produce significantly different results when the texture
980 * is scaled by a large amount.
981 *
982 * The GL code below is more logical (imho), and the difference with
983 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700984 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800985 * GL composition when a buffer scaling is applied (maybe with some
986 * minimal value)? Or, we could make GL behave like HWC -- but this feel
987 * like more of a hack.
988 */
989 const Rect win(computeBounds());
990
Mathias Agopian3f844832013-08-07 21:24:32 -0700991 float left = float(win.left) / float(s.active.w);
992 float top = float(win.top) / float(s.active.h);
993 float right = float(win.right) / float(s.active.w);
994 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800995
Mathias Agopian875d8e12013-06-07 15:35:48 -0700996 // TODO: we probably want to generate the texture coords with the mesh
997 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700998 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
999 texCoords[0] = vec2(left, 1.0f - top);
1000 texCoords[1] = vec2(left, 1.0f - bottom);
1001 texCoords[2] = vec2(right, 1.0f - bottom);
1002 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -08001003
Mathias Agopian875d8e12013-06-07 15:35:48 -07001004 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -08001005 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001006 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001007 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001008}
1009
Dan Stoza9e56aa02015-11-02 13:00:03 -08001010#ifdef USE_HWC2
1011void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1012 bool callIntoHwc) {
1013 if (mHwcLayers.count(hwcId) == 0) {
1014 ALOGE("setCompositionType called without a valid HWC layer");
1015 return;
1016 }
1017 auto& hwcInfo = mHwcLayers[hwcId];
1018 auto& hwcLayer = hwcInfo.layer;
1019 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1020 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1021 if (hwcInfo.compositionType != type) {
1022 ALOGV(" actually setting");
1023 hwcInfo.compositionType = type;
1024 if (callIntoHwc) {
1025 auto error = hwcLayer->setCompositionType(type);
1026 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1027 "composition type %s: %s (%d)", mName.string(),
1028 to_string(type).c_str(), to_string(error).c_str(),
1029 static_cast<int32_t>(error));
1030 }
1031 }
1032}
1033
1034HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1035 if (mHwcLayers.count(hwcId) == 0) {
1036 ALOGE("getCompositionType called without a valid HWC layer");
1037 return HWC2::Composition::Invalid;
1038 }
1039 return mHwcLayers.at(hwcId).compositionType;
1040}
1041
1042void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1043 if (mHwcLayers.count(hwcId) == 0) {
1044 ALOGE("setClearClientTarget called without a valid HWC layer");
1045 return;
1046 }
1047 mHwcLayers[hwcId].clearClientTarget = clear;
1048}
1049
1050bool Layer::getClearClientTarget(int32_t hwcId) const {
1051 if (mHwcLayers.count(hwcId) == 0) {
1052 ALOGE("getClearClientTarget called without a valid HWC layer");
1053 return false;
1054 }
1055 return mHwcLayers.at(hwcId).clearClientTarget;
1056}
1057#endif
1058
Ruben Brunk1681d952014-06-27 15:51:55 -07001059uint32_t Layer::getProducerStickyTransform() const {
1060 int producerStickyTransform = 0;
1061 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1062 if (ret != OK) {
1063 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1064 strerror(-ret), ret);
1065 return 0;
1066 }
1067 return static_cast<uint32_t>(producerStickyTransform);
1068}
1069
Dan Stozacac35382016-01-27 12:21:06 -08001070uint64_t Layer::getHeadFrameNumber() const {
1071 Mutex::Autolock lock(mQueueItemLock);
1072 if (!mQueueItems.empty()) {
1073 return mQueueItems[0].mFrameNumber;
1074 } else {
1075 return mCurrentFrameNumber;
1076 }
1077}
1078
1079bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1080 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1081 // Don't bother with a SyncPoint, since we've already latched the
1082 // relevant frame
1083 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001084 }
1085
Dan Stozacac35382016-01-27 12:21:06 -08001086 Mutex::Autolock lock(mLocalSyncPointMutex);
1087 mLocalSyncPoints.push_back(point);
1088 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001089}
1090
Mathias Agopian13127d82013-03-05 17:47:11 -08001091void Layer::setFiltering(bool filtering) {
1092 mFiltering = filtering;
1093}
1094
1095bool Layer::getFiltering() const {
1096 return mFiltering;
1097}
1098
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001099// As documented in libhardware header, formats in the range
1100// 0x100 - 0x1FF are specific to the HAL implementation, and
1101// are known to have no alpha channel
1102// TODO: move definition for device-specific range into
1103// hardware.h, instead of using hard-coded values here.
1104#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1105
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001106bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001107 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1108 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001109 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001110 switch (format) {
1111 case HAL_PIXEL_FORMAT_RGBA_8888:
1112 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001113 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001114 }
1115 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001116 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001117}
1118
Mathias Agopian13127d82013-03-05 17:47:11 -08001119// ----------------------------------------------------------------------------
1120// local state
1121// ----------------------------------------------------------------------------
1122
Dan Stozac7014012014-02-14 15:03:43 -08001123void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1124 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001125{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001126 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -08001127 const Transform tr(useIdentityTransform ?
Robert Carr3dcabfa2016-03-01 18:36:58 -08001128 hw->getTransform() : hw->getTransform() * s.active.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -08001129 const uint32_t hw_h = hw->getHeight();
1130 Rect win(s.active.w, s.active.h);
1131 if (!s.active.crop.isEmpty()) {
1132 win.intersect(s.active.crop, &win);
1133 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001134 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001135 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001136
Mathias Agopianff2ed702013-09-01 21:36:12 -07001137 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1138 position[0] = tr.transform(win.left, win.top);
1139 position[1] = tr.transform(win.left, win.bottom);
1140 position[2] = tr.transform(win.right, win.bottom);
1141 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -07001142 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001143 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001144 }
1145}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001146
Andy McFadden4125a4f2014-01-29 17:17:11 -08001147bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001148{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001149 // if we don't have a buffer yet, we're translucent regardless of the
1150 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001151 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001152 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001153 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001154
1155 // if the layer has the opaque flag, then we're always opaque,
1156 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001157 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001158}
1159
Dan Stoza23116082015-06-18 14:58:39 -07001160bool Layer::isSecure() const
1161{
1162 const Layer::State& s(mDrawingState);
1163 return (s.flags & layer_state_t::eLayerSecure);
1164}
1165
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001166bool Layer::isProtected() const
1167{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001168 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001169 return (activeBuffer != 0) &&
1170 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1171}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001172
Mathias Agopian13127d82013-03-05 17:47:11 -08001173bool Layer::isFixedSize() const {
1174 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1175}
1176
1177bool Layer::isCropped() const {
1178 return !mCurrentCrop.isEmpty();
1179}
1180
1181bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1182 return mNeedsFiltering || hw->needsFiltering();
1183}
1184
1185void Layer::setVisibleRegion(const Region& visibleRegion) {
1186 // always called from main thread
1187 this->visibleRegion = visibleRegion;
1188}
1189
1190void Layer::setCoveredRegion(const Region& coveredRegion) {
1191 // always called from main thread
1192 this->coveredRegion = coveredRegion;
1193}
1194
1195void Layer::setVisibleNonTransparentRegion(const Region&
1196 setVisibleNonTransparentRegion) {
1197 // always called from main thread
1198 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1199}
1200
1201// ----------------------------------------------------------------------------
1202// transaction
1203// ----------------------------------------------------------------------------
1204
Dan Stoza7dde5992015-05-22 09:51:44 -07001205void Layer::pushPendingState() {
1206 if (!mCurrentState.modified) {
1207 return;
1208 }
1209
Dan Stoza7dde5992015-05-22 09:51:44 -07001210 // If this transaction is waiting on the receipt of a frame, generate a sync
1211 // point and send it to the remote layer.
1212 if (mCurrentState.handle != nullptr) {
1213 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1214 sp<Layer> handleLayer = handle->owner.promote();
1215 if (handleLayer == nullptr) {
1216 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1217 // If we can't promote the layer we are intended to wait on,
1218 // then it is expired or otherwise invalid. Allow this transaction
1219 // to be applied as per normal (no synchronization).
1220 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001221 } else {
1222 auto syncPoint = std::make_shared<SyncPoint>(
1223 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001224 if (handleLayer->addSyncPoint(syncPoint)) {
1225 mRemoteSyncPoints.push_back(std::move(syncPoint));
1226 } else {
1227 // We already missed the frame we're supposed to synchronize
1228 // on, so go ahead and apply the state update
1229 mCurrentState.handle = nullptr;
1230 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001231 }
1232
Dan Stoza7dde5992015-05-22 09:51:44 -07001233 // Wake us up to check if the frame has been received
1234 setTransactionFlags(eTransactionNeeded);
1235 }
1236 mPendingStates.push_back(mCurrentState);
1237}
1238
1239void Layer::popPendingState() {
1240 auto oldFlags = mCurrentState.flags;
1241 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001242 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001243 (mCurrentState.flags & mCurrentState.mask);
1244
1245 mPendingStates.removeAt(0);
1246}
1247
1248bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001249 bool stateUpdateAvailable = false;
1250 while (!mPendingStates.empty()) {
1251 if (mPendingStates[0].handle != nullptr) {
1252 if (mRemoteSyncPoints.empty()) {
1253 // If we don't have a sync point for this, apply it anyway. It
1254 // will be visually wrong, but it should keep us from getting
1255 // into too much trouble.
1256 ALOGE("[%s] No local sync point found", mName.string());
1257 popPendingState();
1258 stateUpdateAvailable = true;
1259 continue;
1260 }
1261
Dan Stozacac35382016-01-27 12:21:06 -08001262 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1263 mPendingStates[0].frameNumber) {
1264 ALOGE("[%s] Unexpected sync point frame number found",
1265 mName.string());
1266
1267 // Signal our end of the sync point and then dispose of it
1268 mRemoteSyncPoints.front()->setTransactionApplied();
1269 mRemoteSyncPoints.pop_front();
1270 continue;
1271 }
1272
Dan Stoza7dde5992015-05-22 09:51:44 -07001273 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1274 // Apply the state update
1275 popPendingState();
1276 stateUpdateAvailable = true;
1277
1278 // Signal our end of the sync point and then dispose of it
1279 mRemoteSyncPoints.front()->setTransactionApplied();
1280 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001281 } else {
1282 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001283 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001284 } else {
1285 popPendingState();
1286 stateUpdateAvailable = true;
1287 }
1288 }
1289
1290 // If we still have pending updates, wake SurfaceFlinger back up and point
1291 // it at this layer so we can process them
1292 if (!mPendingStates.empty()) {
1293 setTransactionFlags(eTransactionNeeded);
1294 mFlinger->setTransactionFlags(eTraversalNeeded);
1295 }
1296
1297 mCurrentState.modified = false;
1298 return stateUpdateAvailable;
1299}
1300
1301void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001302 auto headFrameNumber = getHeadFrameNumber();
1303 Mutex::Autolock lock(mLocalSyncPointMutex);
1304 for (auto& point : mLocalSyncPoints) {
1305 if (headFrameNumber >= point->getFrameNumber()) {
1306 point->setFrameAvailable();
1307 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001308 }
1309}
1310
Mathias Agopian13127d82013-03-05 17:47:11 -08001311uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001312 ATRACE_CALL();
1313
Dan Stoza7dde5992015-05-22 09:51:44 -07001314 pushPendingState();
1315 if (!applyPendingStates()) {
1316 return 0;
1317 }
1318
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001319 const Layer::State& s(getDrawingState());
1320 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001321
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001322 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1323 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001324
1325 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001326 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001327 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001328 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001329 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1330 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1331 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1332 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001333 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1334 c.active.w, c.active.h,
1335 c.active.crop.left,
1336 c.active.crop.top,
1337 c.active.crop.right,
1338 c.active.crop.bottom,
1339 c.active.crop.getWidth(),
1340 c.active.crop.getHeight(),
1341 c.requested.w, c.requested.h,
1342 c.requested.crop.left,
1343 c.requested.crop.top,
1344 c.requested.crop.right,
1345 c.requested.crop.bottom,
1346 c.requested.crop.getWidth(),
1347 c.requested.crop.getHeight(),
1348 s.active.w, s.active.h,
1349 s.active.crop.left,
1350 s.active.crop.top,
1351 s.active.crop.right,
1352 s.active.crop.bottom,
1353 s.active.crop.getWidth(),
1354 s.active.crop.getHeight(),
1355 s.requested.w, s.requested.h,
1356 s.requested.crop.left,
1357 s.requested.crop.top,
1358 s.requested.crop.right,
1359 s.requested.crop.bottom,
1360 s.requested.crop.getWidth(),
1361 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001362
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001363 // record the new size, form this point on, when the client request
1364 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001365 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001366 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001367 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001368
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001369 if (!isFixedSize()) {
1370
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001371 const bool resizePending = (c.requested.w != c.active.w) ||
1372 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001373
Dan Stoza9e9b0442015-04-22 14:59:08 -07001374 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001375 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001376 // if we have a pending resize, unless we are in fixed-size mode.
1377 // the drawing state will be updated only once we receive a buffer
1378 // with the correct size.
1379 //
1380 // in particular, we want to make sure the clip (which is part
1381 // of the geometry state) is latched together with the size but is
1382 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001383 //
1384 // If a sideband stream is attached, however, we want to skip this
1385 // optimization so that transactions aren't missed when a buffer
1386 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001387
1388 flags |= eDontUpdateGeometryState;
1389 }
1390 }
1391
Mathias Agopian13127d82013-03-05 17:47:11 -08001392 // always set active to requested, unless we're asked not to
1393 // this is used by Layer, which special cases resizes.
1394 if (flags & eDontUpdateGeometryState) {
1395 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001396 Layer::State& editCurrentState(getCurrentState());
1397 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001398 }
1399
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001400 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001401 // invalidate and recompute the visible regions if needed
1402 flags |= Layer::eVisibleRegion;
1403 }
1404
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001405 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001406 // invalidate and recompute the visible regions if needed
1407 flags |= eVisibleRegion;
1408 this->contentDirty = true;
1409
1410 // we may use linear filtering, if the matrix scales us
Robert Carr3dcabfa2016-03-01 18:36:58 -08001411 const uint8_t type = c.active.transform.getType();
1412 mNeedsFiltering = (!c.active.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001413 (type >= Transform::SCALE));
1414 }
1415
1416 // Commit the transaction
1417 commitTransaction();
1418 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001419}
1420
Mathias Agopian13127d82013-03-05 17:47:11 -08001421void Layer::commitTransaction() {
1422 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001423}
1424
Mathias Agopian13127d82013-03-05 17:47:11 -08001425uint32_t Layer::getTransactionFlags(uint32_t flags) {
1426 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1427}
1428
1429uint32_t Layer::setTransactionFlags(uint32_t flags) {
1430 return android_atomic_or(flags, &mTransactionFlags);
1431}
1432
1433bool Layer::setPosition(float x, float y) {
Robert Carr3dcabfa2016-03-01 18:36:58 -08001434 if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
Mathias Agopian13127d82013-03-05 17:47:11 -08001435 return false;
1436 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001437 mCurrentState.requested.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001438 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001439 setTransactionFlags(eTransactionNeeded);
1440 return true;
1441}
1442bool Layer::setLayer(uint32_t z) {
1443 if (mCurrentState.z == z)
1444 return false;
1445 mCurrentState.sequence++;
1446 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001447 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001448 setTransactionFlags(eTransactionNeeded);
1449 return true;
1450}
1451bool Layer::setSize(uint32_t w, uint32_t h) {
1452 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1453 return false;
1454 mCurrentState.requested.w = w;
1455 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001456 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001457 setTransactionFlags(eTransactionNeeded);
1458 return true;
1459}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001460#ifdef USE_HWC2
1461bool Layer::setAlpha(float alpha) {
1462#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001463bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001464#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001465 if (mCurrentState.alpha == alpha)
1466 return false;
1467 mCurrentState.sequence++;
1468 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001469 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001470 setTransactionFlags(eTransactionNeeded);
1471 return true;
1472}
1473bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1474 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001475 mCurrentState.requested.transform.set(
Mathias Agopian13127d82013-03-05 17:47:11 -08001476 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001477 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001478 setTransactionFlags(eTransactionNeeded);
1479 return true;
1480}
1481bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001482 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001483 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001484 setTransactionFlags(eTransactionNeeded);
1485 return true;
1486}
1487bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1488 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1489 if (mCurrentState.flags == newFlags)
1490 return false;
1491 mCurrentState.sequence++;
1492 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001493 mCurrentState.mask = mask;
1494 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001495 setTransactionFlags(eTransactionNeeded);
1496 return true;
1497}
1498bool Layer::setCrop(const Rect& crop) {
1499 if (mCurrentState.requested.crop == crop)
1500 return false;
1501 mCurrentState.sequence++;
1502 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001503 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001504 setTransactionFlags(eTransactionNeeded);
1505 return true;
1506}
1507
1508bool Layer::setLayerStack(uint32_t layerStack) {
1509 if (mCurrentState.layerStack == layerStack)
1510 return false;
1511 mCurrentState.sequence++;
1512 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001513 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001514 setTransactionFlags(eTransactionNeeded);
1515 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001516}
1517
Dan Stoza7dde5992015-05-22 09:51:44 -07001518void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1519 uint64_t frameNumber) {
1520 mCurrentState.handle = handle;
1521 mCurrentState.frameNumber = frameNumber;
1522 // We don't set eTransactionNeeded, because just receiving a deferral
1523 // request without any other state updates shouldn't actually induce a delay
1524 mCurrentState.modified = true;
1525 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001526 mCurrentState.handle = nullptr;
1527 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001528 mCurrentState.modified = false;
1529}
1530
Dan Stozaee44edd2015-03-23 15:50:23 -07001531void Layer::useSurfaceDamage() {
1532 if (mFlinger->mForceFullDamage) {
1533 surfaceDamageRegion = Region::INVALID_REGION;
1534 } else {
1535 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1536 }
1537}
1538
1539void Layer::useEmptyDamage() {
1540 surfaceDamageRegion.clear();
1541}
1542
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001543// ----------------------------------------------------------------------------
1544// pageflip handling...
1545// ----------------------------------------------------------------------------
1546
Dan Stoza6b9454d2014-11-07 16:00:59 -08001547bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001548 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001549 return true;
1550 }
1551
Dan Stoza6b9454d2014-11-07 16:00:59 -08001552 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001553 if (mQueueItems.empty()) {
1554 return false;
1555 }
1556 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001557 nsecs_t expectedPresent =
1558 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001559
1560 // Ignore timestamps more than a second in the future
1561 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1562 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1563 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1564 expectedPresent);
1565
1566 bool isDue = timestamp < expectedPresent;
1567 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001568}
1569
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001570bool Layer::onPreComposition() {
1571 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001572 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001573}
1574
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001575void Layer::onPostComposition() {
1576 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001577 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001578 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1579
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001580 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001581 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001582 mFrameTracker.setFrameReadyFence(frameReadyFence);
1583 } else {
1584 // There was no fence for this frame, so assume that it was ready
1585 // to be presented at the desired present time.
1586 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1587 }
1588
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001589 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001590#ifdef USE_HWC2
1591 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1592#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001593 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001594#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001595 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001596 mFrameTracker.setActualPresentFence(presentFence);
1597 } else {
1598 // The HWC doesn't support present fences, so use the refresh
1599 // timestamp instead.
1600 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1601 mFrameTracker.setActualPresentTime(presentTime);
1602 }
1603
1604 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001605 mFrameLatencyNeeded = false;
1606 }
1607}
1608
Dan Stoza9e56aa02015-11-02 13:00:03 -08001609#ifdef USE_HWC2
1610void Layer::releasePendingBuffer() {
1611 mSurfaceFlingerConsumer->releasePendingBuffer();
1612}
1613#endif
1614
Mathias Agopianda27af92012-09-13 18:17:13 -07001615bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001616 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001617#ifdef USE_HWC2
1618 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1619 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1620#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001621 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001622 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001623#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001624}
1625
Mathias Agopian4fec8732012-06-29 14:12:52 -07001626Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001627{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001628 ATRACE_CALL();
1629
Jesse Hall399184a2014-03-03 15:42:54 -08001630 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1631 // mSidebandStreamChanged was true
1632 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001633 if (mSidebandStream != NULL) {
1634 setTransactionFlags(eTransactionNeeded);
1635 mFlinger->setTransactionFlags(eTraversalNeeded);
1636 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001637 recomputeVisibleRegions = true;
1638
1639 const State& s(getDrawingState());
Robert Carr3dcabfa2016-03-01 18:36:58 -08001640 return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001641 }
1642
Mathias Agopian4fec8732012-06-29 14:12:52 -07001643 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001644 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001645
1646 // if we've already called updateTexImage() without going through
1647 // a composition step, we have to skip this layer at this point
1648 // because we cannot call updateTeximage() without a corresponding
1649 // compositionComplete() call.
1650 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001651 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001652 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001653 }
1654
Jamie Gennis351a5132011-09-14 18:23:37 -07001655 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001656 const State& s(getDrawingState());
1657 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001658 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001659
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001660 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001661 Layer::State& front;
1662 Layer::State& current;
1663 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001664 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001665 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001666 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001667 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001668 recomputeVisibleRegions(recomputeVisibleRegions),
1669 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001670 }
1671
1672 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001673 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001674 if (buf == NULL) {
1675 return false;
1676 }
1677
1678 uint32_t bufWidth = buf->getWidth();
1679 uint32_t bufHeight = buf->getHeight();
1680
1681 // check that we received a buffer of the right size
1682 // (Take the buffer's orientation into account)
1683 if (item.mTransform & Transform::ROT_90) {
1684 swap(bufWidth, bufHeight);
1685 }
1686
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001687 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1688 if (front.active != front.requested) {
1689
1690 if (isFixedSize ||
1691 (bufWidth == front.requested.w &&
1692 bufHeight == front.requested.h))
1693 {
1694 // Here we pretend the transaction happened by updating the
1695 // current and drawing states. Drawing state is only accessed
1696 // in this thread, no need to have it locked
1697 front.active = front.requested;
1698
1699 // We also need to update the current state so that
1700 // we don't end-up overwriting the drawing state with
1701 // this stale current state during the next transaction
1702 //
1703 // NOTE: We don't need to hold the transaction lock here
1704 // because State::active is only accessed from this thread.
1705 current.active = front.active;
1706
1707 // recompute visible region
1708 recomputeVisibleRegions = true;
1709 }
1710
1711 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001712 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001713 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1714 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001715 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001716 front.active.w, front.active.h,
1717 front.active.crop.left,
1718 front.active.crop.top,
1719 front.active.crop.right,
1720 front.active.crop.bottom,
1721 front.active.crop.getWidth(),
1722 front.active.crop.getHeight(),
1723 front.requested.w, front.requested.h,
1724 front.requested.crop.left,
1725 front.requested.crop.top,
1726 front.requested.crop.right,
1727 front.requested.crop.bottom,
1728 front.requested.crop.getWidth(),
1729 front.requested.crop.getHeight());
1730 }
1731
Ruben Brunk1681d952014-06-27 15:51:55 -07001732 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001733 if (front.active.w != bufWidth ||
1734 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001735 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001736 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1737 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001738 return true;
1739 }
1740 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001741
1742 // if the transparent region has changed (this test is
1743 // conservative, but that's fine, worst case we're doing
1744 // a bit of extra work), we latch the new one and we
1745 // trigger a visible-region recompute.
1746 if (!front.activeTransparentRegion.isTriviallyEqual(
1747 front.requestedTransparentRegion)) {
1748 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001749
1750 // We also need to update the current state so that
1751 // we don't end-up overwriting the drawing state with
1752 // this stale current state during the next transaction
1753 //
1754 // NOTE: We don't need to hold the transaction lock here
1755 // because State::active is only accessed from this thread.
1756 current.activeTransparentRegion = front.activeTransparentRegion;
1757
1758 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001759 recomputeVisibleRegions = true;
1760 }
1761
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001762 return false;
1763 }
1764 };
1765
Ruben Brunk1681d952014-06-27 15:51:55 -07001766 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1767 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001768
Dan Stozacac35382016-01-27 12:21:06 -08001769
1770 // Check all of our local sync points to ensure that all transactions
1771 // which need to have been applied prior to the frame which is about to
1772 // be latched have signaled
1773
1774 auto headFrameNumber = getHeadFrameNumber();
1775 bool matchingFramesFound = false;
1776 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001777 {
Dan Stozacac35382016-01-27 12:21:06 -08001778 Mutex::Autolock lock(mLocalSyncPointMutex);
1779 for (auto& point : mLocalSyncPoints) {
1780 if (point->getFrameNumber() > headFrameNumber) {
1781 break;
1782 }
1783
1784 matchingFramesFound = true;
1785
1786 if (!point->frameIsAvailable()) {
1787 // We haven't notified the remote layer that the frame for
1788 // this point is available yet. Notify it now, and then
1789 // abort this attempt to latch.
1790 point->setFrameAvailable();
1791 allTransactionsApplied = false;
1792 break;
1793 }
1794
1795 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001796 }
1797 }
1798
Dan Stozacac35382016-01-27 12:21:06 -08001799 if (matchingFramesFound && !allTransactionsApplied) {
1800 mFlinger->signalLayerUpdate();
1801 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001802 }
1803
Pablo Ceballos06312182015-10-07 16:32:12 -07001804 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1805 // of the buffer queue isn't modified when the buffer queue is returning
1806 // BufferItem's that weren't actually queued. This can happen in single
1807 // buffer mode.
1808 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001809 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001810 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001811 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001812 if (updateResult == BufferQueue::PRESENT_LATER) {
1813 // Producer doesn't want buffer to be displayed yet. Signal a
1814 // layer update so we check again at the next opportunity.
1815 mFlinger->signalLayerUpdate();
1816 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001817 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1818 // If the buffer has been rejected, remove it from the shadow queue
1819 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001820 if (queuedBuffer) {
1821 Mutex::Autolock lock(mQueueItemLock);
1822 mQueueItems.removeAt(0);
1823 android_atomic_dec(&mQueuedFrames);
1824 }
Dan Stozaecc50402015-04-28 14:42:06 -07001825 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001826 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1827 // This can occur if something goes wrong when trying to create the
1828 // EGLImage for this buffer. If this happens, the buffer has already
1829 // been released, so we need to clean up the queue and bug out
1830 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001831 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001832 Mutex::Autolock lock(mQueueItemLock);
1833 mQueueItems.clear();
1834 android_atomic_and(0, &mQueuedFrames);
1835 }
1836
1837 // Once we have hit this state, the shadow queue may no longer
1838 // correctly reflect the incoming BufferQueue's contents, so even if
1839 // updateTexImage starts working, the only safe course of action is
1840 // to continue to ignore updates.
1841 mUpdateTexImageFailed = true;
1842
1843 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001844 }
1845
Pablo Ceballos06312182015-10-07 16:32:12 -07001846 if (queuedBuffer) {
1847 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001848 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1849
Dan Stoza6b9454d2014-11-07 16:00:59 -08001850 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001851
1852 // Remove any stale buffers that have been dropped during
1853 // updateTexImage
1854 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1855 mQueueItems.removeAt(0);
1856 android_atomic_dec(&mQueuedFrames);
1857 }
1858
Dan Stoza6b9454d2014-11-07 16:00:59 -08001859 mQueueItems.removeAt(0);
1860 }
1861
Dan Stozaecc50402015-04-28 14:42:06 -07001862
Andy McFadden1585c4d2013-06-28 13:52:40 -07001863 // Decrement the queued-frames count. Signal another event if we
1864 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001865 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001866 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001867 mFlinger->signalLayerUpdate();
1868 }
1869
1870 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001871 // something happened!
1872 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001873 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001874 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001875
Jamie Gennis351a5132011-09-14 18:23:37 -07001876 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001877 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001878 if (mActiveBuffer == NULL) {
1879 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001880 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001881 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001882
Mathias Agopian4824d402012-06-04 18:16:30 -07001883 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001884 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001885 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001886 // the first time we receive a buffer, we need to trigger a
1887 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001888 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001889 }
1890
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001891 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1892 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1893 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001894 if ((crop != mCurrentCrop) ||
1895 (transform != mCurrentTransform) ||
1896 (scalingMode != mCurrentScalingMode))
1897 {
1898 mCurrentCrop = crop;
1899 mCurrentTransform = transform;
1900 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001901 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001902 }
1903
1904 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001905 uint32_t bufWidth = mActiveBuffer->getWidth();
1906 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001907 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1908 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001909 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001910 }
1911 }
1912
1913 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001914 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001915 recomputeVisibleRegions = true;
1916 }
1917
Dan Stozacac35382016-01-27 12:21:06 -08001918 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1919
1920 // Remove any sync points corresponding to the buffer which was just
1921 // latched
1922 {
1923 Mutex::Autolock lock(mLocalSyncPointMutex);
1924 auto point = mLocalSyncPoints.begin();
1925 while (point != mLocalSyncPoints.end()) {
1926 if (!(*point)->frameIsAvailable() ||
1927 !(*point)->transactionIsApplied()) {
1928 // This sync point must have been added since we started
1929 // latching. Don't drop it yet.
1930 ++point;
1931 continue;
1932 }
1933
1934 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1935 point = mLocalSyncPoints.erase(point);
1936 } else {
1937 ++point;
1938 }
1939 }
1940 }
1941
Mathias Agopian4fec8732012-06-29 14:12:52 -07001942 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001943 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001944
1945 // transform the dirty region to window-manager space
Robert Carr3dcabfa2016-03-01 18:36:58 -08001946 outDirtyRegion = (s.active.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001947 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001948 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001949}
1950
Mathias Agopiana67932f2011-04-20 14:20:59 -07001951uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001952{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001953 // TODO: should we do something special if mSecure is set?
1954 if (mProtectedByApp) {
1955 // need a hardware-protected path to external video sink
1956 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001957 }
Riley Andrews03414a12014-07-01 14:22:59 -07001958 if (mPotentialCursor) {
1959 usage |= GraphicBuffer::USAGE_CURSOR;
1960 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001961 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001962 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001963}
1964
Mathias Agopian84300952012-11-21 16:02:13 -08001965void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001966 uint32_t orientation = 0;
1967 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001968 // The transform hint is used to improve performance, but we can
1969 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001970 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001971 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001972 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001973 if (orientation & Transform::ROT_INVALID) {
1974 orientation = 0;
1975 }
1976 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001977 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001978}
1979
Mathias Agopian13127d82013-03-05 17:47:11 -08001980// ----------------------------------------------------------------------------
1981// debugging
1982// ----------------------------------------------------------------------------
1983
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001984void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001985{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001986 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001987
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001988 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001989 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001990 "+ %s %p (%s)\n",
1991 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001992 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001993
Mathias Agopian2ca79392013-04-02 18:30:32 -07001994 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001995 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001996 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001997 sp<Client> client(mClientRef.promote());
1998
Mathias Agopian74d211a2013-04-22 16:55:35 +02001999 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08002000 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
2001 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08002002#ifdef USE_HWC2
2003 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
2004#else
Mathias Agopian13127d82013-03-05 17:47:11 -08002005 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08002006#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002007 " client=%p\n",
Robert Carr3dcabfa2016-03-01 18:36:58 -08002008 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 -08002009 s.active.crop.left, s.active.crop.top,
2010 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002011 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002012 s.alpha, s.flags,
Robert Carr3dcabfa2016-03-01 18:36:58 -08002013 s.active.transform[0][0], s.active.transform[0][1],
2014 s.active.transform[1][0], s.active.transform[1][1],
Mathias Agopian13127d82013-03-05 17:47:11 -08002015 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002016
2017 sp<const GraphicBuffer> buf0(mActiveBuffer);
2018 uint32_t w0=0, h0=0, s0=0, f0=0;
2019 if (buf0 != 0) {
2020 w0 = buf0->getWidth();
2021 h0 = buf0->getHeight();
2022 s0 = buf0->getStride();
2023 f0 = buf0->format;
2024 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002025 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002026 " "
2027 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2028 " queued-frames=%d, mRefreshPending=%d\n",
2029 mFormat, w0, h0, s0,f0,
2030 mQueuedFrames, mRefreshPending);
2031
Mathias Agopian13127d82013-03-05 17:47:11 -08002032 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002033 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002034 }
2035}
2036
Svetoslavd85084b2014-03-20 10:28:31 -07002037void Layer::dumpFrameStats(String8& result) const {
2038 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002039}
2040
Svetoslavd85084b2014-03-20 10:28:31 -07002041void Layer::clearFrameStats() {
2042 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002043}
2044
Jamie Gennis6547ff42013-07-16 20:12:42 -07002045void Layer::logFrameStats() {
2046 mFrameTracker.logAndResetStats(mName);
2047}
2048
Svetoslavd85084b2014-03-20 10:28:31 -07002049void Layer::getFrameStats(FrameStats* outStats) const {
2050 mFrameTracker.getStats(outStats);
2051}
2052
Pablo Ceballos40845df2016-01-25 17:41:15 -08002053void Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
2054 bool* outIsGlesComposition, nsecs_t* outPostedTime,
2055 sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
2056 *outName = mName;
2057 *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2058
2059#ifdef USE_HWC2
2060 *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
2061 mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
2062 HWC2::Composition::Client : true;
2063#else
2064 *outIsGlesComposition = mIsGlesComposition;
2065#endif
2066 *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
2067 *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
2068 *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
2069}
Mathias Agopian13127d82013-03-05 17:47:11 -08002070// ---------------------------------------------------------------------------
2071
2072Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2073 const sp<Layer>& layer)
2074 : mFlinger(flinger), mLayer(layer) {
2075}
2076
2077Layer::LayerCleaner::~LayerCleaner() {
2078 // destroy client resources
2079 mFlinger->onLayerDestroyed(mLayer);
2080}
2081
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002082// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002083}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002084
2085#if defined(__gl_h_)
2086#error "don't include gl/gl.h in this file"
2087#endif
2088
2089#if defined(__gl2_h_)
2090#error "don't include gl2/gl2.h in this file"
2091#endif