blob: 2eedee475d607216aada031c9698ee033ab718df [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();
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000124 mCurrentState.active.finalCrop.makeInvalid();
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700125 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800126#ifdef USE_HWC2
127 mCurrentState.alpha = 1.0f;
128#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700129 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800130#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700131 mCurrentState.layerStack = 0;
132 mCurrentState.flags = layerFlags;
133 mCurrentState.sequence = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700134 mCurrentState.requested = mCurrentState.active;
135
136 // drawing state & current state are identical
137 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700138
Dan Stoza9e56aa02015-11-02 13:00:03 -0800139#ifdef USE_HWC2
140 const auto& hwc = flinger->getHwComposer();
141 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
142 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
143#else
Jamie Gennis6547ff42013-07-16 20:12:42 -0700144 nsecs_t displayPeriod =
145 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800146#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700147 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800148}
149
Mathias Agopian3f844832013-08-07 21:24:32 -0700150void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800151 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700152 sp<IGraphicBufferProducer> producer;
153 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700154 BufferQueue::createBufferQueue(&producer, &consumer);
155 mProducer = new MonitoredProducer(producer, mFlinger);
156 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800157 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800158 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700159 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800160
Dan Stozac9d97202016-03-03 08:20:27 -0800161#ifndef TARGET_DISABLE_TRIPLE_BUFFERING
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700162 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800163#endif
Andy McFadden69052052012-09-14 16:10:11 -0700164
Mathias Agopian84300952012-11-21 16:02:13 -0800165 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
166 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700167}
168
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700169Layer::~Layer() {
Pablo Ceballos8ea4e7b2016-03-03 15:20:02 -0800170 sp<Client> c(mClientRef.promote());
171 if (c != 0) {
172 c->detachLayer(this);
173 }
174
Dan Stozacac35382016-01-27 12:21:06 -0800175 for (auto& point : mRemoteSyncPoints) {
176 point->setTransactionApplied();
177 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700178 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700179 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700180}
181
Mathias Agopian13127d82013-03-05 17:47:11 -0800182// ---------------------------------------------------------------------------
183// callbacks
184// ---------------------------------------------------------------------------
185
Dan Stoza9e56aa02015-11-02 13:00:03 -0800186#ifdef USE_HWC2
187void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
188 if (mHwcLayers.empty()) {
189 return;
190 }
191 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
192}
193#else
Dan Stozac7014012014-02-14 15:03:43 -0800194void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800195 HWComposer::HWCLayerInterface* layer) {
196 if (layer) {
197 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700198 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800199 }
200}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800201#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800202
Dan Stoza6b9454d2014-11-07 16:00:59 -0800203void Layer::onFrameAvailable(const BufferItem& item) {
204 // Add this buffer from our internal queue tracker
205 { // Autolock scope
206 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700207
208 // Reset the frame number tracker when we receive the first buffer after
209 // a frame number reset
210 if (item.mFrameNumber == 1) {
211 mLastFrameNumberReceived = 0;
212 }
213
214 // Ensure that callbacks are handled in order
215 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
216 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
217 ms2ns(500));
218 if (result != NO_ERROR) {
219 ALOGE("[%s] Timed out waiting on callback", mName.string());
220 }
221 }
222
Dan Stoza6b9454d2014-11-07 16:00:59 -0800223 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700224 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700225
226 // Wake up any pending callbacks
227 mLastFrameNumberReceived = item.mFrameNumber;
228 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800229 }
230
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800231 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700232}
233
Dan Stoza6b9454d2014-11-07 16:00:59 -0800234void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700235 { // Autolock scope
236 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700237
Dan Stoza7dde5992015-05-22 09:51:44 -0700238 // Ensure that callbacks are handled in order
239 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
240 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
241 ms2ns(500));
242 if (result != NO_ERROR) {
243 ALOGE("[%s] Timed out waiting on callback", mName.string());
244 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700245 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700246
247 if (mQueueItems.empty()) {
248 ALOGE("Can't replace a frame on an empty queue");
249 return;
250 }
251 mQueueItems.editItemAt(0) = item;
252
253 // Wake up any pending callbacks
254 mLastFrameNumberReceived = item.mFrameNumber;
255 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700256 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800257}
258
Jesse Hall399184a2014-03-03 15:42:54 -0800259void Layer::onSidebandStreamChanged() {
260 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
261 // mSidebandStreamChanged was false
262 mFlinger->signalLayerUpdate();
263 }
264}
265
Mathias Agopian67106042013-03-14 19:18:13 -0700266// called with SurfaceFlinger::mStateLock from the drawing thread after
267// the layer has been remove from the current state list (and just before
268// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800269void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800270 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700271}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700272
Mathias Agopian13127d82013-03-05 17:47:11 -0800273// ---------------------------------------------------------------------------
274// set-up
275// ---------------------------------------------------------------------------
276
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700277const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800278 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800279}
280
Mathias Agopianf9d93272009-06-19 17:00:27 -0700281status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800282 PixelFormat format, uint32_t flags)
283{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700284 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700285 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700286
287 // never allow a surface larger than what our underlying GL implementation
288 // can handle.
289 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800290 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700291 return BAD_VALUE;
292 }
293
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700294 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700295
Riley Andrews03414a12014-07-01 14:22:59 -0700296 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700297 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700298 mCurrentOpacity = getOpacityForFormat(format);
299
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800300 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
301 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
302 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700303
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800304 return NO_ERROR;
305}
306
Dan Stoza7dde5992015-05-22 09:51:44 -0700307/*
308 * The layer handle is just a BBinder object passed to the client
309 * (remote process) -- we don't keep any reference on our side such that
310 * the dtor is called when the remote side let go of its reference.
311 *
312 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
313 * this layer when the handle is destroyed.
314 */
315class Layer::Handle : public BBinder, public LayerCleaner {
316 public:
317 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
318 : LayerCleaner(flinger, layer), owner(layer) {}
319
320 wp<Layer> owner;
321};
322
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700323sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800324 Mutex::Autolock _l(mLock);
325
326 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700327 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800328
329 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700330
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700331 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800332}
333
Dan Stozab9b08832014-03-13 11:55:57 -0700334sp<IGraphicBufferProducer> Layer::getProducer() const {
335 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700336}
337
Mathias Agopian13127d82013-03-05 17:47:11 -0800338// ---------------------------------------------------------------------------
339// h/w composer set-up
340// ---------------------------------------------------------------------------
341
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800342Rect Layer::getContentCrop() const {
343 // this is the crop rectangle that applies to the buffer
344 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700345 Rect crop;
346 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800347 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700348 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800349 } else if (mActiveBuffer != NULL) {
350 // otherwise we use the whole buffer
351 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700352 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800353 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700354 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700355 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700356 return crop;
357}
358
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700359static Rect reduce(const Rect& win, const Region& exclude) {
360 if (CC_LIKELY(exclude.isEmpty())) {
361 return win;
362 }
363 if (exclude.isRect()) {
364 return win.reduce(exclude.getBounds());
365 }
366 return Region(win).subtract(exclude).getBounds();
367}
368
Mathias Agopian13127d82013-03-05 17:47:11 -0800369Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700370 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700371 return computeBounds(s.activeTransparentRegion);
372}
373
374Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
375 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800376 Rect win(s.active.w, s.active.h);
377 if (!s.active.crop.isEmpty()) {
378 win.intersect(s.active.crop, &win);
379 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700380 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700381 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800382}
383
Mathias Agopian6b442672013-07-09 21:24:52 -0700384FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800385 // the content crop is the area of the content that gets scaled to the
386 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700387 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800388
389 // the active.crop is the area of the window that gets cropped, but not
390 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700391 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800392
393 // apply the projection's clipping to the window crop in
394 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700395 // if there are no window scaling involved, this operation will map to full
396 // pixels in the buffer.
397 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
398 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700399
400 Rect activeCrop(s.active.w, s.active.h);
401 if (!s.active.crop.isEmpty()) {
402 activeCrop = s.active.crop;
403 }
404
Robert Carr3dcabfa2016-03-01 18:36:58 -0800405 activeCrop = s.active.transform.transform(activeCrop);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000406 if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
407 activeCrop.clear();
408 }
409 if (!s.active.finalCrop.isEmpty()) {
410 if(!activeCrop.intersect(s.active.finalCrop, &activeCrop)) {
411 activeCrop.clear();
412 }
413 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800414 activeCrop = s.active.transform.inverse().transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800415
Michael Lentine28ea2172014-11-19 18:32:37 -0800416 // This needs to be here as transform.transform(Rect) computes the
417 // transformed rect and then takes the bounding box of the result before
418 // returning. This means
419 // transform.inverse().transform(transform.transform(Rect)) != Rect
420 // in which case we need to make sure the final rect is clipped to the
421 // display bounds.
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000422 if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
423 activeCrop.clear();
424 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800425
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700426 // subtract the transparent region and snap to the bounds
427 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
428
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000429 // Transform the window crop to match the buffer coordinate system,
430 // which means using the inverse of the current transform set on the
431 // SurfaceFlingerConsumer.
432 uint32_t invTransform = mCurrentTransform;
433 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
434 /*
435 * the code below applies the display's inverse transform to the buffer
436 */
437 uint32_t invTransformOrient = hw->getOrientationTransform();
438 // calculate the inverse transform
439 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
440 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
441 NATIVE_WINDOW_TRANSFORM_FLIP_H;
442 // If the transform has been rotated the axis of flip has been swapped
443 // so we need to swap which flip operations we are performing
Michael Lentine7b902582014-08-19 18:14:06 -0700444 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
445 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000446 if (is_h_flipped != is_v_flipped) {
Michael Lentine7b902582014-08-19 18:14:06 -0700447 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
448 NATIVE_WINDOW_TRANSFORM_FLIP_H;
449 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800450 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000451 // and apply to the current transform
452 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
Mathias Agopian13127d82013-03-05 17:47:11 -0800453 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000454
455 int winWidth = s.active.w;
456 int winHeight = s.active.h;
457 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
458 // If the activeCrop has been rotate the ends are rotated but not
459 // the space itself so when transforming ends back we can't rely on
460 // a modification of the axes of rotation. To account for this we
461 // need to reorient the inverse rotation in terms of the current
462 // axes of rotation.
463 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
464 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
465 if (is_h_flipped == is_v_flipped) {
466 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
467 NATIVE_WINDOW_TRANSFORM_FLIP_H;
468 }
469 winWidth = s.active.h;
470 winHeight = s.active.w;
471 }
472 const Rect winCrop = activeCrop.transform(
473 invTransform, s.active.w, s.active.h);
474
475 // below, crop is intersected with winCrop expressed in crop's coordinate space
476 float xScale = crop.getWidth() / float(winWidth);
477 float yScale = crop.getHeight() / float(winHeight);
478
479 float insetL = winCrop.left * xScale;
480 float insetT = winCrop.top * yScale;
481 float insetR = (winWidth - winCrop.right ) * xScale;
482 float insetB = (winHeight - winCrop.bottom) * yScale;
483
484 crop.left += insetL;
485 crop.top += insetT;
486 crop.right -= insetR;
487 crop.bottom -= insetB;
488
Mathias Agopian13127d82013-03-05 17:47:11 -0800489 return crop;
490}
491
Dan Stoza9e56aa02015-11-02 13:00:03 -0800492#ifdef USE_HWC2
493void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
494#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700495void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700496 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700497 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800498#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700499{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800500#ifdef USE_HWC2
501 const auto hwcId = displayDevice->getHwcDisplayId();
502 auto& hwcInfo = mHwcLayers[hwcId];
503#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800504 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800505#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700506
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700507 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800508#ifdef USE_HWC2
509 hwcInfo.forceClientComposition = false;
510
511 if (isSecure() && !displayDevice->isSecure()) {
512 hwcInfo.forceClientComposition = true;
513 }
514
515 auto& hwcLayer = hwcInfo.layer;
516#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700517 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700518
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700519 if (isSecure() && !hw->isSecure()) {
520 layer.setSkip(true);
521 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800522#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700523
Mathias Agopian13127d82013-03-05 17:47:11 -0800524 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700525 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800526#ifdef USE_HWC2
527 if (!isOpaque(s) || s.alpha != 1.0f) {
528 auto blendMode = mPremultipliedAlpha ?
529 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
530 auto error = hwcLayer->setBlendMode(blendMode);
531 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
532 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
533 to_string(error).c_str(), static_cast<int32_t>(error));
534 }
535#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800536 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800537 layer.setBlending(mPremultipliedAlpha ?
538 HWC_BLENDING_PREMULT :
539 HWC_BLENDING_COVERAGE);
540 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800541#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800542
543 // apply the layer's transform, followed by the display's global transform
544 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700545 Region activeTransparentRegion(s.activeTransparentRegion);
546 if (!s.active.crop.isEmpty()) {
547 Rect activeCrop(s.active.crop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800548 activeCrop = s.active.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800549#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000550 if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800551#else
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000552 if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800553#endif
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000554 activeCrop.clear();
555 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800556 activeCrop = s.active.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800557 // This needs to be here as transform.transform(Rect) computes the
558 // transformed rect and then takes the bounding box of the result before
559 // returning. This means
560 // transform.inverse().transform(transform.transform(Rect)) != Rect
561 // in which case we need to make sure the final rect is clipped to the
562 // display bounds.
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000563 if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
564 activeCrop.clear();
565 }
Michael Lentine6c925ed2014-09-26 17:55:01 -0700566 // mark regions outside the crop as transparent
567 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
568 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
569 s.active.w, s.active.h));
570 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
571 activeCrop.left, activeCrop.bottom));
572 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
573 s.active.w, activeCrop.bottom));
574 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800575 Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000576 if (!s.active.finalCrop.isEmpty()) {
577 if(!frame.intersect(s.active.finalCrop, &frame)) {
578 frame.clear();
579 }
580 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800581#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000582 if (!frame.intersect(displayDevice->getViewport(), &frame)) {
583 frame.clear();
584 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800585 const Transform& tr(displayDevice->getTransform());
586 Rect transformedFrame = tr.transform(frame);
587 auto error = hwcLayer->setDisplayFrame(transformedFrame);
588 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
589 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
590 transformedFrame.top, transformedFrame.right,
591 transformedFrame.bottom, to_string(error).c_str(),
592 static_cast<int32_t>(error));
593
594 FloatRect sourceCrop = computeCrop(displayDevice);
595 error = hwcLayer->setSourceCrop(sourceCrop);
596 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
597 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
598 sourceCrop.left, sourceCrop.top, sourceCrop.right,
599 sourceCrop.bottom, to_string(error).c_str(),
600 static_cast<int32_t>(error));
601
602 error = hwcLayer->setPlaneAlpha(s.alpha);
603 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
604 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
605 static_cast<int32_t>(error));
606
607 error = hwcLayer->setZOrder(s.z);
608 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
609 mName.string(), s.z, to_string(error).c_str(),
610 static_cast<int32_t>(error));
611#else
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000612 if (!frame.intersect(hw->getViewport(), &frame)) {
613 frame.clear();
614 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800615 const Transform& tr(hw->getTransform());
616 layer.setFrame(tr.transform(frame));
617 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800618 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800619#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800620
Mathias Agopian29a367b2011-07-12 14:51:45 -0700621 /*
622 * Transformations are applied in this order:
623 * 1) buffer orientation/flip/mirror
624 * 2) state transformation (window manager)
625 * 3) layer orientation (screen orientation)
626 * (NOTE: the matrices are multiplied in reverse order)
627 */
628
629 const Transform bufferOrientation(mCurrentTransform);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800630 Transform transform(tr * s.active.transform * bufferOrientation);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700631
632 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
633 /*
634 * the code below applies the display's inverse transform to the buffer
635 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800636#ifdef USE_HWC2
637 uint32_t invTransform = displayDevice->getOrientationTransform();
638#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700639 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800640#endif
Michael Lentine14409632014-08-19 11:27:30 -0700641 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700642 // calculate the inverse transform
643 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
644 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
645 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700646 // If the transform has been rotated the axis of flip has been swapped
647 // so we need to swap which flip operations we are performing
648 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
649 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
650 if (is_h_flipped != is_v_flipped) {
651 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
652 NATIVE_WINDOW_TRANSFORM_FLIP_H;
653 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700654 }
655 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700656 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700657 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700658
659 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800660 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800661#ifdef USE_HWC2
662 if (orientation & Transform::ROT_INVALID) {
663 // we can only handle simple transformation
664 hwcInfo.forceClientComposition = true;
665 } else {
666 auto transform = static_cast<HWC2::Transform>(orientation);
667 auto error = hwcLayer->setTransform(transform);
668 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
669 "%s (%d)", mName.string(), to_string(transform).c_str(),
670 to_string(error).c_str(), static_cast<int32_t>(error));
671 }
672#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800673 if (orientation & Transform::ROT_INVALID) {
674 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700675 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700676 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800677 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700678 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800679#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700680}
681
Dan Stoza9e56aa02015-11-02 13:00:03 -0800682#ifdef USE_HWC2
683void Layer::forceClientComposition(int32_t hwcId) {
684 if (mHwcLayers.count(hwcId) == 0) {
685 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
686 return;
687 }
688
689 mHwcLayers[hwcId].forceClientComposition = true;
690}
691#endif
692
693#ifdef USE_HWC2
694void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
695 // Apply this display's projection's viewport to the visible region
696 // before giving it to the HWC HAL.
697 const Transform& tr = displayDevice->getTransform();
698 const auto& viewport = displayDevice->getViewport();
699 Region visible = tr.transform(visibleRegion.intersect(viewport));
700 auto hwcId = displayDevice->getHwcDisplayId();
701 auto& hwcLayer = mHwcLayers[hwcId].layer;
702 auto error = hwcLayer->setVisibleRegion(visible);
703 if (error != HWC2::Error::None) {
704 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
705 to_string(error).c_str(), static_cast<int32_t>(error));
706 visible.dump(LOG_TAG);
707 }
708
709 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
710 if (error != HWC2::Error::None) {
711 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
712 to_string(error).c_str(), static_cast<int32_t>(error));
713 surfaceDamageRegion.dump(LOG_TAG);
714 }
715
716 auto compositionType = HWC2::Composition::Invalid;
717 if (mSidebandStream.get()) {
718 compositionType = HWC2::Composition::Sideband;
719 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
720 if (error != HWC2::Error::None) {
721 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
722 mName.string(), mSidebandStream->handle(),
723 to_string(error).c_str(), static_cast<int32_t>(error));
724 return;
725 }
726 } else {
727 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
728 compositionType = HWC2::Composition::Client;
729 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
730 if (error != HWC2::Error::None) {
731 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
732 to_string(error).c_str(), static_cast<int32_t>(error));
733 return;
734 }
735 } else {
736 if (mPotentialCursor) {
737 compositionType = HWC2::Composition::Cursor;
738 }
739 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
740 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
741 acquireFence);
742 if (error != HWC2::Error::None) {
743 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
744 mActiveBuffer->handle, to_string(error).c_str(),
745 static_cast<int32_t>(error));
746 return;
747 }
748 // If it's not a cursor, default to device composition
749 }
750 }
751
752 if (mHwcLayers[hwcId].forceClientComposition) {
753 ALOGV("[%s] Forcing Client composition", mName.string());
754 setCompositionType(hwcId, HWC2::Composition::Client);
755 } else if (compositionType != HWC2::Composition::Invalid) {
756 ALOGV("[%s] Requesting %s composition", mName.string(),
757 to_string(compositionType).c_str());
758 setCompositionType(hwcId, compositionType);
759 } else {
760 ALOGV("[%s] Requesting Device composition", mName.string());
761 setCompositionType(hwcId, HWC2::Composition::Device);
762 }
763}
764#else
Mathias Agopian42977342012-08-05 00:40:46 -0700765void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700766 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800767 // we have to set the visible region on every frame because
768 // we currently free it during onLayerDisplayed(), which is called
769 // after HWComposer::commit() -- every frame.
770 // Apply this display's projection's viewport to the visible region
771 // before giving it to the HWC HAL.
772 const Transform& tr = hw->getTransform();
773 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
774 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700775 layer.setSurfaceDamage(surfaceDamageRegion);
Pablo Ceballos40845df2016-01-25 17:41:15 -0800776 mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
Dan Stozaee44edd2015-03-23 15:50:23 -0700777
Jesse Hall399184a2014-03-03 15:42:54 -0800778 if (mSidebandStream.get()) {
779 layer.setSidebandStream(mSidebandStream);
780 } else {
781 // NOTE: buffer can be NULL if the client never drew into this
782 // layer yet, or if we ran out of memory
783 layer.setBuffer(mActiveBuffer);
784 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700785}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800786#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700787
Dan Stoza9e56aa02015-11-02 13:00:03 -0800788#ifdef USE_HWC2
789void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
790 auto hwcId = displayDevice->getHwcDisplayId();
791 if (mHwcLayers.count(hwcId) == 0 ||
792 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
793 return;
794 }
795
796 // This gives us only the "orientation" component of the transform
797 const State& s(getCurrentState());
798
799 // Apply the layer's transform, followed by the display's global transform
800 // Here we're guaranteed that the layer's transform preserves rects
801 Rect win(s.active.w, s.active.h);
802 if (!s.active.crop.isEmpty()) {
803 win.intersect(s.active.crop, &win);
804 }
805 // Subtract the transparent region and snap to the bounds
806 Rect bounds = reduce(win, s.activeTransparentRegion);
Dan Stozabaf416d2016-03-10 11:57:08 -0800807 Rect frame(s.active.transform.transform(bounds));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800808 frame.intersect(displayDevice->getViewport(), &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000809 if (!s.active.finalCrop.isEmpty()) {
810 frame.intersect(s.active.finalCrop, &frame);
811 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800812 auto& displayTransform(displayDevice->getTransform());
813 auto position = displayTransform.transform(frame);
814
815 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
816 position.top);
817 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
818 "to (%d, %d): %s (%d)", mName.string(), position.left,
819 position.top, to_string(error).c_str(),
820 static_cast<int32_t>(error));
821}
822#else
Dan Stozac7014012014-02-14 15:03:43 -0800823void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700824 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700825 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700826
827 // TODO: there is a possible optimization here: we only need to set the
828 // acquire fence the first time a new buffer is acquired on EACH display.
829
Riley Andrews03414a12014-07-01 14:22:59 -0700830 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800831 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800832 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700833 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700834 if (fenceFd == -1) {
835 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
836 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700837 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700838 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700839 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700840}
841
Riley Andrews03414a12014-07-01 14:22:59 -0700842Rect Layer::getPosition(
843 const sp<const DisplayDevice>& hw)
844{
845 // this gives us only the "orientation" component of the transform
846 const State& s(getCurrentState());
847
848 // apply the layer's transform, followed by the display's global transform
849 // here we're guaranteed that the layer's transform preserves rects
850 Rect win(s.active.w, s.active.h);
851 if (!s.active.crop.isEmpty()) {
852 win.intersect(s.active.crop, &win);
853 }
854 // subtract the transparent region and snap to the bounds
855 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800856 Rect frame(s.active.transform.transform(bounds));
Riley Andrews03414a12014-07-01 14:22:59 -0700857 frame.intersect(hw->getViewport(), &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000858 if (!s.active.finalCrop.isEmpty()) {
859 frame.intersect(s.active.finalCrop, &frame);
860 }
Riley Andrews03414a12014-07-01 14:22:59 -0700861 const Transform& tr(hw->getTransform());
862 return Rect(tr.transform(frame));
863}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800864#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700865
Mathias Agopian13127d82013-03-05 17:47:11 -0800866// ---------------------------------------------------------------------------
867// drawing...
868// ---------------------------------------------------------------------------
869
870void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800871 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800872}
873
Dan Stozac7014012014-02-14 15:03:43 -0800874void Layer::draw(const sp<const DisplayDevice>& hw,
875 bool useIdentityTransform) const {
876 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800877}
878
Dan Stozac7014012014-02-14 15:03:43 -0800879void Layer::draw(const sp<const DisplayDevice>& hw) const {
880 onDraw(hw, Region(hw->bounds()), false);
881}
882
883void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
884 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800885{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800886 ATRACE_CALL();
887
Mathias Agopiana67932f2011-04-20 14:20:59 -0700888 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800889 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700890 // in fact never been drawn into. This happens frequently with
891 // SurfaceView because the WindowManager can't know when the client
892 // has drawn the first time.
893
894 // If there is nothing under us, we paint the screen in black, otherwise
895 // we just skip this update.
896
897 // figure out if there is something below us
898 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700899 const SurfaceFlinger::LayerVector& drawingLayers(
900 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700901 const size_t count = drawingLayers.size();
902 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800903 const sp<Layer>& layer(drawingLayers[i]);
904 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700905 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700906 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700907 }
908 // if not everything below us is covered, we plug the holes!
909 Region holes(clip.subtract(under));
910 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700911 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700912 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800913 return;
914 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700915
Andy McFadden97eba892012-12-11 15:21:45 -0800916 // Bind the current buffer to the GL texture, and wait for it to be
917 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800918 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
919 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800920 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700921 // Go ahead and draw the buffer anyway; no matter what we do the screen
922 // is probably going to have something visibly wrong.
923 }
924
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700925 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
926
Mathias Agopian875d8e12013-06-07 15:35:48 -0700927 RenderEngine& engine(mFlinger->getRenderEngine());
928
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700929 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700930 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700931 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700932
933 // Query the texture matrix given our current filtering mode.
934 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800935 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
936 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700937
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700938 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
939
940 /*
941 * the code below applies the display's inverse transform to the texture transform
942 */
943
944 // create a 4x4 transform matrix from the display transform flags
945 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
946 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
947 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
948
949 mat4 tr;
950 uint32_t transform = hw->getOrientationTransform();
951 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
952 tr = tr * rot90;
953 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
954 tr = tr * flipH;
955 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
956 tr = tr * flipV;
957
958 // calculate the inverse
959 tr = inverse(tr);
960
961 // and finally apply it to the original texture matrix
962 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
963 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
964 }
965
Jamie Genniscbb1a952012-05-08 17:05:52 -0700966 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700967 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
968 mTexture.setFiltering(useFiltering);
969 mTexture.setMatrix(textureMatrix);
970
971 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700972 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700973 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700974 }
Dan Stozac7014012014-02-14 15:03:43 -0800975 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700976 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800977}
978
Mathias Agopian13127d82013-03-05 17:47:11 -0800979
Dan Stozac7014012014-02-14 15:03:43 -0800980void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
981 const Region& /* clip */, float red, float green, float blue,
982 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800983{
Mathias Agopian19733a32013-08-28 18:13:56 -0700984 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800985 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700986 engine.setupFillWithColor(red, green, blue, alpha);
987 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800988}
989
990void Layer::clearWithOpenGL(
991 const sp<const DisplayDevice>& hw, const Region& clip) const {
992 clearWithOpenGL(hw, clip, 0,0,0,0);
993}
994
Dan Stozac7014012014-02-14 15:03:43 -0800995void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
996 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700997 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800998
Dan Stozac7014012014-02-14 15:03:43 -0800999 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -08001000
Mathias Agopian13127d82013-03-05 17:47:11 -08001001 /*
1002 * NOTE: the way we compute the texture coordinates here produces
1003 * different results than when we take the HWC path -- in the later case
1004 * the "source crop" is rounded to texel boundaries.
1005 * This can produce significantly different results when the texture
1006 * is scaled by a large amount.
1007 *
1008 * The GL code below is more logical (imho), and the difference with
1009 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -07001010 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -08001011 * GL composition when a buffer scaling is applied (maybe with some
1012 * minimal value)? Or, we could make GL behave like HWC -- but this feel
1013 * like more of a hack.
1014 */
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001015 Rect win(computeBounds());
1016
1017 if (!s.active.finalCrop.isEmpty()) {
1018 win = s.active.transform.transform(win);
1019 if (!win.intersect(s.active.finalCrop, &win)) {
1020 win.clear();
1021 }
1022 win = s.active.transform.inverse().transform(win);
1023 if (!win.intersect(computeBounds(), &win)) {
1024 win.clear();
1025 }
1026 }
Mathias Agopian13127d82013-03-05 17:47:11 -08001027
Mathias Agopian3f844832013-08-07 21:24:32 -07001028 float left = float(win.left) / float(s.active.w);
1029 float top = float(win.top) / float(s.active.h);
1030 float right = float(win.right) / float(s.active.w);
1031 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -08001032
Mathias Agopian875d8e12013-06-07 15:35:48 -07001033 // TODO: we probably want to generate the texture coords with the mesh
1034 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -07001035 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1036 texCoords[0] = vec2(left, 1.0f - top);
1037 texCoords[1] = vec2(left, 1.0f - bottom);
1038 texCoords[2] = vec2(right, 1.0f - bottom);
1039 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -08001040
Mathias Agopian875d8e12013-06-07 15:35:48 -07001041 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -08001042 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001043 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001044 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001045}
1046
Dan Stoza9e56aa02015-11-02 13:00:03 -08001047#ifdef USE_HWC2
1048void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1049 bool callIntoHwc) {
1050 if (mHwcLayers.count(hwcId) == 0) {
1051 ALOGE("setCompositionType called without a valid HWC layer");
1052 return;
1053 }
1054 auto& hwcInfo = mHwcLayers[hwcId];
1055 auto& hwcLayer = hwcInfo.layer;
1056 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1057 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1058 if (hwcInfo.compositionType != type) {
1059 ALOGV(" actually setting");
1060 hwcInfo.compositionType = type;
1061 if (callIntoHwc) {
1062 auto error = hwcLayer->setCompositionType(type);
1063 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1064 "composition type %s: %s (%d)", mName.string(),
1065 to_string(type).c_str(), to_string(error).c_str(),
1066 static_cast<int32_t>(error));
1067 }
1068 }
1069}
1070
1071HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1072 if (mHwcLayers.count(hwcId) == 0) {
1073 ALOGE("getCompositionType called without a valid HWC layer");
1074 return HWC2::Composition::Invalid;
1075 }
1076 return mHwcLayers.at(hwcId).compositionType;
1077}
1078
1079void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1080 if (mHwcLayers.count(hwcId) == 0) {
1081 ALOGE("setClearClientTarget called without a valid HWC layer");
1082 return;
1083 }
1084 mHwcLayers[hwcId].clearClientTarget = clear;
1085}
1086
1087bool Layer::getClearClientTarget(int32_t hwcId) const {
1088 if (mHwcLayers.count(hwcId) == 0) {
1089 ALOGE("getClearClientTarget called without a valid HWC layer");
1090 return false;
1091 }
1092 return mHwcLayers.at(hwcId).clearClientTarget;
1093}
1094#endif
1095
Ruben Brunk1681d952014-06-27 15:51:55 -07001096uint32_t Layer::getProducerStickyTransform() const {
1097 int producerStickyTransform = 0;
1098 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1099 if (ret != OK) {
1100 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1101 strerror(-ret), ret);
1102 return 0;
1103 }
1104 return static_cast<uint32_t>(producerStickyTransform);
1105}
1106
Dan Stozacac35382016-01-27 12:21:06 -08001107uint64_t Layer::getHeadFrameNumber() const {
1108 Mutex::Autolock lock(mQueueItemLock);
1109 if (!mQueueItems.empty()) {
1110 return mQueueItems[0].mFrameNumber;
1111 } else {
1112 return mCurrentFrameNumber;
1113 }
1114}
1115
1116bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1117 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1118 // Don't bother with a SyncPoint, since we've already latched the
1119 // relevant frame
1120 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001121 }
1122
Dan Stozacac35382016-01-27 12:21:06 -08001123 Mutex::Autolock lock(mLocalSyncPointMutex);
1124 mLocalSyncPoints.push_back(point);
1125 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001126}
1127
Mathias Agopian13127d82013-03-05 17:47:11 -08001128void Layer::setFiltering(bool filtering) {
1129 mFiltering = filtering;
1130}
1131
1132bool Layer::getFiltering() const {
1133 return mFiltering;
1134}
1135
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001136// As documented in libhardware header, formats in the range
1137// 0x100 - 0x1FF are specific to the HAL implementation, and
1138// are known to have no alpha channel
1139// TODO: move definition for device-specific range into
1140// hardware.h, instead of using hard-coded values here.
1141#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1142
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001143bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001144 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1145 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001146 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001147 switch (format) {
1148 case HAL_PIXEL_FORMAT_RGBA_8888:
1149 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001150 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001151 }
1152 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001153 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001154}
1155
Mathias Agopian13127d82013-03-05 17:47:11 -08001156// ----------------------------------------------------------------------------
1157// local state
1158// ----------------------------------------------------------------------------
1159
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001160static void boundPoint(vec2* point, const Rect& crop) {
1161 if (point->x < crop.left) {
1162 point->x = crop.left;
1163 }
1164 if (point->x > crop.right) {
1165 point->x = crop.right;
1166 }
1167 if (point->y < crop.top) {
1168 point->y = crop.top;
1169 }
1170 if (point->y > crop.bottom) {
1171 point->y = crop.bottom;
1172 }
1173}
1174
Dan Stozac7014012014-02-14 15:03:43 -08001175void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1176 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001177{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001178 const Layer::State& s(getDrawingState());
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001179 const Transform tr(hw->getTransform());
Mathias Agopian13127d82013-03-05 17:47:11 -08001180 const uint32_t hw_h = hw->getHeight();
1181 Rect win(s.active.w, s.active.h);
1182 if (!s.active.crop.isEmpty()) {
1183 win.intersect(s.active.crop, &win);
1184 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001185 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001186 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001187
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001188 vec2 lt = vec2(win.left, win.top);
1189 vec2 lb = vec2(win.left, win.bottom);
1190 vec2 rb = vec2(win.right, win.bottom);
1191 vec2 rt = vec2(win.right, win.top);
1192
1193 if (!useIdentityTransform) {
1194 lt = s.active.transform.transform(lt);
1195 lb = s.active.transform.transform(lb);
1196 rb = s.active.transform.transform(rb);
1197 rt = s.active.transform.transform(rt);
1198 }
1199
1200 if (!s.active.finalCrop.isEmpty()) {
1201 boundPoint(&lt, s.active.finalCrop);
1202 boundPoint(&lb, s.active.finalCrop);
1203 boundPoint(&rb, s.active.finalCrop);
1204 boundPoint(&rt, s.active.finalCrop);
1205 }
1206
Mathias Agopianff2ed702013-09-01 21:36:12 -07001207 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001208 position[0] = tr.transform(lt);
1209 position[1] = tr.transform(lb);
1210 position[2] = tr.transform(rb);
1211 position[3] = tr.transform(rt);
Mathias Agopian3f844832013-08-07 21:24:32 -07001212 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001213 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001214 }
1215}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001216
Andy McFadden4125a4f2014-01-29 17:17:11 -08001217bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001218{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001219 // if we don't have a buffer yet, we're translucent regardless of the
1220 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001221 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001222 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001223 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001224
1225 // if the layer has the opaque flag, then we're always opaque,
1226 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001227 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001228}
1229
Dan Stoza23116082015-06-18 14:58:39 -07001230bool Layer::isSecure() const
1231{
1232 const Layer::State& s(mDrawingState);
1233 return (s.flags & layer_state_t::eLayerSecure);
1234}
1235
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001236bool Layer::isProtected() const
1237{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001238 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001239 return (activeBuffer != 0) &&
1240 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1241}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001242
Mathias Agopian13127d82013-03-05 17:47:11 -08001243bool Layer::isFixedSize() const {
1244 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1245}
1246
1247bool Layer::isCropped() const {
1248 return !mCurrentCrop.isEmpty();
1249}
1250
1251bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1252 return mNeedsFiltering || hw->needsFiltering();
1253}
1254
1255void Layer::setVisibleRegion(const Region& visibleRegion) {
1256 // always called from main thread
1257 this->visibleRegion = visibleRegion;
1258}
1259
1260void Layer::setCoveredRegion(const Region& coveredRegion) {
1261 // always called from main thread
1262 this->coveredRegion = coveredRegion;
1263}
1264
1265void Layer::setVisibleNonTransparentRegion(const Region&
1266 setVisibleNonTransparentRegion) {
1267 // always called from main thread
1268 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1269}
1270
1271// ----------------------------------------------------------------------------
1272// transaction
1273// ----------------------------------------------------------------------------
1274
Dan Stoza7dde5992015-05-22 09:51:44 -07001275void Layer::pushPendingState() {
1276 if (!mCurrentState.modified) {
1277 return;
1278 }
1279
Dan Stoza7dde5992015-05-22 09:51:44 -07001280 // If this transaction is waiting on the receipt of a frame, generate a sync
1281 // point and send it to the remote layer.
1282 if (mCurrentState.handle != nullptr) {
1283 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1284 sp<Layer> handleLayer = handle->owner.promote();
1285 if (handleLayer == nullptr) {
1286 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1287 // If we can't promote the layer we are intended to wait on,
1288 // then it is expired or otherwise invalid. Allow this transaction
1289 // to be applied as per normal (no synchronization).
1290 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001291 } else {
1292 auto syncPoint = std::make_shared<SyncPoint>(
1293 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001294 if (handleLayer->addSyncPoint(syncPoint)) {
1295 mRemoteSyncPoints.push_back(std::move(syncPoint));
1296 } else {
1297 // We already missed the frame we're supposed to synchronize
1298 // on, so go ahead and apply the state update
1299 mCurrentState.handle = nullptr;
1300 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001301 }
1302
Dan Stoza7dde5992015-05-22 09:51:44 -07001303 // Wake us up to check if the frame has been received
1304 setTransactionFlags(eTransactionNeeded);
1305 }
1306 mPendingStates.push_back(mCurrentState);
1307}
1308
1309void Layer::popPendingState() {
1310 auto oldFlags = mCurrentState.flags;
1311 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001312 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001313 (mCurrentState.flags & mCurrentState.mask);
1314
1315 mPendingStates.removeAt(0);
1316}
1317
1318bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001319 bool stateUpdateAvailable = false;
1320 while (!mPendingStates.empty()) {
1321 if (mPendingStates[0].handle != nullptr) {
1322 if (mRemoteSyncPoints.empty()) {
1323 // If we don't have a sync point for this, apply it anyway. It
1324 // will be visually wrong, but it should keep us from getting
1325 // into too much trouble.
1326 ALOGE("[%s] No local sync point found", mName.string());
1327 popPendingState();
1328 stateUpdateAvailable = true;
1329 continue;
1330 }
1331
Dan Stozacac35382016-01-27 12:21:06 -08001332 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1333 mPendingStates[0].frameNumber) {
1334 ALOGE("[%s] Unexpected sync point frame number found",
1335 mName.string());
1336
1337 // Signal our end of the sync point and then dispose of it
1338 mRemoteSyncPoints.front()->setTransactionApplied();
1339 mRemoteSyncPoints.pop_front();
1340 continue;
1341 }
1342
Dan Stoza7dde5992015-05-22 09:51:44 -07001343 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1344 // Apply the state update
1345 popPendingState();
1346 stateUpdateAvailable = true;
1347
1348 // Signal our end of the sync point and then dispose of it
1349 mRemoteSyncPoints.front()->setTransactionApplied();
1350 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001351 } else {
1352 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001353 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001354 } else {
1355 popPendingState();
1356 stateUpdateAvailable = true;
1357 }
1358 }
1359
1360 // If we still have pending updates, wake SurfaceFlinger back up and point
1361 // it at this layer so we can process them
1362 if (!mPendingStates.empty()) {
1363 setTransactionFlags(eTransactionNeeded);
1364 mFlinger->setTransactionFlags(eTraversalNeeded);
1365 }
1366
1367 mCurrentState.modified = false;
1368 return stateUpdateAvailable;
1369}
1370
1371void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001372 auto headFrameNumber = getHeadFrameNumber();
1373 Mutex::Autolock lock(mLocalSyncPointMutex);
1374 for (auto& point : mLocalSyncPoints) {
1375 if (headFrameNumber >= point->getFrameNumber()) {
1376 point->setFrameAvailable();
1377 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001378 }
1379}
1380
Mathias Agopian13127d82013-03-05 17:47:11 -08001381uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001382 ATRACE_CALL();
1383
Dan Stoza7dde5992015-05-22 09:51:44 -07001384 pushPendingState();
1385 if (!applyPendingStates()) {
1386 return 0;
1387 }
1388
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001389 const Layer::State& s(getDrawingState());
1390 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001391
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001392 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1393 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001394
1395 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001396 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001397 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001398 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001399 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1400 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1401 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1402 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001403 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1404 c.active.w, c.active.h,
1405 c.active.crop.left,
1406 c.active.crop.top,
1407 c.active.crop.right,
1408 c.active.crop.bottom,
1409 c.active.crop.getWidth(),
1410 c.active.crop.getHeight(),
1411 c.requested.w, c.requested.h,
1412 c.requested.crop.left,
1413 c.requested.crop.top,
1414 c.requested.crop.right,
1415 c.requested.crop.bottom,
1416 c.requested.crop.getWidth(),
1417 c.requested.crop.getHeight(),
1418 s.active.w, s.active.h,
1419 s.active.crop.left,
1420 s.active.crop.top,
1421 s.active.crop.right,
1422 s.active.crop.bottom,
1423 s.active.crop.getWidth(),
1424 s.active.crop.getHeight(),
1425 s.requested.w, s.requested.h,
1426 s.requested.crop.left,
1427 s.requested.crop.top,
1428 s.requested.crop.right,
1429 s.requested.crop.bottom,
1430 s.requested.crop.getWidth(),
1431 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001432
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001433 // record the new size, form this point on, when the client request
1434 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001435 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001436 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001437 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001438
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001439 if (!isFixedSize()) {
1440
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001441 const bool resizePending = (c.requested.w != c.active.w) ||
1442 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001443
Dan Stoza9e9b0442015-04-22 14:59:08 -07001444 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001445 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001446 // if we have a pending resize, unless we are in fixed-size mode.
1447 // the drawing state will be updated only once we receive a buffer
1448 // with the correct size.
1449 //
1450 // in particular, we want to make sure the clip (which is part
1451 // of the geometry state) is latched together with the size but is
1452 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001453 //
1454 // If a sideband stream is attached, however, we want to skip this
1455 // optimization so that transactions aren't missed when a buffer
1456 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001457
1458 flags |= eDontUpdateGeometryState;
1459 }
1460 }
1461
Mathias Agopian13127d82013-03-05 17:47:11 -08001462 // always set active to requested, unless we're asked not to
1463 // this is used by Layer, which special cases resizes.
1464 if (flags & eDontUpdateGeometryState) {
1465 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001466 Layer::State& editCurrentState(getCurrentState());
1467 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001468 }
1469
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001470 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001471 // invalidate and recompute the visible regions if needed
1472 flags |= Layer::eVisibleRegion;
1473 }
1474
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001475 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001476 // invalidate and recompute the visible regions if needed
1477 flags |= eVisibleRegion;
1478 this->contentDirty = true;
1479
1480 // we may use linear filtering, if the matrix scales us
Robert Carr3dcabfa2016-03-01 18:36:58 -08001481 const uint8_t type = c.active.transform.getType();
1482 mNeedsFiltering = (!c.active.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001483 (type >= Transform::SCALE));
1484 }
1485
1486 // Commit the transaction
1487 commitTransaction();
1488 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001489}
1490
Mathias Agopian13127d82013-03-05 17:47:11 -08001491void Layer::commitTransaction() {
1492 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001493}
1494
Mathias Agopian13127d82013-03-05 17:47:11 -08001495uint32_t Layer::getTransactionFlags(uint32_t flags) {
1496 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1497}
1498
1499uint32_t Layer::setTransactionFlags(uint32_t flags) {
1500 return android_atomic_or(flags, &mTransactionFlags);
1501}
1502
1503bool Layer::setPosition(float x, float y) {
Robert Carr3dcabfa2016-03-01 18:36:58 -08001504 if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
Mathias Agopian13127d82013-03-05 17:47:11 -08001505 return false;
1506 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001507 mCurrentState.requested.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001508 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001509 setTransactionFlags(eTransactionNeeded);
1510 return true;
1511}
1512bool Layer::setLayer(uint32_t z) {
1513 if (mCurrentState.z == z)
1514 return false;
1515 mCurrentState.sequence++;
1516 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001517 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001518 setTransactionFlags(eTransactionNeeded);
1519 return true;
1520}
1521bool Layer::setSize(uint32_t w, uint32_t h) {
1522 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1523 return false;
1524 mCurrentState.requested.w = w;
1525 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001526 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001527 setTransactionFlags(eTransactionNeeded);
1528 return true;
1529}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001530#ifdef USE_HWC2
1531bool Layer::setAlpha(float alpha) {
1532#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001533bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001534#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001535 if (mCurrentState.alpha == alpha)
1536 return false;
1537 mCurrentState.sequence++;
1538 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001539 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001540 setTransactionFlags(eTransactionNeeded);
1541 return true;
1542}
1543bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1544 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001545 mCurrentState.requested.transform.set(
Mathias Agopian13127d82013-03-05 17:47:11 -08001546 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001547 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001548 setTransactionFlags(eTransactionNeeded);
1549 return true;
1550}
1551bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001552 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001553 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001554 setTransactionFlags(eTransactionNeeded);
1555 return true;
1556}
1557bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1558 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1559 if (mCurrentState.flags == newFlags)
1560 return false;
1561 mCurrentState.sequence++;
1562 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001563 mCurrentState.mask = mask;
1564 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001565 setTransactionFlags(eTransactionNeeded);
1566 return true;
1567}
1568bool Layer::setCrop(const Rect& crop) {
1569 if (mCurrentState.requested.crop == crop)
1570 return false;
1571 mCurrentState.sequence++;
1572 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001573 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001574 setTransactionFlags(eTransactionNeeded);
1575 return true;
1576}
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001577bool Layer::setFinalCrop(const Rect& crop) {
1578 if (mCurrentState.requested.finalCrop == crop)
1579 return false;
1580 mCurrentState.sequence++;
1581 mCurrentState.requested.finalCrop = crop;
1582 mCurrentState.modified = true;
1583 setTransactionFlags(eTransactionNeeded);
1584 return true;
1585}
Mathias Agopian13127d82013-03-05 17:47:11 -08001586
1587bool Layer::setLayerStack(uint32_t layerStack) {
1588 if (mCurrentState.layerStack == layerStack)
1589 return false;
1590 mCurrentState.sequence++;
1591 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001592 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001593 setTransactionFlags(eTransactionNeeded);
1594 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001595}
1596
Dan Stoza7dde5992015-05-22 09:51:44 -07001597void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1598 uint64_t frameNumber) {
1599 mCurrentState.handle = handle;
1600 mCurrentState.frameNumber = frameNumber;
1601 // We don't set eTransactionNeeded, because just receiving a deferral
1602 // request without any other state updates shouldn't actually induce a delay
1603 mCurrentState.modified = true;
1604 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001605 mCurrentState.handle = nullptr;
1606 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001607 mCurrentState.modified = false;
1608}
1609
Dan Stozaee44edd2015-03-23 15:50:23 -07001610void Layer::useSurfaceDamage() {
1611 if (mFlinger->mForceFullDamage) {
1612 surfaceDamageRegion = Region::INVALID_REGION;
1613 } else {
1614 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1615 }
1616}
1617
1618void Layer::useEmptyDamage() {
1619 surfaceDamageRegion.clear();
1620}
1621
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001622// ----------------------------------------------------------------------------
1623// pageflip handling...
1624// ----------------------------------------------------------------------------
1625
Dan Stoza6b9454d2014-11-07 16:00:59 -08001626bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001627 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001628 return true;
1629 }
1630
Dan Stoza6b9454d2014-11-07 16:00:59 -08001631 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001632 if (mQueueItems.empty()) {
1633 return false;
1634 }
1635 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001636 nsecs_t expectedPresent =
1637 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001638
1639 // Ignore timestamps more than a second in the future
1640 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1641 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1642 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1643 expectedPresent);
1644
1645 bool isDue = timestamp < expectedPresent;
1646 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001647}
1648
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001649bool Layer::onPreComposition() {
1650 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001651 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001652}
1653
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001654void Layer::onPostComposition() {
1655 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001656 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001657 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1658
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001659 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001660 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001661 mFrameTracker.setFrameReadyFence(frameReadyFence);
1662 } else {
1663 // There was no fence for this frame, so assume that it was ready
1664 // to be presented at the desired present time.
1665 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1666 }
1667
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001668 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001669#ifdef USE_HWC2
1670 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1671#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001672 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001673#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001674 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001675 mFrameTracker.setActualPresentFence(presentFence);
1676 } else {
1677 // The HWC doesn't support present fences, so use the refresh
1678 // timestamp instead.
1679 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1680 mFrameTracker.setActualPresentTime(presentTime);
1681 }
1682
1683 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001684 mFrameLatencyNeeded = false;
1685 }
1686}
1687
Dan Stoza9e56aa02015-11-02 13:00:03 -08001688#ifdef USE_HWC2
1689void Layer::releasePendingBuffer() {
1690 mSurfaceFlingerConsumer->releasePendingBuffer();
1691}
1692#endif
1693
Mathias Agopianda27af92012-09-13 18:17:13 -07001694bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001695 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001696#ifdef USE_HWC2
1697 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1698 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1699#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001700 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001701 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001702#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001703}
1704
Mathias Agopian4fec8732012-06-29 14:12:52 -07001705Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001706{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001707 ATRACE_CALL();
1708
Jesse Hall399184a2014-03-03 15:42:54 -08001709 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1710 // mSidebandStreamChanged was true
1711 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001712 if (mSidebandStream != NULL) {
1713 setTransactionFlags(eTransactionNeeded);
1714 mFlinger->setTransactionFlags(eTraversalNeeded);
1715 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001716 recomputeVisibleRegions = true;
1717
1718 const State& s(getDrawingState());
Robert Carr3dcabfa2016-03-01 18:36:58 -08001719 return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001720 }
1721
Mathias Agopian4fec8732012-06-29 14:12:52 -07001722 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001723 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001724
1725 // if we've already called updateTexImage() without going through
1726 // a composition step, we have to skip this layer at this point
1727 // because we cannot call updateTeximage() without a corresponding
1728 // compositionComplete() call.
1729 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001730 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001731 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001732 }
1733
Jamie Gennis351a5132011-09-14 18:23:37 -07001734 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001735 const State& s(getDrawingState());
1736 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001737 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001738
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001739 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001740 Layer::State& front;
1741 Layer::State& current;
1742 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001743 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001744 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001745 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001746 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001747 recomputeVisibleRegions(recomputeVisibleRegions),
1748 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001749 }
1750
1751 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001752 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001753 if (buf == NULL) {
1754 return false;
1755 }
1756
1757 uint32_t bufWidth = buf->getWidth();
1758 uint32_t bufHeight = buf->getHeight();
1759
1760 // check that we received a buffer of the right size
1761 // (Take the buffer's orientation into account)
1762 if (item.mTransform & Transform::ROT_90) {
1763 swap(bufWidth, bufHeight);
1764 }
1765
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001766 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1767 if (front.active != front.requested) {
1768
1769 if (isFixedSize ||
1770 (bufWidth == front.requested.w &&
1771 bufHeight == front.requested.h))
1772 {
1773 // Here we pretend the transaction happened by updating the
1774 // current and drawing states. Drawing state is only accessed
1775 // in this thread, no need to have it locked
1776 front.active = front.requested;
1777
1778 // We also need to update the current state so that
1779 // we don't end-up overwriting the drawing state with
1780 // this stale current state during the next transaction
1781 //
1782 // NOTE: We don't need to hold the transaction lock here
1783 // because State::active is only accessed from this thread.
1784 current.active = front.active;
1785
1786 // recompute visible region
1787 recomputeVisibleRegions = true;
1788 }
1789
1790 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001791 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001792 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1793 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001794 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001795 front.active.w, front.active.h,
1796 front.active.crop.left,
1797 front.active.crop.top,
1798 front.active.crop.right,
1799 front.active.crop.bottom,
1800 front.active.crop.getWidth(),
1801 front.active.crop.getHeight(),
1802 front.requested.w, front.requested.h,
1803 front.requested.crop.left,
1804 front.requested.crop.top,
1805 front.requested.crop.right,
1806 front.requested.crop.bottom,
1807 front.requested.crop.getWidth(),
1808 front.requested.crop.getHeight());
1809 }
1810
Ruben Brunk1681d952014-06-27 15:51:55 -07001811 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001812 if (front.active.w != bufWidth ||
1813 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001814 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001815 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1816 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001817 return true;
1818 }
1819 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001820
1821 // if the transparent region has changed (this test is
1822 // conservative, but that's fine, worst case we're doing
1823 // a bit of extra work), we latch the new one and we
1824 // trigger a visible-region recompute.
1825 if (!front.activeTransparentRegion.isTriviallyEqual(
1826 front.requestedTransparentRegion)) {
1827 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001828
1829 // We also need to update the current state so that
1830 // we don't end-up overwriting the drawing state with
1831 // this stale current state during the next transaction
1832 //
1833 // NOTE: We don't need to hold the transaction lock here
1834 // because State::active is only accessed from this thread.
1835 current.activeTransparentRegion = front.activeTransparentRegion;
1836
1837 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001838 recomputeVisibleRegions = true;
1839 }
1840
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001841 return false;
1842 }
1843 };
1844
Ruben Brunk1681d952014-06-27 15:51:55 -07001845 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1846 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001847
Dan Stozacac35382016-01-27 12:21:06 -08001848
1849 // Check all of our local sync points to ensure that all transactions
1850 // which need to have been applied prior to the frame which is about to
1851 // be latched have signaled
1852
1853 auto headFrameNumber = getHeadFrameNumber();
1854 bool matchingFramesFound = false;
1855 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001856 {
Dan Stozacac35382016-01-27 12:21:06 -08001857 Mutex::Autolock lock(mLocalSyncPointMutex);
1858 for (auto& point : mLocalSyncPoints) {
1859 if (point->getFrameNumber() > headFrameNumber) {
1860 break;
1861 }
1862
1863 matchingFramesFound = true;
1864
1865 if (!point->frameIsAvailable()) {
1866 // We haven't notified the remote layer that the frame for
1867 // this point is available yet. Notify it now, and then
1868 // abort this attempt to latch.
1869 point->setFrameAvailable();
1870 allTransactionsApplied = false;
1871 break;
1872 }
1873
1874 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001875 }
1876 }
1877
Dan Stozacac35382016-01-27 12:21:06 -08001878 if (matchingFramesFound && !allTransactionsApplied) {
1879 mFlinger->signalLayerUpdate();
1880 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001881 }
1882
Pablo Ceballos06312182015-10-07 16:32:12 -07001883 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1884 // of the buffer queue isn't modified when the buffer queue is returning
Pablo Ceballos2dcb3632016-03-17 15:50:23 -07001885 // BufferItem's that weren't actually queued. This can happen in shared
Pablo Ceballos06312182015-10-07 16:32:12 -07001886 // buffer mode.
1887 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001888 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001889 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001890 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001891 if (updateResult == BufferQueue::PRESENT_LATER) {
1892 // Producer doesn't want buffer to be displayed yet. Signal a
1893 // layer update so we check again at the next opportunity.
1894 mFlinger->signalLayerUpdate();
1895 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001896 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1897 // If the buffer has been rejected, remove it from the shadow queue
1898 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001899 if (queuedBuffer) {
1900 Mutex::Autolock lock(mQueueItemLock);
1901 mQueueItems.removeAt(0);
1902 android_atomic_dec(&mQueuedFrames);
1903 }
Dan Stozaecc50402015-04-28 14:42:06 -07001904 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001905 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1906 // This can occur if something goes wrong when trying to create the
1907 // EGLImage for this buffer. If this happens, the buffer has already
1908 // been released, so we need to clean up the queue and bug out
1909 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001910 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001911 Mutex::Autolock lock(mQueueItemLock);
1912 mQueueItems.clear();
1913 android_atomic_and(0, &mQueuedFrames);
1914 }
1915
1916 // Once we have hit this state, the shadow queue may no longer
1917 // correctly reflect the incoming BufferQueue's contents, so even if
1918 // updateTexImage starts working, the only safe course of action is
1919 // to continue to ignore updates.
1920 mUpdateTexImageFailed = true;
1921
1922 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001923 }
1924
Pablo Ceballos06312182015-10-07 16:32:12 -07001925 if (queuedBuffer) {
1926 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001927 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1928
Dan Stoza6b9454d2014-11-07 16:00:59 -08001929 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001930
1931 // Remove any stale buffers that have been dropped during
1932 // updateTexImage
1933 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1934 mQueueItems.removeAt(0);
1935 android_atomic_dec(&mQueuedFrames);
1936 }
1937
Dan Stoza6b9454d2014-11-07 16:00:59 -08001938 mQueueItems.removeAt(0);
1939 }
1940
Dan Stozaecc50402015-04-28 14:42:06 -07001941
Andy McFadden1585c4d2013-06-28 13:52:40 -07001942 // Decrement the queued-frames count. Signal another event if we
1943 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001944 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001945 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001946 mFlinger->signalLayerUpdate();
1947 }
1948
1949 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001950 // something happened!
1951 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001952 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001953 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001954
Jamie Gennis351a5132011-09-14 18:23:37 -07001955 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001956 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001957 if (mActiveBuffer == NULL) {
1958 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001959 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001960 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001961
Mathias Agopian4824d402012-06-04 18:16:30 -07001962 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001963 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001964 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001965 // the first time we receive a buffer, we need to trigger a
1966 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001967 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001968 }
1969
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001970 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1971 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1972 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001973 if ((crop != mCurrentCrop) ||
1974 (transform != mCurrentTransform) ||
1975 (scalingMode != mCurrentScalingMode))
1976 {
1977 mCurrentCrop = crop;
1978 mCurrentTransform = transform;
1979 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001980 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001981 }
1982
1983 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001984 uint32_t bufWidth = mActiveBuffer->getWidth();
1985 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001986 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1987 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001988 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001989 }
1990 }
1991
1992 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001993 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001994 recomputeVisibleRegions = true;
1995 }
1996
Dan Stozacac35382016-01-27 12:21:06 -08001997 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1998
1999 // Remove any sync points corresponding to the buffer which was just
2000 // latched
2001 {
2002 Mutex::Autolock lock(mLocalSyncPointMutex);
2003 auto point = mLocalSyncPoints.begin();
2004 while (point != mLocalSyncPoints.end()) {
2005 if (!(*point)->frameIsAvailable() ||
2006 !(*point)->transactionIsApplied()) {
2007 // This sync point must have been added since we started
2008 // latching. Don't drop it yet.
2009 ++point;
2010 continue;
2011 }
2012
2013 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2014 point = mLocalSyncPoints.erase(point);
2015 } else {
2016 ++point;
2017 }
2018 }
2019 }
2020
Mathias Agopian4fec8732012-06-29 14:12:52 -07002021 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07002022 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07002023
2024 // transform the dirty region to window-manager space
Robert Carr3dcabfa2016-03-01 18:36:58 -08002025 outDirtyRegion = (s.active.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07002026 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07002027 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002028}
2029
Mathias Agopiana67932f2011-04-20 14:20:59 -07002030uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07002031{
Mathias Agopiana67932f2011-04-20 14:20:59 -07002032 // TODO: should we do something special if mSecure is set?
2033 if (mProtectedByApp) {
2034 // need a hardware-protected path to external video sink
2035 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07002036 }
Riley Andrews03414a12014-07-01 14:22:59 -07002037 if (mPotentialCursor) {
2038 usage |= GraphicBuffer::USAGE_CURSOR;
2039 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07002040 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07002041 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07002042}
2043
Mathias Agopian84300952012-11-21 16:02:13 -08002044void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07002045 uint32_t orientation = 0;
2046 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08002047 // The transform hint is used to improve performance, but we can
2048 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07002049 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07002050 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07002051 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07002052 if (orientation & Transform::ROT_INVALID) {
2053 orientation = 0;
2054 }
2055 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08002056 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07002057}
2058
Mathias Agopian13127d82013-03-05 17:47:11 -08002059// ----------------------------------------------------------------------------
2060// debugging
2061// ----------------------------------------------------------------------------
2062
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002063void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08002064{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07002065 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08002066
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002067 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02002068 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002069 "+ %s %p (%s)\n",
2070 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002071 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002072
Mathias Agopian2ca79392013-04-02 18:30:32 -07002073 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08002074 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07002075 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08002076 sp<Client> client(mClientRef.promote());
2077
Mathias Agopian74d211a2013-04-22 16:55:35 +02002078 result.appendFormat( " "
Pablo Ceballosacbe6782016-03-04 17:54:21 +00002079 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2080 "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
Mathias Agopian13127d82013-03-05 17:47:11 -08002081 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08002082#ifdef USE_HWC2
2083 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
2084#else
Mathias Agopian13127d82013-03-05 17:47:11 -08002085 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08002086#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002087 " client=%p\n",
Robert Carr3dcabfa2016-03-01 18:36:58 -08002088 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 -08002089 s.active.crop.left, s.active.crop.top,
2090 s.active.crop.right, s.active.crop.bottom,
Pablo Ceballosacbe6782016-03-04 17:54:21 +00002091 s.active.finalCrop.left, s.active.finalCrop.top,
2092 s.active.finalCrop.right, s.active.finalCrop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002093 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002094 s.alpha, s.flags,
Robert Carr3dcabfa2016-03-01 18:36:58 -08002095 s.active.transform[0][0], s.active.transform[0][1],
2096 s.active.transform[1][0], s.active.transform[1][1],
Mathias Agopian13127d82013-03-05 17:47:11 -08002097 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002098
2099 sp<const GraphicBuffer> buf0(mActiveBuffer);
2100 uint32_t w0=0, h0=0, s0=0, f0=0;
2101 if (buf0 != 0) {
2102 w0 = buf0->getWidth();
2103 h0 = buf0->getHeight();
2104 s0 = buf0->getStride();
2105 f0 = buf0->format;
2106 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002107 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002108 " "
2109 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2110 " queued-frames=%d, mRefreshPending=%d\n",
2111 mFormat, w0, h0, s0,f0,
2112 mQueuedFrames, mRefreshPending);
2113
Mathias Agopian13127d82013-03-05 17:47:11 -08002114 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002115 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002116 }
2117}
2118
Svetoslavd85084b2014-03-20 10:28:31 -07002119void Layer::dumpFrameStats(String8& result) const {
2120 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002121}
2122
Svetoslavd85084b2014-03-20 10:28:31 -07002123void Layer::clearFrameStats() {
2124 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002125}
2126
Jamie Gennis6547ff42013-07-16 20:12:42 -07002127void Layer::logFrameStats() {
2128 mFrameTracker.logAndResetStats(mName);
2129}
2130
Svetoslavd85084b2014-03-20 10:28:31 -07002131void Layer::getFrameStats(FrameStats* outStats) const {
2132 mFrameTracker.getStats(outStats);
2133}
2134
Pablo Ceballos40845df2016-01-25 17:41:15 -08002135void Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
2136 bool* outIsGlesComposition, nsecs_t* outPostedTime,
2137 sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
2138 *outName = mName;
2139 *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2140
2141#ifdef USE_HWC2
2142 *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
2143 mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
2144 HWC2::Composition::Client : true;
2145#else
2146 *outIsGlesComposition = mIsGlesComposition;
2147#endif
2148 *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
2149 *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
2150 *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
2151}
Mathias Agopian13127d82013-03-05 17:47:11 -08002152// ---------------------------------------------------------------------------
2153
2154Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2155 const sp<Layer>& layer)
2156 : mFlinger(flinger), mLayer(layer) {
2157}
2158
2159Layer::LayerCleaner::~LayerCleaner() {
2160 // destroy client resources
2161 mFlinger->onLayerDestroyed(mLayer);
2162}
2163
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002164// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002165}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002166
2167#if defined(__gl_h_)
2168#error "don't include gl/gl.h in this file"
2169#endif
2170
2171#if defined(__gl2_h_)
2172#error "don't include gl2/gl2.h in this file"
2173#endif