blob: a318a8f46aed9204c6d76b3ff0af96c962bc13ce [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
Mathias Agopian13127d82013-03-05 17:47:11 -080022#include <math.h>
David Sodman41fdfc92017-11-06 16:09:56 -080023#include <stdint.h>
24#include <stdlib.h>
25#include <sys/types.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
Courtney Goeltzenleuchter36c44dc2017-04-14 09:33:16 -060037#include <ui/DebugUtils.h>
Mathias Agopian3330b202009-10-05 17:07:12 -070038#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080040
Dan Stoza6b9454d2014-11-07 16:00:59 -080041#include <gui/BufferItem.h>
Mathias Agopiana9347642017-02-13 16:42:28 -080042#include <gui/BufferQueue.h>
Kalle Raitaa099a242017-01-11 11:17:29 -080043#include <gui/LayerDebugInfo.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080044#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045
Mathias Agopian3e25fd82013-04-22 17:52:16 +020046#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070047#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#include "Layer.h"
Fabien Sanglard7b1563a2016-10-13 12:05:28 -070049#include "LayerRejecter.h"
Dan Stozab9b08832014-03-13 11:55:57 -070050#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051#include "SurfaceFlinger.h"
David Sodman41fdfc92017-11-06 16:09:56 -080052#include "clz.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053
Mathias Agopian1b031492012-06-20 17:51:20 -070054#include "DisplayHardware/HWComposer.h"
55
Mathias Agopian875d8e12013-06-07 15:35:48 -070056#include "RenderEngine/RenderEngine.h"
57
Dan Stozac5da2712016-07-20 15:38:12 -070058#include <mutex>
chaviw1d044282017-09-27 12:19:28 -070059#include "LayerProtoHelper.h"
Dan Stozac5da2712016-07-20 15:38:12 -070060
David Sodman41fdfc92017-11-06 16:09:56 -080061#define DEBUG_RESIZE 0
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080062
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080063namespace android {
64
Mathias Agopian13127d82013-03-05 17:47:11 -080065int32_t Layer::sSequence = 1;
66
David Sodman41fdfc92017-11-06 16:09:56 -080067Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
68 uint32_t h, uint32_t flags)
David Sodman0c69cad2017-08-21 12:12:51 -070069 : contentDirty(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080070 sequence(uint32_t(android_atomic_inc(&sSequence))),
71 mFlinger(flinger),
David Sodman0c69cad2017-08-21 12:12:51 -070072 mSurfaceFlingerConsumer(NULL),
Mathias Agopian13127d82013-03-05 17:47:11 -080073 mPremultipliedAlpha(true),
David Sodman0c69cad2017-08-21 12:12:51 -070074 mName(name),
Mathias Agopian13127d82013-03-05 17:47:11 -080075 mTransactionFlags(0),
Dan Stoza7dde5992015-05-22 09:51:44 -070076 mPendingStateMutex(),
77 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070078 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080079 mSidebandStreamChanged(false),
Mathias Agopiana9347642017-02-13 16:42:28 -080080 mActiveBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
Mathias Agopiana67932f2011-04-20 14:20:59 -070081 mCurrentTransform(0),
Robert Carrc3574f72016-03-24 12:19:32 -070082 mOverrideScalingMode(-1),
Mathias Agopiana67932f2011-04-20 14:20:59 -070083 mCurrentOpacity(true),
Dan Stozacac35382016-01-27 12:21:06 -080084 mCurrentFrameNumber(0),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080085 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080086 mFiltering(false),
87 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070088 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Fabien Sanglard9d96de42016-10-11 00:15:18 +000089#ifndef USE_HWC2
90 mIsGlesComposition(false),
91#endif
Mathias Agopian13127d82013-03-05 17:47:11 -080092 mProtectedByApp(false),
Riley Andrews03414a12014-07-01 14:22:59 -070093 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070094 mPotentialCursor(false),
95 mQueueItemLock(),
96 mQueueItemCondition(),
97 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070098 mLastFrameNumberReceived(0),
Robert Carr82364e32016-05-15 11:27:47 -070099 mAutoRefresh(false),
David Sodman41fdfc92017-11-06 16:09:56 -0800100 mFreezeGeometryUpdates(false) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800101
Mathias Agopiana67932f2011-04-20 14:20:59 -0700102 mCurrentCrop.makeInvalid();
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700103
104 uint32_t layerFlags = 0;
David Sodman41fdfc92017-11-06 16:09:56 -0800105 if (flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
106 if (flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
107 if (flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700108
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700109 mName = name;
Dan Stozaf7ba41a2017-05-10 15:11:11 -0700110 mTransactionName = String8("TX - ") + mName;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700111
112 mCurrentState.active.w = w;
113 mCurrentState.active.h = h;
David Sodman0c69cad2017-08-21 12:12:51 -0700114 mCurrentState.flags = layerFlags;
Robert Carr3dcabfa2016-03-01 18:36:58 -0800115 mCurrentState.active.transform.set(0, 0);
Robert Carrb5d3d262016-03-25 15:08:13 -0700116 mCurrentState.crop.makeInvalid();
117 mCurrentState.finalCrop.makeInvalid();
Robert Carr7bf247e2017-05-18 14:02:49 -0700118 mCurrentState.requestedFinalCrop = mCurrentState.finalCrop;
119 mCurrentState.requestedCrop = mCurrentState.crop;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700120 mCurrentState.z = 0;
chaviw13fdc492017-06-27 12:40:18 -0700121 mCurrentState.color.a = 1.0f;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700122 mCurrentState.layerStack = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700123 mCurrentState.sequence = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700124 mCurrentState.requested = mCurrentState.active;
Courtney Goeltzenleuchterbb09b432016-11-30 13:51:28 -0700125 mCurrentState.dataSpace = HAL_DATASPACE_UNKNOWN;
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500126 mCurrentState.appId = 0;
127 mCurrentState.type = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700128
129 // drawing state & current state are identical
130 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700131
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000132#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800133 const auto& hwc = flinger->getHwComposer();
134 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
135 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000136#else
David Sodman41fdfc92017-11-06 16:09:56 -0800137 nsecs_t displayPeriod = flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000138#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700139 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800140
141 CompositorTiming compositorTiming;
142 flinger->getCompositorTiming(&compositorTiming);
143 mFrameEventHistory.initializeCompositorTiming(compositorTiming);
Jamie Gennise8696a42012-01-15 18:54:57 -0800144}
145
David Sodman41fdfc92017-11-06 16:09:56 -0800146void Layer::onFirstRef() {}
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700147
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700148Layer::~Layer() {
Jamie Gennis6547ff42013-07-16 20:12:42 -0700149 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700150}
151
Mathias Agopian13127d82013-03-05 17:47:11 -0800152// ---------------------------------------------------------------------------
153// callbacks
154// ---------------------------------------------------------------------------
155
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000156#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800157void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
158 if (mHwcLayers.empty()) {
159 return;
160 }
David Sodman0c69cad2017-08-21 12:12:51 -0700161 if (mSurfaceFlingerConsumer) {
162 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
163 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800164}
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000165#else
166void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
David Sodman41fdfc92017-11-06 16:09:56 -0800167 HWComposer::HWCLayerInterface* layer) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000168 if (layer) {
169 layer->onDisplayed();
170 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
171 }
172}
173#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800174
Chia-I Wuc6657022017-08-15 11:18:17 -0700175void Layer::onRemovedFromCurrentState() {
176 // the layer is removed from SF mCurrentState to mLayersPendingRemoval
177
Robert Carr5edb1ad2017-04-25 10:54:24 -0700178 if (mCurrentState.zOrderRelativeOf != nullptr) {
179 sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
180 if (strongRelative != nullptr) {
181 strongRelative->removeZOrderRelative(this);
Chia-I Wuc6657022017-08-15 11:18:17 -0700182 mFlinger->setTransactionFlags(eTraversalNeeded);
Robert Carr5edb1ad2017-04-25 10:54:24 -0700183 }
184 mCurrentState.zOrderRelativeOf = nullptr;
185 }
186
Chia-I Wuc6657022017-08-15 11:18:17 -0700187 for (const auto& child : mCurrentChildren) {
188 child->onRemovedFromCurrentState();
189 }
190}
Chia-I Wu38512252017-05-17 14:36:16 -0700191
Chia-I Wuc6657022017-08-15 11:18:17 -0700192void Layer::onRemoved() {
193 // the layer is removed from SF mLayersPendingRemoval
194
David Sodman0c69cad2017-08-21 12:12:51 -0700195 if (mSurfaceFlingerConsumer) {
196 mSurfaceFlingerConsumer->abandon();
197 }
Chia-I Wu38512252017-05-17 14:36:16 -0700198#ifdef USE_HWC2
Steven Thomasb02664d2017-07-26 18:48:28 -0700199 destroyAllHwcLayers();
Chia-I Wu38512252017-05-17 14:36:16 -0700200#endif
201
Robert Carr1f0a16a2016-10-24 16:27:39 -0700202 for (const auto& child : mCurrentChildren) {
203 child->onRemoved();
204 }
Mathias Agopian48d819a2009-09-10 19:41:18 -0700205}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700206
Mathias Agopian13127d82013-03-05 17:47:11 -0800207// ---------------------------------------------------------------------------
208// set-up
209// ---------------------------------------------------------------------------
210
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700211const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800212 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800213}
214
chaviw13fdc492017-06-27 12:40:18 -0700215bool Layer::getPremultipledAlpha() const {
216 return mPremultipliedAlpha;
217}
218
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700219sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800220 Mutex::Autolock _l(mLock);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700221 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800222}
223
224// ---------------------------------------------------------------------------
225// h/w composer set-up
226// ---------------------------------------------------------------------------
227
Steven Thomasb02664d2017-07-26 18:48:28 -0700228#ifdef USE_HWC2
229bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) {
David Sodman41fdfc92017-11-06 16:09:56 -0800230 LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Already have a layer for hwcId %d", hwcId);
Steven Thomasb02664d2017-07-26 18:48:28 -0700231 HWC2::Layer* layer = hwc->createLayer(hwcId);
232 if (!layer) {
233 return false;
234 }
235 HWCInfo& hwcInfo = mHwcLayers[hwcId];
236 hwcInfo.hwc = hwc;
237 hwcInfo.layer = layer;
238 layer->setLayerDestroyedListener(
David Sodman41fdfc92017-11-06 16:09:56 -0800239 [this, hwcId](HWC2::Layer* /*layer*/) { mHwcLayers.erase(hwcId); });
Steven Thomasb02664d2017-07-26 18:48:28 -0700240 return true;
241}
242
243void Layer::destroyHwcLayer(int32_t hwcId) {
244 if (mHwcLayers.count(hwcId) == 0) {
245 return;
246 }
247 auto& hwcInfo = mHwcLayers[hwcId];
David Sodman41fdfc92017-11-06 16:09:56 -0800248 LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer");
Steven Thomasb02664d2017-07-26 18:48:28 -0700249 LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer");
250 hwcInfo.hwc->destroyLayer(hwcId, hwcInfo.layer);
251 // The layer destroyed listener should have cleared the entry from
252 // mHwcLayers. Verify that.
David Sodman41fdfc92017-11-06 16:09:56 -0800253 LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Stale layer entry in mHwcLayers");
Steven Thomasb02664d2017-07-26 18:48:28 -0700254}
255
256void Layer::destroyAllHwcLayers() {
257 size_t numLayers = mHwcLayers.size();
258 for (size_t i = 0; i < numLayers; ++i) {
259 LOG_ALWAYS_FATAL_IF(mHwcLayers.empty(), "destroyAllHwcLayers failed");
260 destroyHwcLayer(mHwcLayers.begin()->first);
261 }
262 LOG_ALWAYS_FATAL_IF(!mHwcLayers.empty(),
David Sodman41fdfc92017-11-06 16:09:56 -0800263 "All hardware composer layers should have been destroyed");
Steven Thomasb02664d2017-07-26 18:48:28 -0700264}
265#endif
266
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800267Rect Layer::getContentCrop() const {
268 // this is the crop rectangle that applies to the buffer
269 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700270 Rect crop;
271 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800272 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700273 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800274 } else if (mActiveBuffer != NULL) {
275 // otherwise we use the whole buffer
276 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700277 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800278 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700279 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700280 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700281 return crop;
282}
283
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700284static Rect reduce(const Rect& win, const Region& exclude) {
285 if (CC_LIKELY(exclude.isEmpty())) {
286 return win;
287 }
288 if (exclude.isRect()) {
289 return win.reduce(exclude.getBounds());
290 }
291 return Region(win).subtract(exclude).getBounds();
292}
293
Robert Carr1f0a16a2016-10-24 16:27:39 -0700294Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
295 const Layer::State& s(getDrawingState());
296 Rect win(s.active.w, s.active.h);
297
298 if (!s.crop.isEmpty()) {
299 win.intersect(s.crop, &win);
300 }
301
302 Transform t = getTransform();
303 win = t.transform(win);
304
Robert Carr41b08b52017-06-01 16:11:34 -0700305 if (!s.finalCrop.isEmpty()) {
306 win.intersect(s.finalCrop, &win);
307 }
308
Chia-I Wue41dbe62017-06-13 14:10:56 -0700309 const sp<Layer>& p = mDrawingParent.promote();
Robert Carr1f0a16a2016-10-24 16:27:39 -0700310 // Now we need to calculate the parent bounds, so we can clip ourselves to those.
311 // When calculating the parent bounds for purposes of clipping,
312 // we don't need to constrain the parent to its transparent region.
313 // The transparent region is an optimization based on the
314 // buffer contents of the layer, but does not affect the space allocated to
315 // it by policy, and thus children should be allowed to extend into the
316 // parent's transparent region. In fact one of the main uses, is to reduce
317 // buffer allocation size in cases where a child window sits behind a main window
318 // (by marking the hole in the parent window as a transparent region)
319 if (p != nullptr) {
320 Rect bounds = p->computeScreenBounds(false);
321 bounds.intersect(win, &win);
322 }
323
324 if (reduceTransparentRegion) {
325 auto const screenTransparentRegion = t.transform(s.activeTransparentRegion);
326 win = reduce(win, screenTransparentRegion);
327 }
328
329 return win;
330}
331
Mathias Agopian13127d82013-03-05 17:47:11 -0800332Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700333 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700334 return computeBounds(s.activeTransparentRegion);
335}
336
337Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
338 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800339 Rect win(s.active.w, s.active.h);
Robert Carrb5d3d262016-03-25 15:08:13 -0700340
341 if (!s.crop.isEmpty()) {
342 win.intersect(s.crop, &win);
Mathias Agopian13127d82013-03-05 17:47:11 -0800343 }
Robert Carr1f0a16a2016-10-24 16:27:39 -0700344
345 Rect bounds = win;
Chia-I Wue41dbe62017-06-13 14:10:56 -0700346 const auto& p = mDrawingParent.promote();
Robert Carr1f0a16a2016-10-24 16:27:39 -0700347 if (p != nullptr) {
Robert Carrde9ec442017-02-08 17:43:36 -0800348 // Look in computeScreenBounds recursive call for explanation of
349 // why we pass false here.
350 bounds = p->computeScreenBounds(false /* reduceTransparentRegion */);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700351 }
352
353 Transform t = getTransform();
354 if (p != nullptr) {
355 win = t.transform(win);
356 win.intersect(bounds, &win);
357 win = t.inverse().transform(win);
358 }
359
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700360 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700361 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800362}
363
Robert Carr1f0a16a2016-10-24 16:27:39 -0700364Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& hw) const {
Robert Carrb5d3d262016-03-25 15:08:13 -0700365 // the crop is the area of the window that gets cropped, but not
Mathias Agopian13127d82013-03-05 17:47:11 -0800366 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700367 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800368
369 // apply the projection's clipping to the window crop in
370 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700371 // if there are no window scaling involved, this operation will map to full
372 // pixels in the buffer.
373 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
374 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700375
376 Rect activeCrop(s.active.w, s.active.h);
Robert Carrb5d3d262016-03-25 15:08:13 -0700377 if (!s.crop.isEmpty()) {
Chia-I Wudf7867f2017-07-20 14:24:37 -0700378 activeCrop.intersect(s.crop, &activeCrop);
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700379 }
380
Robert Carr1f0a16a2016-10-24 16:27:39 -0700381 Transform t = getTransform();
382 activeCrop = t.transform(activeCrop);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000383 if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
384 activeCrop.clear();
385 }
Robert Carrb5d3d262016-03-25 15:08:13 -0700386 if (!s.finalCrop.isEmpty()) {
David Sodman41fdfc92017-11-06 16:09:56 -0800387 if (!activeCrop.intersect(s.finalCrop, &activeCrop)) {
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000388 activeCrop.clear();
389 }
390 }
chaviwb1154d12017-10-31 14:15:36 -0700391
392 const auto& p = mDrawingParent.promote();
393 if (p != nullptr) {
394 auto parentCrop = p->computeInitialCrop(hw);
395 activeCrop.intersect(parentCrop, &activeCrop);
396 }
397
Robert Carr1f0a16a2016-10-24 16:27:39 -0700398 return activeCrop;
399}
400
Dan Stoza5a423ea2017-02-16 14:10:39 -0800401FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Robert Carr1f0a16a2016-10-24 16:27:39 -0700402 // the content crop is the area of the content that gets scaled to the
403 // layer's size. This is in buffer space.
Dan Stoza5a423ea2017-02-16 14:10:39 -0800404 FloatRect crop = getContentCrop().toFloatRect();
Robert Carr1f0a16a2016-10-24 16:27:39 -0700405
406 // In addition there is a WM-specified crop we pull from our drawing state.
407 const State& s(getDrawingState());
408
409 // Screen space to make reduction to parent crop clearer.
410 Rect activeCrop = computeInitialCrop(hw);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700411 Transform t = getTransform();
412 // Back to layer space to work with the content crop.
413 activeCrop = t.inverse().transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800414
Michael Lentine28ea2172014-11-19 18:32:37 -0800415 // This needs to be here as transform.transform(Rect) computes the
416 // transformed rect and then takes the bounding box of the result before
417 // returning. This means
418 // transform.inverse().transform(transform.transform(Rect)) != Rect
419 // in which case we need to make sure the final rect is clipped to the
420 // display bounds.
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000421 if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
422 activeCrop.clear();
423 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800424
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700425 // subtract the transparent region and snap to the bounds
426 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
427
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000428 // Transform the window crop to match the buffer coordinate system,
429 // which means using the inverse of the current transform set on the
430 // SurfaceFlingerConsumer.
431 uint32_t invTransform = mCurrentTransform;
Robert Carrcae605c2017-03-29 12:10:31 -0700432 if (getTransformToDisplayInverse()) {
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000433 /*
Pablo Ceballos021623b2016-04-15 17:31:51 -0700434 * the code below applies the primary display's inverse transform to the
435 * buffer
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000436 */
David Sodman41fdfc92017-11-06 16:09:56 -0800437 uint32_t invTransformOrient = DisplayDevice::getPrimaryDisplayOrientationTransform();
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000438 // calculate the inverse transform
439 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
David Sodman41fdfc92017-11-06 16:09:56 -0800440 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
Mathias Agopian13127d82013-03-05 17:47:11 -0800441 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000442 // and apply to the current transform
David Sodman41fdfc92017-11-06 16:09:56 -0800443 invTransform = (Transform(invTransformOrient) * Transform(invTransform)).getOrientation();
Mathias Agopian13127d82013-03-05 17:47:11 -0800444 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000445
446 int winWidth = s.active.w;
447 int winHeight = s.active.h;
448 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
449 // If the activeCrop has been rotate the ends are rotated but not
450 // the space itself so when transforming ends back we can't rely on
451 // a modification of the axes of rotation. To account for this we
452 // need to reorient the inverse rotation in terms of the current
453 // axes of rotation.
454 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
455 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
456 if (is_h_flipped == is_v_flipped) {
David Sodman41fdfc92017-11-06 16:09:56 -0800457 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000458 }
459 winWidth = s.active.h;
460 winHeight = s.active.w;
461 }
David Sodman41fdfc92017-11-06 16:09:56 -0800462 const Rect winCrop = activeCrop.transform(invTransform, s.active.w, s.active.h);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000463
464 // below, crop is intersected with winCrop expressed in crop's coordinate space
David Sodman41fdfc92017-11-06 16:09:56 -0800465 float xScale = crop.getWidth() / float(winWidth);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000466 float yScale = crop.getHeight() / float(winHeight);
467
David Sodman41fdfc92017-11-06 16:09:56 -0800468 float insetL = winCrop.left * xScale;
469 float insetT = winCrop.top * yScale;
470 float insetR = (winWidth - winCrop.right) * xScale;
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000471 float insetB = (winHeight - winCrop.bottom) * yScale;
472
David Sodman41fdfc92017-11-06 16:09:56 -0800473 crop.left += insetL;
474 crop.top += insetT;
475 crop.right -= insetR;
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000476 crop.bottom -= insetB;
477
Mathias Agopian13127d82013-03-05 17:47:11 -0800478 return crop;
479}
480
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000481#ifdef USE_HWC2
Robert Carrae060832016-11-28 10:51:00 -0800482void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z)
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000483#else
David Sodman41fdfc92017-11-06 16:09:56 -0800484void Layer::setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer)
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000485#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700486{
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000487#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800488 const auto hwcId = displayDevice->getHwcDisplayId();
489 auto& hwcInfo = mHwcLayers[hwcId];
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000490#else
491 layer.setDefaultState();
492#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700493
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700494 // enable this layer
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000495#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800496 hwcInfo.forceClientComposition = false;
497
498 if (isSecure() && !displayDevice->isSecure()) {
499 hwcInfo.forceClientComposition = true;
500 }
501
502 auto& hwcLayer = hwcInfo.layer;
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000503#else
504 layer.setSkip(false);
505
506 if (isSecure() && !hw->isSecure()) {
507 layer.setSkip(true);
508 }
509#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700510
Mathias Agopian13127d82013-03-05 17:47:11 -0800511 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700512 const State& s(getDrawingState());
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000513#ifdef USE_HWC2
David Revemanecf0fa52017-03-03 11:32:44 -0500514 auto blendMode = HWC2::BlendMode::None;
Robert Carr6452f122017-03-21 10:41:29 -0700515 if (!isOpaque(s) || getAlpha() != 1.0f) {
David Sodman41fdfc92017-11-06 16:09:56 -0800516 blendMode =
517 mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800518 }
David Revemanecf0fa52017-03-03 11:32:44 -0500519 auto error = hwcLayer->setBlendMode(blendMode);
David Sodman41fdfc92017-11-06 16:09:56 -0800520 ALOGE_IF(error != HWC2::Error::None,
521 "[%s] Failed to set blend mode %s:"
522 " %s (%d)",
523 mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(),
524 static_cast<int32_t>(error));
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000525#else
chaviw13fdc492017-06-27 12:40:18 -0700526 if (!isOpaque(s) || getAlpha() != 1.0f) {
David Sodman41fdfc92017-11-06 16:09:56 -0800527 layer.setBlending(mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE);
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000528 }
529#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800530
531 // apply the layer's transform, followed by the display's global transform
532 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700533 Region activeTransparentRegion(s.activeTransparentRegion);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700534 Transform t = getTransform();
Robert Carrb5d3d262016-03-25 15:08:13 -0700535 if (!s.crop.isEmpty()) {
536 Rect activeCrop(s.crop);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700537 activeCrop = t.transform(activeCrop);
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000538#ifdef USE_HWC2
David Sodman41fdfc92017-11-06 16:09:56 -0800539 if (!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000540#else
David Sodman41fdfc92017-11-06 16:09:56 -0800541 if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000542#endif
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000543 activeCrop.clear();
544 }
Robert Carr1f0a16a2016-10-24 16:27:39 -0700545 activeCrop = t.inverse().transform(activeCrop, true);
Michael Lentine28ea2172014-11-19 18:32:37 -0800546 // This needs to be here as transform.transform(Rect) computes the
547 // transformed rect and then takes the bounding box of the result before
548 // returning. This means
549 // transform.inverse().transform(transform.transform(Rect)) != Rect
550 // in which case we need to make sure the final rect is clipped to the
551 // display bounds.
David Sodman41fdfc92017-11-06 16:09:56 -0800552 if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000553 activeCrop.clear();
554 }
Michael Lentine6c925ed2014-09-26 17:55:01 -0700555 // mark regions outside the crop as transparent
556 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
David Sodman41fdfc92017-11-06 16:09:56 -0800557 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom, s.active.w, s.active.h));
558 activeTransparentRegion.orSelf(Rect(0, activeCrop.top, activeCrop.left, activeCrop.bottom));
559 activeTransparentRegion.orSelf(
560 Rect(activeCrop.right, activeCrop.top, s.active.w, activeCrop.bottom));
Michael Lentine6c925ed2014-09-26 17:55:01 -0700561 }
Robert Carr1f0a16a2016-10-24 16:27:39 -0700562
563 Rect frame(t.transform(computeBounds(activeTransparentRegion)));
Robert Carrb5d3d262016-03-25 15:08:13 -0700564 if (!s.finalCrop.isEmpty()) {
David Sodman41fdfc92017-11-06 16:09:56 -0800565 if (!frame.intersect(s.finalCrop, &frame)) {
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000566 frame.clear();
567 }
568 }
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000569#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000570 if (!frame.intersect(displayDevice->getViewport(), &frame)) {
571 frame.clear();
572 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800573 const Transform& tr(displayDevice->getTransform());
574 Rect transformedFrame = tr.transform(frame);
David Revemanecf0fa52017-03-03 11:32:44 -0500575 error = hwcLayer->setDisplayFrame(transformedFrame);
Dan Stozae22aec72016-08-01 13:20:59 -0700576 if (error != HWC2::Error::None) {
David Sodman41fdfc92017-11-06 16:09:56 -0800577 ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(),
578 transformedFrame.left, transformedFrame.top, transformedFrame.right,
579 transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stozae22aec72016-08-01 13:20:59 -0700580 } else {
581 hwcInfo.displayFrame = transformedFrame;
582 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800583
Dan Stoza5a423ea2017-02-16 14:10:39 -0800584 FloatRect sourceCrop = computeCrop(displayDevice);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800585 error = hwcLayer->setSourceCrop(sourceCrop);
Dan Stozae22aec72016-08-01 13:20:59 -0700586 if (error != HWC2::Error::None) {
587 ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
David Sodman41fdfc92017-11-06 16:09:56 -0800588 "%s (%d)",
589 mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom,
590 to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stozae22aec72016-08-01 13:20:59 -0700591 } else {
592 hwcInfo.sourceCrop = sourceCrop;
593 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800594
chaviw13fdc492017-06-27 12:40:18 -0700595 float alpha = static_cast<float>(getAlpha());
Robert Carr6452f122017-03-21 10:41:29 -0700596 error = hwcLayer->setPlaneAlpha(alpha);
David Sodman41fdfc92017-11-06 16:09:56 -0800597 ALOGE_IF(error != HWC2::Error::None,
598 "[%s] Failed to set plane alpha %.3f: "
599 "%s (%d)",
600 mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800601
Robert Carrae060832016-11-28 10:51:00 -0800602 error = hwcLayer->setZOrder(z);
David Sodman41fdfc92017-11-06 16:09:56 -0800603 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
604 to_string(error).c_str(), static_cast<int32_t>(error));
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500605
Albert Chaulk2a589632017-05-04 16:59:44 -0400606 int type = s.type;
607 int appId = s.appId;
Chia-I Wue41dbe62017-06-13 14:10:56 -0700608 sp<Layer> parent = mDrawingParent.promote();
Albert Chaulk2a589632017-05-04 16:59:44 -0400609 if (parent.get()) {
610 auto& parentState = parent->getDrawingState();
611 type = parentState.type;
612 appId = parentState.appId;
613 }
614
615 error = hwcLayer->setInfo(type, appId);
David Sodman41fdfc92017-11-06 16:09:56 -0800616 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
617 static_cast<int32_t>(error));
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000618#else
619 if (!frame.intersect(hw->getViewport(), &frame)) {
620 frame.clear();
621 }
622 const Transform& tr(hw->getTransform());
623 layer.setFrame(tr.transform(frame));
624 layer.setCrop(computeCrop(hw));
David Sodman41fdfc92017-11-06 16:09:56 -0800625 layer.setPlaneAlpha(static_cast<uint8_t>(std::round(255.0f * getAlpha())));
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000626#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800627
Mathias Agopian29a367b2011-07-12 14:51:45 -0700628 /*
629 * Transformations are applied in this order:
630 * 1) buffer orientation/flip/mirror
631 * 2) state transformation (window manager)
632 * 3) layer orientation (screen orientation)
633 * (NOTE: the matrices are multiplied in reverse order)
634 */
635
636 const Transform bufferOrientation(mCurrentTransform);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700637 Transform transform(tr * t * bufferOrientation);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700638
Robert Carrcae605c2017-03-29 12:10:31 -0700639 if (getTransformToDisplayInverse()) {
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700640 /*
Pablo Ceballos021623b2016-04-15 17:31:51 -0700641 * the code below applies the primary display's inverse transform to the
642 * buffer
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700643 */
David Sodman41fdfc92017-11-06 16:09:56 -0800644 uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700645 // calculate the inverse transform
646 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
David Sodman41fdfc92017-11-06 16:09:56 -0800647 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700648 }
Robert Carrcae605c2017-03-29 12:10:31 -0700649
650 /*
651 * Here we cancel out the orientation component of the WM transform.
652 * The scaling and translate components are already included in our bounds
653 * computation so it's enough to just omit it in the composition.
654 * See comment in onDraw with ref to b/36727915 for why.
655 */
656 transform = Transform(invTransform) * tr * bufferOrientation;
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();
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000661#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800662 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);
David Sodman41fdfc92017-11-06 16:09:56 -0800668 ALOGE_IF(error != HWC2::Error::None,
669 "[%s] Failed to set transform %s: "
670 "%s (%d)",
671 mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
672 static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800673 }
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000674#else
675 if (orientation & Transform::ROT_INVALID) {
676 // we can only handle simple transformation
677 layer.setSkip(true);
678 } else {
679 layer.setTransform(orientation);
680 }
681#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700682}
683
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000684#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800685void Layer::forceClientComposition(int32_t hwcId) {
686 if (mHwcLayers.count(hwcId) == 0) {
687 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
688 return;
689 }
690
691 mHwcLayers[hwcId].forceClientComposition = true;
692}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800693
Dan Stoza9e56aa02015-11-02 13:00:03 -0800694void 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();
Chia-I Wuaaff73f2017-02-13 12:28:24 -0800701 auto& hwcInfo = mHwcLayers[hwcId];
702 auto& hwcLayer = hwcInfo.layer;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800703 auto error = hwcLayer->setVisibleRegion(visible);
704 if (error != HWC2::Error::None) {
705 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
David Sodman41fdfc92017-11-06 16:09:56 -0800706 to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800707 visible.dump(LOG_TAG);
708 }
709
710 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
711 if (error != HWC2::Error::None) {
712 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
David Sodman41fdfc92017-11-06 16:09:56 -0800713 to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800714 surfaceDamageRegion.dump(LOG_TAG);
715 }
716
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700717 // Sideband layers
Dan Stoza9e56aa02015-11-02 13:00:03 -0800718 if (mSidebandStream.get()) {
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700719 setCompositionType(hwcId, HWC2::Composition::Sideband);
720 ALOGV("[%s] Requesting Sideband composition", mName.string());
721 error = hwcLayer->setSidebandStream(mSidebandStream->handle());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800722 if (error != HWC2::Error::None) {
David Sodman41fdfc92017-11-06 16:09:56 -0800723 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
724 mSidebandStream->handle(), to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800725 }
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700726 return;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800727 }
728
Dan Stoza0a21df72016-07-20 12:52:38 -0700729 // Client layers
Chia-I Wuaaff73f2017-02-13 12:28:24 -0800730 if (hwcInfo.forceClientComposition ||
David Sodman41fdfc92017-11-06 16:09:56 -0800731 (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700732 ALOGV("[%s] Requesting Client composition", mName.string());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800733 setCompositionType(hwcId, HWC2::Composition::Client);
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700734 return;
735 }
736
Dan Stoza0a21df72016-07-20 12:52:38 -0700737 // SolidColor layers
738 if (mActiveBuffer == nullptr) {
739 setCompositionType(hwcId, HWC2::Composition::SolidColor);
Dan Stozac6c89542016-07-27 10:16:52 -0700740
chaviw13fdc492017-06-27 12:40:18 -0700741 half4 color = getColor();
David Sodman41fdfc92017-11-06 16:09:56 -0800742 error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
743 static_cast<uint8_t>(std::round(255.0f * color.g)),
744 static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
Dan Stoza0a21df72016-07-20 12:52:38 -0700745 if (error != HWC2::Error::None) {
David Sodman41fdfc92017-11-06 16:09:56 -0800746 ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
747 static_cast<int32_t>(error));
Dan Stoza0a21df72016-07-20 12:52:38 -0700748 }
Dan Stozac6c89542016-07-27 10:16:52 -0700749
750 // Clear out the transform, because it doesn't make sense absent a
751 // source buffer
752 error = hwcLayer->setTransform(HWC2::Transform::None);
753 if (error != HWC2::Error::None) {
754 ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
David Sodman41fdfc92017-11-06 16:09:56 -0800755 to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stozac6c89542016-07-27 10:16:52 -0700756 }
757
Dan Stoza0a21df72016-07-20 12:52:38 -0700758 return;
759 }
760
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700761 // Device or Cursor layers
762 if (mPotentialCursor) {
763 ALOGV("[%s] Requesting Cursor composition", mName.string());
764 setCompositionType(hwcId, HWC2::Composition::Cursor);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800765 } else {
766 ALOGV("[%s] Requesting Device composition", mName.string());
767 setCompositionType(hwcId, HWC2::Composition::Device);
768 }
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700769
Courtney Goeltzenleuchterbb09b432016-11-30 13:51:28 -0700770 ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace);
771 error = hwcLayer->setDataspace(mCurrentState.dataSpace);
772 if (error != HWC2::Error::None) {
David Sodman41fdfc92017-11-06 16:09:56 -0800773 ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace,
774 to_string(error).c_str(), static_cast<int32_t>(error));
Courtney Goeltzenleuchterbb09b432016-11-30 13:51:28 -0700775 }
776
Chia-I Wu06d63de2017-01-04 14:58:51 +0800777 uint32_t hwcSlot = 0;
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400778 sp<GraphicBuffer> hwcBuffer;
David Sodman41fdfc92017-11-06 16:09:56 -0800779 hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer);
Chia-I Wu06d63de2017-01-04 14:58:51 +0800780
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700781 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400782 error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700783 if (error != HWC2::Error::None) {
David Sodman41fdfc92017-11-06 16:09:56 -0800784 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle,
785 to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stoza0f67b3f2016-05-17 10:48:38 -0700786 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800787}
Courtney Goeltzenleuchter9551fd32016-10-20 17:18:15 -0600788
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000789#else
790void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
David Sodman41fdfc92017-11-06 16:09:56 -0800791 HWComposer::HWCLayerInterface& layer) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000792 // we have to set the visible region on every frame because
793 // we currently free it during onLayerDisplayed(), which is called
794 // after HWComposer::commit() -- every frame.
795 // Apply this display's projection's viewport to the visible region
796 // before giving it to the HWC HAL.
797 const Transform& tr = hw->getTransform();
798 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
799 layer.setVisibleRegionScreen(visible);
800 layer.setSurfaceDamage(surfaceDamageRegion);
801 mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
Dan Stozaee44edd2015-03-23 15:50:23 -0700802
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000803 if (mSidebandStream.get()) {
804 layer.setSidebandStream(mSidebandStream);
805 } else {
806 // NOTE: buffer can be NULL if the client never drew into this
807 // layer yet, or if we ran out of memory
808 layer.setBuffer(mActiveBuffer);
809 }
810}
811#endif
812
813#ifdef USE_HWC2
Dan Stoza9e56aa02015-11-02 13:00:03 -0800814void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
815 auto hwcId = displayDevice->getHwcDisplayId();
David Sodman41fdfc92017-11-06 16:09:56 -0800816 if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800817 return;
818 }
819
820 // This gives us only the "orientation" component of the transform
821 const State& s(getCurrentState());
822
823 // Apply the layer's transform, followed by the display's global transform
824 // Here we're guaranteed that the layer's transform preserves rects
825 Rect win(s.active.w, s.active.h);
Robert Carrb5d3d262016-03-25 15:08:13 -0700826 if (!s.crop.isEmpty()) {
827 win.intersect(s.crop, &win);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800828 }
829 // Subtract the transparent region and snap to the bounds
830 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700831 Rect frame(getTransform().transform(bounds));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800832 frame.intersect(displayDevice->getViewport(), &frame);
Robert Carrb5d3d262016-03-25 15:08:13 -0700833 if (!s.finalCrop.isEmpty()) {
834 frame.intersect(s.finalCrop, &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000835 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800836 auto& displayTransform(displayDevice->getTransform());
837 auto position = displayTransform.transform(frame);
838
David Sodman41fdfc92017-11-06 16:09:56 -0800839 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, position.top);
840 ALOGE_IF(error != HWC2::Error::None,
841 "[%s] Failed to set cursor position "
842 "to (%d, %d): %s (%d)",
843 mName.string(), position.left, position.top, to_string(error).c_str(),
844 static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800845}
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000846#else
847void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
David Sodman41fdfc92017-11-06 16:09:56 -0800848 HWComposer::HWCLayerInterface& layer) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000849 int fenceFd = -1;
850
851 // TODO: there is a possible optimization here: we only need to set the
852 // acquire fence the first time a new buffer is acquired on EACH display.
853
David Sodman41fdfc92017-11-06 16:09:56 -0800854 if (layer.getCompositionType() == HWC_OVERLAY ||
855 layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000856 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
857 if (fence->isValid()) {
858 fenceFd = fence->dup();
859 if (fenceFd == -1) {
860 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
861 }
862 }
863 }
864 layer.setAcquireFenceFd(fenceFd);
865}
866
David Sodman41fdfc92017-11-06 16:09:56 -0800867Rect Layer::getPosition(const sp<const DisplayDevice>& hw) {
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000868 // this gives us only the "orientation" component of the transform
869 const State& s(getCurrentState());
870
871 // apply the layer's transform, followed by the display's global transform
872 // here we're guaranteed that the layer's transform preserves rects
873 Rect win(s.active.w, s.active.h);
874 if (!s.crop.isEmpty()) {
875 win.intersect(s.crop, &win);
876 }
877 // subtract the transparent region and snap to the bounds
878 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr1f0a16a2016-10-24 16:27:39 -0700879 Rect frame(getTransform().transform(bounds));
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000880 frame.intersect(hw->getViewport(), &frame);
881 if (!s.finalCrop.isEmpty()) {
882 frame.intersect(s.finalCrop, &frame);
883 }
884 const Transform& tr(hw->getTransform());
885 return Rect(tr.transform(frame));
886}
887#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700888
Mathias Agopian13127d82013-03-05 17:47:11 -0800889// ---------------------------------------------------------------------------
890// drawing...
891// ---------------------------------------------------------------------------
892
chaviwa76b2712017-09-20 12:02:26 -0700893void Layer::draw(const RenderArea& renderArea, const Region& clip) const {
894 onDraw(renderArea, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800895}
896
chaviwa76b2712017-09-20 12:02:26 -0700897void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) const {
898 onDraw(renderArea, Region(renderArea.getBounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800899}
900
chaviwa76b2712017-09-20 12:02:26 -0700901void Layer::draw(const RenderArea& renderArea) const {
902 onDraw(renderArea, Region(renderArea.getBounds()), false);
Dan Stozac7014012014-02-14 15:03:43 -0800903}
904
David Sodman41fdfc92017-11-06 16:09:56 -0800905void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
906 float alpha) const {
Mathias Agopian19733a32013-08-28 18:13:56 -0700907 RenderEngine& engine(mFlinger->getRenderEngine());
chaviwa76b2712017-09-20 12:02:26 -0700908 computeGeometry(renderArea, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700909 engine.setupFillWithColor(red, green, blue, alpha);
910 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800911}
912
chaviwa76b2712017-09-20 12:02:26 -0700913void Layer::clearWithOpenGL(const RenderArea& renderArea) const {
David Sodman41fdfc92017-11-06 16:09:56 -0800914 clearWithOpenGL(renderArea, 0, 0, 0, 0);
Mathias Agopian13127d82013-03-05 17:47:11 -0800915}
916
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000917#ifdef USE_HWC2
David Sodman41fdfc92017-11-06 16:09:56 -0800918void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800919 if (mHwcLayers.count(hwcId) == 0) {
920 ALOGE("setCompositionType called without a valid HWC layer");
921 return;
922 }
923 auto& hwcInfo = mHwcLayers[hwcId];
924 auto& hwcLayer = hwcInfo.layer;
David Sodman41fdfc92017-11-06 16:09:56 -0800925 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), to_string(type).c_str(),
926 static_cast<int>(callIntoHwc));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800927 if (hwcInfo.compositionType != type) {
928 ALOGV(" actually setting");
929 hwcInfo.compositionType = type;
930 if (callIntoHwc) {
931 auto error = hwcLayer->setCompositionType(type);
David Sodman41fdfc92017-11-06 16:09:56 -0800932 ALOGE_IF(error != HWC2::Error::None,
933 "[%s] Failed to set "
934 "composition type %s: %s (%d)",
935 mName.string(), to_string(type).c_str(), to_string(error).c_str(),
936 static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800937 }
938 }
939}
940
941HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
Dan Stozaec0f7172016-07-21 11:09:40 -0700942 if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
943 // If we're querying the composition type for a display that does not
944 // have a HWC counterpart, then it will always be Client
945 return HWC2::Composition::Client;
946 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800947 if (mHwcLayers.count(hwcId) == 0) {
Dan Stozaec0f7172016-07-21 11:09:40 -0700948 ALOGE("getCompositionType called with an invalid HWC layer");
Dan Stoza9e56aa02015-11-02 13:00:03 -0800949 return HWC2::Composition::Invalid;
950 }
951 return mHwcLayers.at(hwcId).compositionType;
952}
953
954void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
955 if (mHwcLayers.count(hwcId) == 0) {
956 ALOGE("setClearClientTarget called without a valid HWC layer");
957 return;
958 }
959 mHwcLayers[hwcId].clearClientTarget = clear;
960}
961
962bool Layer::getClearClientTarget(int32_t hwcId) const {
963 if (mHwcLayers.count(hwcId) == 0) {
964 ALOGE("getClearClientTarget called without a valid HWC layer");
965 return false;
966 }
967 return mHwcLayers.at(hwcId).clearClientTarget;
968}
Fabien Sanglard9d96de42016-10-11 00:15:18 +0000969#endif
Dan Stoza9e56aa02015-11-02 13:00:03 -0800970
Dan Stozacac35382016-01-27 12:21:06 -0800971bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
972 if (point->getFrameNumber() <= mCurrentFrameNumber) {
973 // Don't bother with a SyncPoint, since we've already latched the
974 // relevant frame
975 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -0700976 }
977
Dan Stozacac35382016-01-27 12:21:06 -0800978 Mutex::Autolock lock(mLocalSyncPointMutex);
979 mLocalSyncPoints.push_back(point);
980 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -0700981}
982
Mathias Agopian13127d82013-03-05 17:47:11 -0800983void Layer::setFiltering(bool filtering) {
984 mFiltering = filtering;
985}
986
987bool Layer::getFiltering() const {
988 return mFiltering;
989}
990
Mathias Agopian13127d82013-03-05 17:47:11 -0800991// ----------------------------------------------------------------------------
992// local state
993// ----------------------------------------------------------------------------
994
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000995static void boundPoint(vec2* point, const Rect& crop) {
996 if (point->x < crop.left) {
997 point->x = crop.left;
998 }
999 if (point->x > crop.right) {
1000 point->x = crop.right;
1001 }
1002 if (point->y < crop.top) {
1003 point->y = crop.top;
1004 }
1005 if (point->y > crop.bottom) {
1006 point->y = crop.bottom;
1007 }
1008}
1009
chaviwa76b2712017-09-20 12:02:26 -07001010void Layer::computeGeometry(const RenderArea& renderArea, Mesh& mesh,
1011 bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001012 const Layer::State& s(getDrawingState());
chaviwa76b2712017-09-20 12:02:26 -07001013 const Transform renderAreaTransform(renderArea.getTransform());
1014 const uint32_t height = renderArea.getHeight();
Robert Carr1f0a16a2016-10-24 16:27:39 -07001015 Rect win = computeBounds();
Mathias Agopian3f844832013-08-07 21:24:32 -07001016
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001017 vec2 lt = vec2(win.left, win.top);
1018 vec2 lb = vec2(win.left, win.bottom);
1019 vec2 rb = vec2(win.right, win.bottom);
1020 vec2 rt = vec2(win.right, win.top);
1021
Robert Carr1f0a16a2016-10-24 16:27:39 -07001022 Transform layerTransform = getTransform();
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001023 if (!useIdentityTransform) {
Robert Carr1f0a16a2016-10-24 16:27:39 -07001024 lt = layerTransform.transform(lt);
1025 lb = layerTransform.transform(lb);
1026 rb = layerTransform.transform(rb);
1027 rt = layerTransform.transform(rt);
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001028 }
1029
Robert Carrb5d3d262016-03-25 15:08:13 -07001030 if (!s.finalCrop.isEmpty()) {
1031 boundPoint(&lt, s.finalCrop);
1032 boundPoint(&lb, s.finalCrop);
1033 boundPoint(&rb, s.finalCrop);
1034 boundPoint(&rt, s.finalCrop);
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001035 }
1036
Mathias Agopianff2ed702013-09-01 21:36:12 -07001037 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
chaviwa76b2712017-09-20 12:02:26 -07001038 position[0] = renderAreaTransform.transform(lt);
1039 position[1] = renderAreaTransform.transform(lb);
1040 position[2] = renderAreaTransform.transform(rb);
1041 position[3] = renderAreaTransform.transform(rt);
David Sodman41fdfc92017-11-06 16:09:56 -08001042 for (size_t i = 0; i < 4; i++) {
chaviwa76b2712017-09-20 12:02:26 -07001043 position[i].y = height - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001044 }
1045}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001046
David Sodman41fdfc92017-11-06 16:09:56 -08001047bool Layer::isSecure() const {
Dan Stoza23116082015-06-18 14:58:39 -07001048 const Layer::State& s(mDrawingState);
1049 return (s.flags & layer_state_t::eLayerSecure);
1050}
1051
Mathias Agopian13127d82013-03-05 17:47:11 -08001052void Layer::setVisibleRegion(const Region& visibleRegion) {
1053 // always called from main thread
1054 this->visibleRegion = visibleRegion;
1055}
1056
1057void Layer::setCoveredRegion(const Region& coveredRegion) {
1058 // always called from main thread
1059 this->coveredRegion = coveredRegion;
1060}
1061
David Sodman41fdfc92017-11-06 16:09:56 -08001062void Layer::setVisibleNonTransparentRegion(const Region& setVisibleNonTransparentRegion) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001063 // always called from main thread
1064 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1065}
1066
1067// ----------------------------------------------------------------------------
1068// transaction
1069// ----------------------------------------------------------------------------
1070
Dan Stoza7dde5992015-05-22 09:51:44 -07001071void Layer::pushPendingState() {
1072 if (!mCurrentState.modified) {
1073 return;
1074 }
1075
Dan Stoza7dde5992015-05-22 09:51:44 -07001076 // If this transaction is waiting on the receipt of a frame, generate a sync
1077 // point and send it to the remote layer.
Robert Carr0d480722017-01-10 16:42:54 -08001078 if (mCurrentState.barrierLayer != nullptr) {
1079 sp<Layer> barrierLayer = mCurrentState.barrierLayer.promote();
1080 if (barrierLayer == nullptr) {
1081 ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
Dan Stoza7dde5992015-05-22 09:51:44 -07001082 // If we can't promote the layer we are intended to wait on,
1083 // then it is expired or otherwise invalid. Allow this transaction
1084 // to be applied as per normal (no synchronization).
Robert Carr0d480722017-01-10 16:42:54 -08001085 mCurrentState.barrierLayer = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001086 } else {
David Sodman41fdfc92017-11-06 16:09:56 -08001087 auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber);
Robert Carr0d480722017-01-10 16:42:54 -08001088 if (barrierLayer->addSyncPoint(syncPoint)) {
Dan Stozacac35382016-01-27 12:21:06 -08001089 mRemoteSyncPoints.push_back(std::move(syncPoint));
1090 } else {
1091 // We already missed the frame we're supposed to synchronize
1092 // on, so go ahead and apply the state update
Robert Carr0d480722017-01-10 16:42:54 -08001093 mCurrentState.barrierLayer = nullptr;
Dan Stozacac35382016-01-27 12:21:06 -08001094 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001095 }
1096
Dan Stoza7dde5992015-05-22 09:51:44 -07001097 // Wake us up to check if the frame has been received
1098 setTransactionFlags(eTransactionNeeded);
Dan Stozaf5702ff2016-11-02 16:27:47 -07001099 mFlinger->setTransactionFlags(eTraversalNeeded);
Dan Stoza7dde5992015-05-22 09:51:44 -07001100 }
1101 mPendingStates.push_back(mCurrentState);
Dan Stozaf7ba41a2017-05-10 15:11:11 -07001102 ATRACE_INT(mTransactionName.string(), mPendingStates.size());
Dan Stoza7dde5992015-05-22 09:51:44 -07001103}
1104
Pablo Ceballos05289c22016-04-14 15:49:55 -07001105void Layer::popPendingState(State* stateToCommit) {
1106 auto oldFlags = stateToCommit->flags;
1107 *stateToCommit = mPendingStates[0];
David Sodman41fdfc92017-11-06 16:09:56 -08001108 stateToCommit->flags =
1109 (oldFlags & ~stateToCommit->mask) | (stateToCommit->flags & stateToCommit->mask);
Dan Stoza7dde5992015-05-22 09:51:44 -07001110
1111 mPendingStates.removeAt(0);
Dan Stozaf7ba41a2017-05-10 15:11:11 -07001112 ATRACE_INT(mTransactionName.string(), mPendingStates.size());
Dan Stoza7dde5992015-05-22 09:51:44 -07001113}
1114
Pablo Ceballos05289c22016-04-14 15:49:55 -07001115bool Layer::applyPendingStates(State* stateToCommit) {
Dan Stoza7dde5992015-05-22 09:51:44 -07001116 bool stateUpdateAvailable = false;
1117 while (!mPendingStates.empty()) {
Robert Carr0d480722017-01-10 16:42:54 -08001118 if (mPendingStates[0].barrierLayer != nullptr) {
Dan Stoza7dde5992015-05-22 09:51:44 -07001119 if (mRemoteSyncPoints.empty()) {
1120 // If we don't have a sync point for this, apply it anyway. It
1121 // will be visually wrong, but it should keep us from getting
1122 // into too much trouble.
1123 ALOGE("[%s] No local sync point found", mName.string());
Pablo Ceballos05289c22016-04-14 15:49:55 -07001124 popPendingState(stateToCommit);
Dan Stoza7dde5992015-05-22 09:51:44 -07001125 stateUpdateAvailable = true;
1126 continue;
1127 }
1128
David Sodman41fdfc92017-11-06 16:09:56 -08001129 if (mRemoteSyncPoints.front()->getFrameNumber() != mPendingStates[0].frameNumber) {
1130 ALOGE("[%s] Unexpected sync point frame number found", mName.string());
Dan Stozacac35382016-01-27 12:21:06 -08001131
1132 // Signal our end of the sync point and then dispose of it
1133 mRemoteSyncPoints.front()->setTransactionApplied();
1134 mRemoteSyncPoints.pop_front();
1135 continue;
1136 }
1137
Dan Stoza7dde5992015-05-22 09:51:44 -07001138 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1139 // Apply the state update
Pablo Ceballos05289c22016-04-14 15:49:55 -07001140 popPendingState(stateToCommit);
Dan Stoza7dde5992015-05-22 09:51:44 -07001141 stateUpdateAvailable = true;
1142
1143 // Signal our end of the sync point and then dispose of it
1144 mRemoteSyncPoints.front()->setTransactionApplied();
1145 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001146 } else {
1147 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001148 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001149 } else {
Pablo Ceballos05289c22016-04-14 15:49:55 -07001150 popPendingState(stateToCommit);
Dan Stoza7dde5992015-05-22 09:51:44 -07001151 stateUpdateAvailable = true;
1152 }
1153 }
1154
1155 // If we still have pending updates, wake SurfaceFlinger back up and point
1156 // it at this layer so we can process them
1157 if (!mPendingStates.empty()) {
1158 setTransactionFlags(eTransactionNeeded);
1159 mFlinger->setTransactionFlags(eTraversalNeeded);
1160 }
1161
1162 mCurrentState.modified = false;
1163 return stateUpdateAvailable;
1164}
1165
Mathias Agopian13127d82013-03-05 17:47:11 -08001166uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001167 ATRACE_CALL();
1168
Dan Stoza7dde5992015-05-22 09:51:44 -07001169 pushPendingState();
Pablo Ceballos05289c22016-04-14 15:49:55 -07001170 Layer::State c = getCurrentState();
1171 if (!applyPendingStates(&c)) {
Dan Stoza7dde5992015-05-22 09:51:44 -07001172 return 0;
1173 }
1174
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001175 const Layer::State& s(getDrawingState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001176
David Sodman41fdfc92017-11-06 16:09:56 -08001177 const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001178
David Sodman0c69cad2017-08-21 12:12:51 -07001179 if (mSurfaceFlingerConsumer && sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001180 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001181 ALOGD_IF(DEBUG_RESIZE,
David Sodman41fdfc92017-11-06 16:09:56 -08001182 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
1183 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1184 " requested={ wh={%4u,%4u} }}\n"
1185 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1186 " requested={ wh={%4u,%4u} }}\n",
1187 this, getName().string(), mCurrentTransform, getEffectiveScalingMode(), c.active.w,
1188 c.active.h, c.crop.left, c.crop.top, c.crop.right, c.crop.bottom,
1189 c.crop.getWidth(), c.crop.getHeight(), c.requested.w, c.requested.h, s.active.w,
1190 s.active.h, s.crop.left, s.crop.top, s.crop.right, s.crop.bottom,
1191 s.crop.getWidth(), s.crop.getHeight(), s.requested.w, s.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001192
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001193 // record the new size, form this point on, when the client request
1194 // a buffer, it'll get the new size.
David Sodman41fdfc92017-11-06 16:09:56 -08001195 mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001196 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001197
Robert Carre392b552017-09-19 12:16:05 -07001198 // Don't let Layer::doTransaction update the drawing state
1199 // if we have a pending resize, unless we are in fixed-size mode.
1200 // the drawing state will be updated only once we receive a buffer
1201 // with the correct size.
1202 //
1203 // In particular, we want to make sure the clip (which is part
1204 // of the geometry state) is latched together with the size but is
1205 // latched immediately when no resizing is involved.
1206 //
1207 // If a sideband stream is attached, however, we want to skip this
1208 // optimization so that transactions aren't missed when a buffer
1209 // never arrives
1210 //
1211 // In the case that we don't have a buffer we ignore other factors
1212 // and avoid entering the resizePending state. At a high level the
1213 // resizePending state is to avoid applying the state of the new buffer
1214 // to the old buffer. However in the state where we don't have an old buffer
1215 // there is no such concern but we may still be being used as a parent layer.
David Sodman41fdfc92017-11-06 16:09:56 -08001216 const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) &&
1217 (mActiveBuffer != nullptr);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001218 if (!isFixedSize()) {
Dan Stoza9e9b0442015-04-22 14:59:08 -07001219 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001220 flags |= eDontUpdateGeometryState;
1221 }
1222 }
1223
Robert Carr7bf247e2017-05-18 14:02:49 -07001224 // Here we apply various requested geometry states, depending on our
1225 // latching configuration. See Layer.h for a detailed discussion of
1226 // how geometry latching is controlled.
1227 if (!(flags & eDontUpdateGeometryState)) {
Pablo Ceballos7d052572016-06-02 17:46:05 -07001228 Layer::State& editCurrentState(getCurrentState());
Robert Carr7bf247e2017-05-18 14:02:49 -07001229
1230 // If mFreezeGeometryUpdates is true we are in the setGeometryAppliesWithResize
1231 // mode, which causes attributes which normally latch regardless of scaling mode,
1232 // to be delayed. We copy the requested state to the active state making sure
1233 // to respect these rules (again see Layer.h for a detailed discussion).
1234 //
1235 // There is an awkward asymmetry in the handling of the crop states in the position
1236 // states, as can be seen below. Largely this arises from position and transform
1237 // being stored in the same data structure while having different latching rules.
1238 // b/38182305
1239 //
1240 // Careful that "c" and editCurrentState may not begin as equivalent due to
1241 // applyPendingStates in the presence of deferred transactions.
1242 if (mFreezeGeometryUpdates) {
Robert Carr82364e32016-05-15 11:27:47 -07001243 float tx = c.active.transform.tx();
1244 float ty = c.active.transform.ty();
1245 c.active = c.requested;
1246 c.active.transform.set(tx, ty);
1247 editCurrentState.active = c.active;
1248 } else {
1249 editCurrentState.active = editCurrentState.requested;
1250 c.active = c.requested;
1251 }
Mathias Agopian13127d82013-03-05 17:47:11 -08001252 }
1253
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001254 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001255 // invalidate and recompute the visible regions if needed
1256 flags |= Layer::eVisibleRegion;
1257 }
1258
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001259 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001260 // invalidate and recompute the visible regions if needed
1261 flags |= eVisibleRegion;
1262 this->contentDirty = true;
1263
1264 // we may use linear filtering, if the matrix scales us
Robert Carr3dcabfa2016-03-01 18:36:58 -08001265 const uint8_t type = c.active.transform.getType();
David Sodman41fdfc92017-11-06 16:09:56 -08001266 mNeedsFiltering = (!c.active.transform.preserveRects() || (type >= Transform::SCALE));
Mathias Agopian13127d82013-03-05 17:47:11 -08001267 }
1268
Dan Stozac8145172016-04-28 16:29:06 -07001269 // If the layer is hidden, signal and clear out all local sync points so
1270 // that transactions for layers depending on this layer's frames becoming
1271 // visible are not blocked
1272 if (c.flags & layer_state_t::eLayerHidden) {
Robert Carr1f0a16a2016-10-24 16:27:39 -07001273 clearSyncPoints();
Dan Stozac8145172016-04-28 16:29:06 -07001274 }
1275
Mathias Agopian13127d82013-03-05 17:47:11 -08001276 // Commit the transaction
Pablo Ceballos05289c22016-04-14 15:49:55 -07001277 commitTransaction(c);
Mathias Agopian13127d82013-03-05 17:47:11 -08001278 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001279}
1280
Pablo Ceballos05289c22016-04-14 15:49:55 -07001281void Layer::commitTransaction(const State& stateToCommit) {
1282 mDrawingState = stateToCommit;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001283}
1284
Mathias Agopian13127d82013-03-05 17:47:11 -08001285uint32_t Layer::getTransactionFlags(uint32_t flags) {
1286 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1287}
1288
1289uint32_t Layer::setTransactionFlags(uint32_t flags) {
1290 return android_atomic_or(flags, &mTransactionFlags);
1291}
1292
Robert Carr82364e32016-05-15 11:27:47 -07001293bool Layer::setPosition(float x, float y, bool immediate) {
Robert Carr3dcabfa2016-03-01 18:36:58 -08001294 if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
Mathias Agopian13127d82013-03-05 17:47:11 -08001295 return false;
1296 mCurrentState.sequence++;
Robert Carr69663fb2016-03-27 19:59:19 -07001297
1298 // We update the requested and active position simultaneously because
1299 // we want to apply the position portion of the transform matrix immediately,
1300 // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
Robert Carr3dcabfa2016-03-01 18:36:58 -08001301 mCurrentState.requested.transform.set(x, y);
Robert Carr7bf247e2017-05-18 14:02:49 -07001302 if (immediate && !mFreezeGeometryUpdates) {
1303 // Here we directly update the active state
1304 // unlike other setters, because we store it within
1305 // the transform, but use different latching rules.
1306 // b/38182305
Robert Carr82364e32016-05-15 11:27:47 -07001307 mCurrentState.active.transform.set(x, y);
1308 }
Robert Carr7bf247e2017-05-18 14:02:49 -07001309 mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
Robert Carr69663fb2016-03-27 19:59:19 -07001310
Dan Stoza7dde5992015-05-22 09:51:44 -07001311 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001312 setTransactionFlags(eTransactionNeeded);
1313 return true;
1314}
Robert Carr82364e32016-05-15 11:27:47 -07001315
Robert Carr1f0a16a2016-10-24 16:27:39 -07001316bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) {
1317 ssize_t idx = mCurrentChildren.indexOf(childLayer);
1318 if (idx < 0) {
1319 return false;
1320 }
1321 if (childLayer->setLayer(z)) {
1322 mCurrentChildren.removeAt(idx);
1323 mCurrentChildren.add(childLayer);
1324 }
1325 return true;
1326}
1327
Robert Carrae060832016-11-28 10:51:00 -08001328bool Layer::setLayer(int32_t z) {
David Sodman41fdfc92017-11-06 16:09:56 -08001329 if (mCurrentState.z == z) return false;
Mathias Agopian13127d82013-03-05 17:47:11 -08001330 mCurrentState.sequence++;
1331 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001332 mCurrentState.modified = true;
Robert Carrdb66e622017-04-10 16:55:57 -07001333
1334 // Discard all relative layering.
1335 if (mCurrentState.zOrderRelativeOf != nullptr) {
1336 sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
1337 if (strongRelative != nullptr) {
1338 strongRelative->removeZOrderRelative(this);
1339 }
1340 mCurrentState.zOrderRelativeOf = nullptr;
1341 }
Mathias Agopian13127d82013-03-05 17:47:11 -08001342 setTransactionFlags(eTransactionNeeded);
1343 return true;
1344}
Robert Carr1f0a16a2016-10-24 16:27:39 -07001345
Robert Carrdb66e622017-04-10 16:55:57 -07001346void Layer::removeZOrderRelative(const wp<Layer>& relative) {
1347 mCurrentState.zOrderRelatives.remove(relative);
1348 mCurrentState.sequence++;
1349 mCurrentState.modified = true;
1350 setTransactionFlags(eTransactionNeeded);
1351}
1352
1353void Layer::addZOrderRelative(const wp<Layer>& relative) {
1354 mCurrentState.zOrderRelatives.add(relative);
1355 mCurrentState.modified = true;
1356 mCurrentState.sequence++;
1357 setTransactionFlags(eTransactionNeeded);
1358}
1359
1360bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t z) {
1361 sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
1362 if (handle == nullptr) {
1363 return false;
1364 }
1365 sp<Layer> relative = handle->owner.promote();
1366 if (relative == nullptr) {
1367 return false;
1368 }
1369
1370 mCurrentState.sequence++;
1371 mCurrentState.modified = true;
1372 mCurrentState.z = z;
1373
chaviw9ab4bd12017-11-03 13:11:00 -07001374 auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
1375 if (oldZOrderRelativeOf != nullptr) {
1376 oldZOrderRelativeOf->removeZOrderRelative(this);
1377 }
Robert Carrdb66e622017-04-10 16:55:57 -07001378 mCurrentState.zOrderRelativeOf = relative;
1379 relative->addZOrderRelative(this);
1380
1381 setTransactionFlags(eTransactionNeeded);
1382
1383 return true;
1384}
1385
Mathias Agopian13127d82013-03-05 17:47:11 -08001386bool Layer::setSize(uint32_t w, uint32_t h) {
David Sodman41fdfc92017-11-06 16:09:56 -08001387 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) return false;
Mathias Agopian13127d82013-03-05 17:47:11 -08001388 mCurrentState.requested.w = w;
1389 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001390 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001391 setTransactionFlags(eTransactionNeeded);
1392 return true;
1393}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001394bool Layer::setAlpha(float alpha) {
David Sodman41fdfc92017-11-06 16:09:56 -08001395 if (mCurrentState.color.a == alpha) return false;
Mathias Agopian13127d82013-03-05 17:47:11 -08001396 mCurrentState.sequence++;
chaviw13fdc492017-06-27 12:40:18 -07001397 mCurrentState.color.a = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001398 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001399 setTransactionFlags(eTransactionNeeded);
1400 return true;
1401}
chaviw13fdc492017-06-27 12:40:18 -07001402
1403bool Layer::setColor(const half3& color) {
David Sodman41fdfc92017-11-06 16:09:56 -08001404 if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
1405 color.b == mCurrentState.color.b)
chaviw13fdc492017-06-27 12:40:18 -07001406 return false;
1407
1408 mCurrentState.sequence++;
1409 mCurrentState.color.r = color.r;
1410 mCurrentState.color.g = color.g;
1411 mCurrentState.color.b = color.b;
1412 mCurrentState.modified = true;
1413 setTransactionFlags(eTransactionNeeded);
1414 return true;
1415}
1416
Mathias Agopian13127d82013-03-05 17:47:11 -08001417bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1418 mCurrentState.sequence++;
David Sodman41fdfc92017-11-06 16:09:56 -08001419 mCurrentState.requested.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001420 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001421 setTransactionFlags(eTransactionNeeded);
1422 return true;
1423}
1424bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001425 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001426 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001427 setTransactionFlags(eTransactionNeeded);
1428 return true;
1429}
1430bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1431 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
David Sodman41fdfc92017-11-06 16:09:56 -08001432 if (mCurrentState.flags == newFlags) return false;
Mathias Agopian13127d82013-03-05 17:47:11 -08001433 mCurrentState.sequence++;
1434 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001435 mCurrentState.mask = mask;
1436 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001437 setTransactionFlags(eTransactionNeeded);
1438 return true;
1439}
Robert Carr99e27f02016-06-16 15:18:02 -07001440
1441bool Layer::setCrop(const Rect& crop, bool immediate) {
David Sodman41fdfc92017-11-06 16:09:56 -08001442 if (mCurrentState.requestedCrop == crop) return false;
Mathias Agopian13127d82013-03-05 17:47:11 -08001443 mCurrentState.sequence++;
Robert Carr99e27f02016-06-16 15:18:02 -07001444 mCurrentState.requestedCrop = crop;
Robert Carr7bf247e2017-05-18 14:02:49 -07001445 if (immediate && !mFreezeGeometryUpdates) {
Robert Carr99e27f02016-06-16 15:18:02 -07001446 mCurrentState.crop = crop;
1447 }
Robert Carr7bf247e2017-05-18 14:02:49 -07001448 mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
1449
Dan Stoza7dde5992015-05-22 09:51:44 -07001450 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001451 setTransactionFlags(eTransactionNeeded);
1452 return true;
1453}
Robert Carr8d5227b2017-03-16 15:41:03 -07001454
1455bool Layer::setFinalCrop(const Rect& crop, bool immediate) {
David Sodman41fdfc92017-11-06 16:09:56 -08001456 if (mCurrentState.requestedFinalCrop == crop) return false;
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001457 mCurrentState.sequence++;
Robert Carr8d5227b2017-03-16 15:41:03 -07001458 mCurrentState.requestedFinalCrop = crop;
Robert Carr7bf247e2017-05-18 14:02:49 -07001459 if (immediate && !mFreezeGeometryUpdates) {
Robert Carr8d5227b2017-03-16 15:41:03 -07001460 mCurrentState.finalCrop = crop;
1461 }
Robert Carr7bf247e2017-05-18 14:02:49 -07001462 mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
1463
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001464 mCurrentState.modified = true;
1465 setTransactionFlags(eTransactionNeeded);
1466 return true;
1467}
Mathias Agopian13127d82013-03-05 17:47:11 -08001468
Robert Carrc3574f72016-03-24 12:19:32 -07001469bool Layer::setOverrideScalingMode(int32_t scalingMode) {
David Sodman41fdfc92017-11-06 16:09:56 -08001470 if (scalingMode == mOverrideScalingMode) return false;
Robert Carrc3574f72016-03-24 12:19:32 -07001471 mOverrideScalingMode = scalingMode;
Robert Carr82364e32016-05-15 11:27:47 -07001472 setTransactionFlags(eTransactionNeeded);
Robert Carrc3574f72016-03-24 12:19:32 -07001473 return true;
1474}
1475
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -05001476void Layer::setInfo(uint32_t type, uint32_t appId) {
David Sodman41fdfc92017-11-06 16:09:56 -08001477 mCurrentState.appId = appId;
1478 mCurrentState.type = type;
1479 mCurrentState.modified = true;
1480 setTransactionFlags(eTransactionNeeded);
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -05001481}
1482
Mathias Agopian13127d82013-03-05 17:47:11 -08001483bool Layer::setLayerStack(uint32_t layerStack) {
David Sodman41fdfc92017-11-06 16:09:56 -08001484 if (mCurrentState.layerStack == layerStack) return false;
Mathias Agopian13127d82013-03-05 17:47:11 -08001485 mCurrentState.sequence++;
1486 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001487 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001488 setTransactionFlags(eTransactionNeeded);
1489 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001490}
1491
Courtney Goeltzenleuchterbb09b432016-11-30 13:51:28 -07001492bool Layer::setDataSpace(android_dataspace dataSpace) {
David Sodman41fdfc92017-11-06 16:09:56 -08001493 if (mCurrentState.dataSpace == dataSpace) return false;
Courtney Goeltzenleuchterbb09b432016-11-30 13:51:28 -07001494 mCurrentState.sequence++;
1495 mCurrentState.dataSpace = dataSpace;
1496 mCurrentState.modified = true;
1497 setTransactionFlags(eTransactionNeeded);
1498 return true;
1499}
1500
Courtney Goeltzenleuchter532b2632017-05-05 16:34:38 -06001501android_dataspace Layer::getDataSpace() const {
1502 return mCurrentState.dataSpace;
1503}
1504
Robert Carr1f0a16a2016-10-24 16:27:39 -07001505uint32_t Layer::getLayerStack() const {
Chia-I Wue41dbe62017-06-13 14:10:56 -07001506 auto p = mDrawingParent.promote();
Robert Carr1f0a16a2016-10-24 16:27:39 -07001507 if (p == nullptr) {
1508 return getDrawingState().layerStack;
1509 }
1510 return p->getLayerStack();
1511}
1512
David Sodman41fdfc92017-11-06 16:09:56 -08001513void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
Robert Carr0d480722017-01-10 16:42:54 -08001514 mCurrentState.barrierLayer = barrierLayer;
Dan Stoza7dde5992015-05-22 09:51:44 -07001515 mCurrentState.frameNumber = frameNumber;
1516 // We don't set eTransactionNeeded, because just receiving a deferral
1517 // request without any other state updates shouldn't actually induce a delay
1518 mCurrentState.modified = true;
1519 pushPendingState();
Robert Carr0d480722017-01-10 16:42:54 -08001520 mCurrentState.barrierLayer = nullptr;
Dan Stoza792e5292016-02-11 11:43:58 -08001521 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001522 mCurrentState.modified = false;
Robert Carr0d480722017-01-10 16:42:54 -08001523}
1524
David Sodman41fdfc92017-11-06 16:09:56 -08001525void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
Robert Carr0d480722017-01-10 16:42:54 -08001526 sp<Handle> handle = static_cast<Handle*>(barrierHandle.get());
1527 deferTransactionUntil(handle->owner.promote(), frameNumber);
Dan Stoza7dde5992015-05-22 09:51:44 -07001528}
1529
Dan Stozaee44edd2015-03-23 15:50:23 -07001530void Layer::useSurfaceDamage() {
1531 if (mFlinger->mForceFullDamage) {
1532 surfaceDamageRegion = Region::INVALID_REGION;
1533 } else {
1534 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1535 }
1536}
1537
1538void Layer::useEmptyDamage() {
1539 surfaceDamageRegion.clear();
1540}
1541
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001542// ----------------------------------------------------------------------------
1543// pageflip handling...
1544// ----------------------------------------------------------------------------
1545
Dan Stoza6b9454d2014-11-07 16:00:59 -08001546bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001547 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001548 return true;
1549 }
1550
Dan Stoza6b9454d2014-11-07 16:00:59 -08001551 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001552 if (mQueueItems.empty()) {
1553 return false;
1554 }
1555 auto timestamp = mQueueItems[0].mTimestamp;
David Sodman41fdfc92017-11-06 16:09:56 -08001556 nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001557
1558 // Ignore timestamps more than a second in the future
1559 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
David Sodman41fdfc92017-11-06 16:09:56 -08001560 ALOGW_IF(!isPlausible,
1561 "[%s] Timestamp %" PRId64 " seems implausible "
1562 "relative to expectedPresent %" PRId64,
1563 mName.string(), timestamp, expectedPresent);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001564
1565 bool isDue = timestamp < expectedPresent;
1566 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001567}
1568
Brian Anderson0a61b0c2016-12-07 14:55:56 -08001569bool Layer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
David Sodman41fdfc92017-11-06 16:09:56 -08001570 const std::shared_ptr<FenceTime>& presentFence,
1571 const CompositorTiming& compositorTiming) {
Brian Andersond6927fb2016-07-23 23:37:30 -07001572 // mFrameLatencyNeeded is true when a new frame was latched for the
1573 // composition.
David Sodman41fdfc92017-11-06 16:09:56 -08001574 if (!mFrameLatencyNeeded) return false;
Fabien Sanglard28e98082016-12-05 10:19:46 -08001575
Fabien Sanglard28e98082016-12-05 10:19:46 -08001576 // Update mFrameEventHistory.
1577 {
1578 Mutex::Autolock lock(mFrameEventHistoryMutex);
David Sodman41fdfc92017-11-06 16:09:56 -08001579 mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence,
1580 compositorTiming);
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001581 }
Fabien Sanglard28e98082016-12-05 10:19:46 -08001582
1583 // Update mFrameTracker.
1584 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
1585 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1586
David Sodman41fdfc92017-11-06 16:09:56 -08001587 std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime();
Fabien Sanglard28e98082016-12-05 10:19:46 -08001588 if (frameReadyFence->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -07001589 mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
Fabien Sanglard28e98082016-12-05 10:19:46 -08001590 } else {
1591 // There was no fence for this frame, so assume that it was ready
1592 // to be presented at the desired present time.
1593 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1594 }
1595
Brian Anderson3d4039d2016-09-23 16:31:30 -07001596 if (presentFence->isValid()) {
David Sodman41fdfc92017-11-06 16:09:56 -08001597 mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
Fabien Sanglard28e98082016-12-05 10:19:46 -08001598 } else {
1599 // The HWC doesn't support present fences, so use the refresh
1600 // timestamp instead.
Brian Anderson3d4039d2016-09-23 16:31:30 -07001601 mFrameTracker.setActualPresentTime(
David Sodman41fdfc92017-11-06 16:09:56 -08001602 mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY));
Fabien Sanglard28e98082016-12-05 10:19:46 -08001603 }
1604
1605 mFrameTracker.advanceFrame();
1606 mFrameLatencyNeeded = false;
1607 return true;
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001608}
1609
Robert Carr1f0a16a2016-10-24 16:27:39 -07001610bool Layer::isHiddenByPolicy() const {
1611 const Layer::State& s(mDrawingState);
Chia-I Wue41dbe62017-06-13 14:10:56 -07001612 const auto& parent = mDrawingParent.promote();
Robert Carr1f0a16a2016-10-24 16:27:39 -07001613 if (parent != nullptr && parent->isHiddenByPolicy()) {
1614 return true;
1615 }
1616 return s.flags & layer_state_t::eLayerHidden;
1617}
1618
David Sodman41fdfc92017-11-06 16:09:56 -08001619uint32_t Layer::getEffectiveUsage(uint32_t usage) const {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001620 // TODO: should we do something special if mSecure is set?
1621 if (mProtectedByApp) {
1622 // need a hardware-protected path to external video sink
1623 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001624 }
Riley Andrews03414a12014-07-01 14:22:59 -07001625 if (mPotentialCursor) {
1626 usage |= GraphicBuffer::USAGE_CURSOR;
1627 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001628 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001629 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001630}
1631
Mathias Agopian84300952012-11-21 16:02:13 -08001632void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001633 uint32_t orientation = 0;
1634 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001635 // The transform hint is used to improve performance, but we can
1636 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001637 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001638 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001639 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001640 if (orientation & Transform::ROT_INVALID) {
1641 orientation = 0;
1642 }
1643 }
David Sodman0c69cad2017-08-21 12:12:51 -07001644 if (mSurfaceFlingerConsumer) {
1645 mSurfaceFlingerConsumer->setTransformHint(orientation);
1646 }
Mathias Agopiana4583642011-08-23 18:03:18 -07001647}
1648
Mathias Agopian13127d82013-03-05 17:47:11 -08001649// ----------------------------------------------------------------------------
1650// debugging
1651// ----------------------------------------------------------------------------
1652
Kalle Raitaa099a242017-01-11 11:17:29 -08001653LayerDebugInfo Layer::getLayerDebugInfo() const {
1654 LayerDebugInfo info;
1655 const Layer::State& ds = getDrawingState();
1656 info.mName = getName();
chaviw1acbec72017-07-27 15:28:26 -07001657 sp<Layer> parent = getParent();
Kalle Raitaa099a242017-01-11 11:17:29 -08001658 info.mParentName = (parent == nullptr ? std::string("none") : parent->getName().string());
1659 info.mType = String8(getTypeId());
1660 info.mTransparentRegion = ds.activeTransparentRegion;
1661 info.mVisibleRegion = visibleRegion;
1662 info.mSurfaceDamageRegion = surfaceDamageRegion;
1663 info.mLayerStack = getLayerStack();
1664 info.mX = ds.active.transform.tx();
1665 info.mY = ds.active.transform.ty();
1666 info.mZ = ds.z;
1667 info.mWidth = ds.active.w;
1668 info.mHeight = ds.active.h;
1669 info.mCrop = ds.crop;
1670 info.mFinalCrop = ds.finalCrop;
chaviw13fdc492017-06-27 12:40:18 -07001671 info.mColor = ds.color;
Kalle Raitaa099a242017-01-11 11:17:29 -08001672 info.mFlags = ds.flags;
1673 info.mPixelFormat = getPixelFormat();
1674 info.mDataSpace = getDataSpace();
1675 info.mMatrix[0][0] = ds.active.transform[0][0];
1676 info.mMatrix[0][1] = ds.active.transform[0][1];
1677 info.mMatrix[1][0] = ds.active.transform[1][0];
1678 info.mMatrix[1][1] = ds.active.transform[1][1];
1679 {
1680 sp<const GraphicBuffer> activeBuffer = getActiveBuffer();
1681 if (activeBuffer != 0) {
1682 info.mActiveBufferWidth = activeBuffer->getWidth();
1683 info.mActiveBufferHeight = activeBuffer->getHeight();
1684 info.mActiveBufferStride = activeBuffer->getStride();
1685 info.mActiveBufferFormat = activeBuffer->format;
1686 } else {
1687 info.mActiveBufferWidth = 0;
1688 info.mActiveBufferHeight = 0;
1689 info.mActiveBufferStride = 0;
1690 info.mActiveBufferFormat = 0;
1691 }
Mathias Agopian13127d82013-03-05 17:47:11 -08001692 }
Kalle Raitaa099a242017-01-11 11:17:29 -08001693 info.mNumQueuedFrames = getQueuedFrameCount();
1694 info.mRefreshPending = isBufferLatched();
1695 info.mIsOpaque = isOpaque(ds);
1696 info.mContentDirty = contentDirty;
1697 return info;
Mathias Agopian13127d82013-03-05 17:47:11 -08001698}
Fabien Sanglard9d96de42016-10-11 00:15:18 +00001699#ifdef USE_HWC2
Dan Stozae22aec72016-08-01 13:20:59 -07001700void Layer::miniDumpHeader(String8& result) {
1701 result.append("----------------------------------------");
1702 result.append("---------------------------------------\n");
1703 result.append(" Layer name\n");
1704 result.append(" Z | ");
1705 result.append(" Comp Type | ");
1706 result.append(" Disp Frame (LTRB) | ");
1707 result.append(" Source Crop (LTRB)\n");
1708 result.append("----------------------------------------");
1709 result.append("---------------------------------------\n");
1710}
1711
1712void Layer::miniDump(String8& result, int32_t hwcId) const {
1713 if (mHwcLayers.count(hwcId) == 0) {
1714 return;
1715 }
1716
1717 String8 name;
1718 if (mName.length() > 77) {
1719 std::string shortened;
1720 shortened.append(mName.string(), 36);
1721 shortened.append("[...]");
1722 shortened.append(mName.string() + (mName.length() - 36), 36);
1723 name = shortened.c_str();
1724 } else {
1725 name = mName;
1726 }
1727
1728 result.appendFormat(" %s\n", name.string());
1729
1730 const Layer::State& layerState(getDrawingState());
1731 const HWCInfo& hwcInfo = mHwcLayers.at(hwcId);
John Reck8c3b6ac2017-08-24 10:25:42 -07001732 result.appendFormat(" %10d | ", layerState.z);
David Sodman41fdfc92017-11-06 16:09:56 -08001733 result.appendFormat("%10s | ", to_string(getCompositionType(hwcId)).c_str());
Dan Stozae22aec72016-08-01 13:20:59 -07001734 const Rect& frame = hwcInfo.displayFrame;
David Sodman41fdfc92017-11-06 16:09:56 -08001735 result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
Dan Stoza5a423ea2017-02-16 14:10:39 -08001736 const FloatRect& crop = hwcInfo.sourceCrop;
David Sodman41fdfc92017-11-06 16:09:56 -08001737 result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom);
Dan Stozae22aec72016-08-01 13:20:59 -07001738
1739 result.append("- - - - - - - - - - - - - - - - - - - - ");
1740 result.append("- - - - - - - - - - - - - - - - - - - -\n");
1741}
Fabien Sanglard9d96de42016-10-11 00:15:18 +00001742#endif
Dan Stozae22aec72016-08-01 13:20:59 -07001743
Svetoslavd85084b2014-03-20 10:28:31 -07001744void Layer::dumpFrameStats(String8& result) const {
1745 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001746}
1747
Svetoslavd85084b2014-03-20 10:28:31 -07001748void Layer::clearFrameStats() {
1749 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001750}
1751
Jamie Gennis6547ff42013-07-16 20:12:42 -07001752void Layer::logFrameStats() {
1753 mFrameTracker.logAndResetStats(mName);
1754}
1755
Svetoslavd85084b2014-03-20 10:28:31 -07001756void Layer::getFrameStats(FrameStats* outStats) const {
1757 mFrameTracker.getStats(outStats);
1758}
1759
Brian Andersond6927fb2016-07-23 23:37:30 -07001760void Layer::dumpFrameEvents(String8& result) {
David Sodman41fdfc92017-11-06 16:09:56 -08001761 result.appendFormat("- Layer %s (%s, %p)\n", getName().string(), getTypeId(), this);
Brian Andersond6927fb2016-07-23 23:37:30 -07001762 Mutex::Autolock lock(mFrameEventHistoryMutex);
1763 mFrameEventHistory.checkFencesForCompletion();
1764 mFrameEventHistory.dump(result);
1765}
Pablo Ceballos40845df2016-01-25 17:41:15 -08001766
Brian Anderson5ea5e592016-12-01 16:54:33 -08001767void Layer::onDisconnect() {
1768 Mutex::Autolock lock(mFrameEventHistoryMutex);
1769 mFrameEventHistory.onDisconnect();
1770}
1771
Brian Anderson3890c392016-07-25 12:48:08 -07001772void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
David Sodman41fdfc92017-11-06 16:09:56 -08001773 FrameEventHistoryDelta* outDelta) {
Brian Andersond6927fb2016-07-23 23:37:30 -07001774 Mutex::Autolock lock(mFrameEventHistoryMutex);
1775 if (newTimestamps) {
Brian Andersonfbc80ae2017-05-26 16:23:54 -07001776 // If there are any unsignaled fences in the aquire timeline at this
1777 // point, the previously queued frame hasn't been latched yet. Go ahead
1778 // and try to get the signal time here so the syscall is taken out of
1779 // the main thread's critical path.
1780 mAcquireTimeline.updateSignalTimes();
1781 // Push the new fence after updating since it's likely still pending.
Brian Anderson3d4039d2016-09-23 16:31:30 -07001782 mAcquireTimeline.push(newTimestamps->acquireFence);
Brian Andersond6927fb2016-07-23 23:37:30 -07001783 mFrameEventHistory.addQueue(*newTimestamps);
1784 }
1785
Brian Anderson3890c392016-07-25 12:48:08 -07001786 if (outDelta) {
1787 mFrameEventHistory.getAndResetDelta(outDelta);
Brian Andersond6927fb2016-07-23 23:37:30 -07001788 }
Pablo Ceballos40845df2016-01-25 17:41:15 -08001789}
Dan Stozae77c7662016-05-13 11:37:28 -07001790
David Sodman41fdfc92017-11-06 16:09:56 -08001791std::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(bool forceFlush) {
Dan Stozae77c7662016-05-13 11:37:28 -07001792 std::vector<OccupancyTracker::Segment> history;
David Sodman0c69cad2017-08-21 12:12:51 -07001793
David Sodman41fdfc92017-11-06 16:09:56 -08001794 if (!mSurfaceFlingerConsumer) return {};
David Sodman0c69cad2017-08-21 12:12:51 -07001795
David Sodman41fdfc92017-11-06 16:09:56 -08001796 status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history);
Dan Stozae77c7662016-05-13 11:37:28 -07001797 if (result != NO_ERROR) {
David Sodman41fdfc92017-11-06 16:09:56 -08001798 ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result);
Dan Stozae77c7662016-05-13 11:37:28 -07001799 return {};
1800 }
1801 return history;
1802}
1803
Robert Carr367c5682016-06-20 11:55:28 -07001804bool Layer::getTransformToDisplayInverse() const {
David Sodman0c69cad2017-08-21 12:12:51 -07001805 if (mSurfaceFlingerConsumer) {
1806 return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
1807 }
1808 return false;
Robert Carr367c5682016-06-20 11:55:28 -07001809}
1810
Chia-I Wu98f1c102017-05-30 14:54:08 -07001811size_t Layer::getChildrenCount() const {
1812 size_t count = 0;
1813 for (const sp<Layer>& child : mCurrentChildren) {
1814 count += 1 + child->getChildrenCount();
1815 }
1816 return count;
1817}
1818
Robert Carr1f0a16a2016-10-24 16:27:39 -07001819void Layer::addChild(const sp<Layer>& layer) {
1820 mCurrentChildren.add(layer);
1821 layer->setParent(this);
1822}
1823
1824ssize_t Layer::removeChild(const sp<Layer>& layer) {
1825 layer->setParent(nullptr);
1826 return mCurrentChildren.remove(layer);
1827}
1828
Robert Carr1db73f62016-12-21 12:58:51 -08001829bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) {
1830 sp<Handle> handle = nullptr;
1831 sp<Layer> newParent = nullptr;
1832 if (newParentHandle == nullptr) {
1833 return false;
1834 }
1835 handle = static_cast<Handle*>(newParentHandle.get());
1836 newParent = handle->owner.promote();
1837 if (newParent == nullptr) {
1838 ALOGE("Unable to promote Layer handle");
1839 return false;
1840 }
1841
1842 for (const sp<Layer>& child : mCurrentChildren) {
Chia-I Wue41dbe62017-06-13 14:10:56 -07001843 newParent->addChild(child);
Robert Carr1db73f62016-12-21 12:58:51 -08001844
1845 sp<Client> client(child->mClientRef.promote());
1846 if (client != nullptr) {
1847 client->setParentLayer(newParent);
1848 }
1849 }
1850 mCurrentChildren.clear();
1851
1852 return true;
1853}
1854
chaviwf1961f72017-09-18 16:41:07 -07001855bool Layer::reparent(const sp<IBinder>& newParentHandle) {
1856 if (newParentHandle == nullptr) {
chaviw06178942017-07-27 10:25:59 -07001857 return false;
1858 }
1859
1860 auto handle = static_cast<Handle*>(newParentHandle.get());
1861 sp<Layer> newParent = handle->owner.promote();
1862 if (newParent == nullptr) {
1863 ALOGE("Unable to promote Layer handle");
1864 return false;
1865 }
1866
chaviwf1961f72017-09-18 16:41:07 -07001867 sp<Layer> parent = getParent();
1868 if (parent != nullptr) {
1869 parent->removeChild(this);
chaviw06178942017-07-27 10:25:59 -07001870 }
chaviwf1961f72017-09-18 16:41:07 -07001871 newParent->addChild(this);
chaviw06178942017-07-27 10:25:59 -07001872
chaviwf1961f72017-09-18 16:41:07 -07001873 sp<Client> client(mClientRef.promote());
chaviw06178942017-07-27 10:25:59 -07001874 sp<Client> newParentClient(newParent->mClientRef.promote());
1875
chaviwf1961f72017-09-18 16:41:07 -07001876 if (client != newParentClient) {
1877 client->setParentLayer(newParent);
chaviw06178942017-07-27 10:25:59 -07001878 }
1879
chaviw06178942017-07-27 10:25:59 -07001880 return true;
1881}
1882
Robert Carr9524cb32017-02-13 11:32:32 -08001883bool Layer::detachChildren() {
Dan Stoza412903f2017-04-27 13:42:17 -07001884 traverseInZOrder(LayerVector::StateSet::Drawing, [this](Layer* child) {
Robert Carr9524cb32017-02-13 11:32:32 -08001885 if (child == this) {
1886 return;
1887 }
1888
chaviw161410b02017-07-27 10:46:08 -07001889 sp<Client> parentClient = mClientRef.promote();
Robert Carr9524cb32017-02-13 11:32:32 -08001890 sp<Client> client(child->mClientRef.promote());
chaviw161410b02017-07-27 10:46:08 -07001891 if (client != nullptr && parentClient != client) {
Robert Carr9524cb32017-02-13 11:32:32 -08001892 client->detachLayer(child);
1893 }
1894 });
1895
1896 return true;
1897}
1898
Robert Carr1f0a16a2016-10-24 16:27:39 -07001899void Layer::setParent(const sp<Layer>& layer) {
Chia-I Wue41dbe62017-06-13 14:10:56 -07001900 mCurrentParent = layer;
Robert Carr1f0a16a2016-10-24 16:27:39 -07001901}
1902
1903void Layer::clearSyncPoints() {
1904 for (const auto& child : mCurrentChildren) {
1905 child->clearSyncPoints();
1906 }
1907
1908 Mutex::Autolock lock(mLocalSyncPointMutex);
1909 for (auto& point : mLocalSyncPoints) {
1910 point->setFrameAvailable();
1911 }
1912 mLocalSyncPoints.clear();
1913}
1914
1915int32_t Layer::getZ() const {
1916 return mDrawingState.z;
1917}
1918
David Sodman41fdfc92017-11-06 16:09:56 -08001919__attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList(
1920 LayerVector::StateSet stateSet) {
Dan Stoza412903f2017-04-27 13:42:17 -07001921 LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
1922 "makeTraversalList received invalid stateSet");
1923 const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
1924 const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
1925 const State& state = useDrawing ? mDrawingState : mCurrentState;
1926
1927 if (state.zOrderRelatives.size() == 0) {
1928 return children;
Robert Carrdb66e622017-04-10 16:55:57 -07001929 }
1930 LayerVector traverse;
1931
Dan Stoza412903f2017-04-27 13:42:17 -07001932 for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
Robert Carrdb66e622017-04-10 16:55:57 -07001933 sp<Layer> strongRelative = weakRelative.promote();
1934 if (strongRelative != nullptr) {
1935 traverse.add(strongRelative);
Robert Carrdb66e622017-04-10 16:55:57 -07001936 }
1937 }
1938
Dan Stoza412903f2017-04-27 13:42:17 -07001939 for (const sp<Layer>& child : children) {
Robert Carrdb66e622017-04-10 16:55:57 -07001940 traverse.add(child);
1941 }
1942
1943 return traverse;
1944}
1945
Robert Carr1f0a16a2016-10-24 16:27:39 -07001946/**
Robert Carrdb66e622017-04-10 16:55:57 -07001947 * Negatively signed relatives are before 'this' in Z-order.
Robert Carr1f0a16a2016-10-24 16:27:39 -07001948 */
Dan Stoza412903f2017-04-27 13:42:17 -07001949void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {
1950 LayerVector list = makeTraversalList(stateSet);
Robert Carrdb66e622017-04-10 16:55:57 -07001951
Robert Carr1f0a16a2016-10-24 16:27:39 -07001952 size_t i = 0;
Robert Carrdb66e622017-04-10 16:55:57 -07001953 for (; i < list.size(); i++) {
1954 const auto& relative = list[i];
1955 if (relative->getZ() >= 0) {
Robert Carr1f0a16a2016-10-24 16:27:39 -07001956 break;
Robert Carrdb66e622017-04-10 16:55:57 -07001957 }
Dan Stoza412903f2017-04-27 13:42:17 -07001958 relative->traverseInZOrder(stateSet, visitor);
Robert Carr1f0a16a2016-10-24 16:27:39 -07001959 }
Dan Stoza412903f2017-04-27 13:42:17 -07001960 visitor(this);
Robert Carrdb66e622017-04-10 16:55:57 -07001961 for (; i < list.size(); i++) {
1962 const auto& relative = list[i];
Dan Stoza412903f2017-04-27 13:42:17 -07001963 relative->traverseInZOrder(stateSet, visitor);
Robert Carr1f0a16a2016-10-24 16:27:39 -07001964 }
1965}
1966
1967/**
Robert Carrdb66e622017-04-10 16:55:57 -07001968 * Positively signed relatives are before 'this' in reverse Z-order.
Robert Carr1f0a16a2016-10-24 16:27:39 -07001969 */
Dan Stoza412903f2017-04-27 13:42:17 -07001970void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet,
1971 const LayerVector::Visitor& visitor) {
1972 LayerVector list = makeTraversalList(stateSet);
Robert Carrdb66e622017-04-10 16:55:57 -07001973
Robert Carr1f0a16a2016-10-24 16:27:39 -07001974 int32_t i = 0;
David Sodman41fdfc92017-11-06 16:09:56 -08001975 for (i = list.size() - 1; i >= 0; i--) {
Robert Carrdb66e622017-04-10 16:55:57 -07001976 const auto& relative = list[i];
1977 if (relative->getZ() < 0) {
Robert Carr1f0a16a2016-10-24 16:27:39 -07001978 break;
1979 }
Dan Stoza412903f2017-04-27 13:42:17 -07001980 relative->traverseInReverseZOrder(stateSet, visitor);
Robert Carr1f0a16a2016-10-24 16:27:39 -07001981 }
Dan Stoza412903f2017-04-27 13:42:17 -07001982 visitor(this);
David Sodman41fdfc92017-11-06 16:09:56 -08001983 for (; i >= 0; i--) {
Robert Carrdb66e622017-04-10 16:55:57 -07001984 const auto& relative = list[i];
Dan Stoza412903f2017-04-27 13:42:17 -07001985 relative->traverseInReverseZOrder(stateSet, visitor);
Robert Carr1f0a16a2016-10-24 16:27:39 -07001986 }
1987}
1988
chaviwa76b2712017-09-20 12:02:26 -07001989/**
1990 * Traverse only children in z order, ignoring relative layers.
1991 */
1992void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet,
1993 const LayerVector::Visitor& visitor) {
1994 const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
1995 const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
1996
1997 size_t i = 0;
1998 for (; i < children.size(); i++) {
1999 const auto& relative = children[i];
2000 if (relative->getZ() >= 0) {
2001 break;
2002 }
2003 relative->traverseChildrenInZOrder(stateSet, visitor);
2004 }
2005 visitor(this);
2006 for (; i < children.size(); i++) {
2007 const auto& relative = children[i];
2008 relative->traverseChildrenInZOrder(stateSet, visitor);
2009 }
2010}
2011
Robert Carr1f0a16a2016-10-24 16:27:39 -07002012Transform Layer::getTransform() const {
2013 Transform t;
Chia-I Wue41dbe62017-06-13 14:10:56 -07002014 const auto& p = mDrawingParent.promote();
Robert Carr1f0a16a2016-10-24 16:27:39 -07002015 if (p != nullptr) {
2016 t = p->getTransform();
Robert Carr9b429f42017-04-17 14:56:57 -07002017
2018 // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
2019 // it isFixedSize) then there may be additional scaling not accounted
2020 // for in the transform. We need to mirror this scaling in child surfaces
2021 // or we will break the contract where WM can treat child surfaces as
2022 // pixels in the parent surface.
Chia-I Wu0a68b462017-07-18 11:30:05 -07002023 if (p->isFixedSize() && p->mActiveBuffer != nullptr) {
Robert Carr1725eee2017-04-26 18:32:15 -07002024 int bufferWidth;
2025 int bufferHeight;
2026 if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) {
2027 bufferWidth = p->mActiveBuffer->getWidth();
2028 bufferHeight = p->mActiveBuffer->getHeight();
2029 } else {
2030 bufferHeight = p->mActiveBuffer->getWidth();
2031 bufferWidth = p->mActiveBuffer->getHeight();
2032 }
David Sodman41fdfc92017-11-06 16:09:56 -08002033 float sx = p->getDrawingState().active.w / static_cast<float>(bufferWidth);
2034 float sy = p->getDrawingState().active.h / static_cast<float>(bufferHeight);
Robert Carr9b429f42017-04-17 14:56:57 -07002035 Transform extraParentScaling;
2036 extraParentScaling.set(sx, 0, 0, sy);
2037 t = t * extraParentScaling;
2038 }
Robert Carr1f0a16a2016-10-24 16:27:39 -07002039 }
2040 return t * getDrawingState().active.transform;
2041}
2042
chaviw13fdc492017-06-27 12:40:18 -07002043half Layer::getAlpha() const {
Chia-I Wue41dbe62017-06-13 14:10:56 -07002044 const auto& p = mDrawingParent.promote();
Robert Carr6452f122017-03-21 10:41:29 -07002045
chaviw13fdc492017-06-27 12:40:18 -07002046 half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
2047 return parentAlpha * getDrawingState().color.a;
Robert Carr6452f122017-03-21 10:41:29 -07002048}
Robert Carr6452f122017-03-21 10:41:29 -07002049
chaviw13fdc492017-06-27 12:40:18 -07002050half4 Layer::getColor() const {
2051 const half4 color(getDrawingState().color);
2052 return half4(color.r, color.g, color.b, getAlpha());
Robert Carr6452f122017-03-21 10:41:29 -07002053}
Robert Carr6452f122017-03-21 10:41:29 -07002054
Robert Carr1f0a16a2016-10-24 16:27:39 -07002055void Layer::commitChildList() {
2056 for (size_t i = 0; i < mCurrentChildren.size(); i++) {
2057 const auto& child = mCurrentChildren[i];
2058 child->commitChildList();
2059 }
2060 mDrawingChildren = mCurrentChildren;
Chia-I Wue41dbe62017-06-13 14:10:56 -07002061 mDrawingParent = mCurrentParent;
Robert Carr1f0a16a2016-10-24 16:27:39 -07002062}
2063
chaviw1d044282017-09-27 12:19:28 -07002064void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
2065 const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
2066 const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
2067 const State& state = useDrawing ? mDrawingState : mCurrentState;
2068
2069 Transform requestedTransform = state.active.transform;
2070 Transform transform = getTransform();
2071
2072 layerInfo->set_id(sequence);
2073 layerInfo->set_name(getName().c_str());
2074 layerInfo->set_type(String8(getTypeId()));
2075
2076 for (const auto& child : children) {
2077 layerInfo->add_children(child->sequence);
2078 }
2079
2080 for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
2081 sp<Layer> strongRelative = weakRelative.promote();
2082 if (strongRelative != nullptr) {
2083 layerInfo->add_relatives(strongRelative->sequence);
2084 }
2085 }
2086
2087 LayerProtoHelper::writeToProto(state.activeTransparentRegion,
2088 layerInfo->mutable_transparent_region());
2089 LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
2090 LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
2091
2092 layerInfo->set_layer_stack(getLayerStack());
2093 layerInfo->set_z(state.z);
2094
2095 PositionProto* position = layerInfo->mutable_position();
2096 position->set_x(transform.tx());
2097 position->set_y(transform.ty());
2098
2099 PositionProto* requestedPosition = layerInfo->mutable_requested_position();
2100 requestedPosition->set_x(requestedTransform.tx());
2101 requestedPosition->set_y(requestedTransform.ty());
2102
2103 SizeProto* size = layerInfo->mutable_size();
2104 size->set_w(state.active.w);
2105 size->set_h(state.active.h);
2106
2107 LayerProtoHelper::writeToProto(state.crop, layerInfo->mutable_crop());
2108 LayerProtoHelper::writeToProto(state.finalCrop, layerInfo->mutable_final_crop());
2109
2110 layerInfo->set_is_opaque(isOpaque(state));
2111 layerInfo->set_invalidate(contentDirty);
2112 layerInfo->set_dataspace(dataspaceDetails(getDataSpace()));
2113 layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
2114 LayerProtoHelper::writeToProto(getColor(), layerInfo->mutable_color());
2115 LayerProtoHelper::writeToProto(state.color, layerInfo->mutable_requested_color());
2116 layerInfo->set_flags(state.flags);
2117
2118 LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
2119 LayerProtoHelper::writeToProto(requestedTransform, layerInfo->mutable_requested_transform());
2120
2121 auto parent = getParent();
2122 if (parent != nullptr) {
2123 layerInfo->set_parent(parent->sequence);
2124 }
2125
2126 auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
2127 if (zOrderRelativeOf != nullptr) {
2128 layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
2129 }
2130
2131 auto activeBuffer = getActiveBuffer();
2132 if (activeBuffer != nullptr) {
2133 LayerProtoHelper::writeToProto(activeBuffer, layerInfo->mutable_active_buffer());
2134 }
2135
2136 layerInfo->set_queued_frames(getQueuedFrameCount());
2137 layerInfo->set_refresh_pending(isBufferLatched());
2138}
2139
Mathias Agopian13127d82013-03-05 17:47:11 -08002140// ---------------------------------------------------------------------------
2141
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002142}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002143
2144#if defined(__gl_h_)
2145#error "don't include gl/gl.h in this file"
2146#endif
2147
2148#if defined(__gl2_h_)
2149#error "don't include gl2/gl2.h in this file"
2150#endif