blob: 910aeae3df158e2dd24c4d99bf37893eb92b0a1d [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dan Stoza9e56aa02015-11-02 13:00:03 -080017//#define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "Layer"
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080020#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080022#include <stdlib.h>
23#include <stdint.h>
24#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080025#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026
Mathias Agopiana67932f2011-04-20 14:20:59 -070027#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070028#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070029#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080030
31#include <utils/Errors.h>
32#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080033#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080035#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080036
Mathias Agopian3330b202009-10-05 17:07:12 -070037#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080039
Dan Stoza6b9454d2014-11-07 16:00:59 -080040#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080041#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042
43#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020044#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070045#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070047#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049
Mathias Agopian1b031492012-06-20 17:51:20 -070050#include "DisplayHardware/HWComposer.h"
51
Mathias Agopian875d8e12013-06-07 15:35:48 -070052#include "RenderEngine/RenderEngine.h"
53
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080054#define DEBUG_RESIZE 0
55
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080056namespace android {
57
58// ---------------------------------------------------------------------------
59
Mathias Agopian13127d82013-03-05 17:47:11 -080060int32_t Layer::sSequence = 1;
61
Mathias Agopian4d9b8222013-03-12 17:11:48 -070062Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
63 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080064 : contentDirty(false),
65 sequence(uint32_t(android_atomic_inc(&sSequence))),
66 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070067 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mPremultipliedAlpha(true),
69 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080070 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080071 mTransactionFlags(0),
Dan Stoza7dde5992015-05-22 09:51:44 -070072 mPendingStateMutex(),
73 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070074 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080075 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070076 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070077 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070078 mCurrentOpacity(true),
Dan Stozacac35382016-01-27 12:21:06 -080079 mCurrentFrameNumber(0),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080080 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080081 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080082 mFiltering(false),
83 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070084 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080085 mProtectedByApp(false),
86 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070087 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070088 mPotentialCursor(false),
89 mQueueItemLock(),
90 mQueueItemCondition(),
91 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070092 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080093 mUpdateTexImageFailed(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080094 mAutoRefresh(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080095{
Dan Stoza9e56aa02015-11-02 13:00:03 -080096#ifdef USE_HWC2
97 ALOGV("Creating Layer %s", name.string());
98#endif
99
Mathias Agopiana67932f2011-04-20 14:20:59 -0700100 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -0700101 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -0700102 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700103
104 uint32_t layerFlags = 0;
105 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -0800106 layerFlags |= layer_state_t::eLayerHidden;
107 if (flags & ISurfaceComposerClient::eOpaque)
108 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700109 if (flags & ISurfaceComposerClient::eSecure)
110 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700111
112 if (flags & ISurfaceComposerClient::eNonPremultiplied)
113 mPremultipliedAlpha = false;
114
115 mName = name;
116
117 mCurrentState.active.w = w;
118 mCurrentState.active.h = h;
Robert Carr3dcabfa2016-03-01 18:36:58 -0800119 mCurrentState.active.transform.set(0, 0);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700120 mCurrentState.active.crop.makeInvalid();
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000121 mCurrentState.active.finalCrop.makeInvalid();
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700122 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800123#ifdef USE_HWC2
124 mCurrentState.alpha = 1.0f;
125#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700126 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800127#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700128 mCurrentState.layerStack = 0;
129 mCurrentState.flags = layerFlags;
130 mCurrentState.sequence = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700131 mCurrentState.requested = mCurrentState.active;
132
133 // drawing state & current state are identical
134 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700135
Dan Stoza9e56aa02015-11-02 13:00:03 -0800136#ifdef USE_HWC2
137 const auto& hwc = flinger->getHwComposer();
138 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
139 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
140#else
Jamie Gennis6547ff42013-07-16 20:12:42 -0700141 nsecs_t displayPeriod =
142 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800143#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700144 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800145}
146
Mathias Agopian3f844832013-08-07 21:24:32 -0700147void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800148 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700149 sp<IGraphicBufferProducer> producer;
150 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700151 BufferQueue::createBufferQueue(&producer, &consumer);
152 mProducer = new MonitoredProducer(producer, mFlinger);
153 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800154 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800155 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700156 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800157
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700158#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
159#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700160#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700161 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800162#endif
Andy McFadden69052052012-09-14 16:10:11 -0700163
Mathias Agopian84300952012-11-21 16:02:13 -0800164 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
165 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700166}
167
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700168Layer::~Layer() {
Pablo Ceballos8ea4e7b2016-03-03 15:20:02 -0800169 sp<Client> c(mClientRef.promote());
170 if (c != 0) {
171 c->detachLayer(this);
172 }
173
Dan Stozacac35382016-01-27 12:21:06 -0800174 for (auto& point : mRemoteSyncPoints) {
175 point->setTransactionApplied();
176 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700177 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700178 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700179}
180
Mathias Agopian13127d82013-03-05 17:47:11 -0800181// ---------------------------------------------------------------------------
182// callbacks
183// ---------------------------------------------------------------------------
184
Dan Stoza9e56aa02015-11-02 13:00:03 -0800185#ifdef USE_HWC2
186void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
187 if (mHwcLayers.empty()) {
188 return;
189 }
190 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
191}
192#else
Dan Stozac7014012014-02-14 15:03:43 -0800193void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800194 HWComposer::HWCLayerInterface* layer) {
195 if (layer) {
196 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700197 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800198 }
199}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800200#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800201
Dan Stoza6b9454d2014-11-07 16:00:59 -0800202void Layer::onFrameAvailable(const BufferItem& item) {
203 // Add this buffer from our internal queue tracker
204 { // Autolock scope
205 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700206
207 // Reset the frame number tracker when we receive the first buffer after
208 // a frame number reset
209 if (item.mFrameNumber == 1) {
210 mLastFrameNumberReceived = 0;
211 }
212
213 // Ensure that callbacks are handled in order
214 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
215 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
216 ms2ns(500));
217 if (result != NO_ERROR) {
218 ALOGE("[%s] Timed out waiting on callback", mName.string());
219 }
220 }
221
Dan Stoza6b9454d2014-11-07 16:00:59 -0800222 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700223 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700224
225 // Wake up any pending callbacks
226 mLastFrameNumberReceived = item.mFrameNumber;
227 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800228 }
229
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800230 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700231}
232
Dan Stoza6b9454d2014-11-07 16:00:59 -0800233void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700234 { // Autolock scope
235 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700236
Dan Stoza7dde5992015-05-22 09:51:44 -0700237 // Ensure that callbacks are handled in order
238 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
239 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
240 ms2ns(500));
241 if (result != NO_ERROR) {
242 ALOGE("[%s] Timed out waiting on callback", mName.string());
243 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700244 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700245
246 if (mQueueItems.empty()) {
247 ALOGE("Can't replace a frame on an empty queue");
248 return;
249 }
250 mQueueItems.editItemAt(0) = item;
251
252 // Wake up any pending callbacks
253 mLastFrameNumberReceived = item.mFrameNumber;
254 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700255 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800256}
257
Jesse Hall399184a2014-03-03 15:42:54 -0800258void Layer::onSidebandStreamChanged() {
259 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
260 // mSidebandStreamChanged was false
261 mFlinger->signalLayerUpdate();
262 }
263}
264
Mathias Agopian67106042013-03-14 19:18:13 -0700265// called with SurfaceFlinger::mStateLock from the drawing thread after
266// the layer has been remove from the current state list (and just before
267// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800268void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800269 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700270}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700271
Mathias Agopian13127d82013-03-05 17:47:11 -0800272// ---------------------------------------------------------------------------
273// set-up
274// ---------------------------------------------------------------------------
275
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700276const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800277 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800278}
279
Mathias Agopianf9d93272009-06-19 17:00:27 -0700280status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800281 PixelFormat format, uint32_t flags)
282{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700283 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700284 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700285
286 // never allow a surface larger than what our underlying GL implementation
287 // can handle.
288 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800289 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700290 return BAD_VALUE;
291 }
292
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700293 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700294
Riley Andrews03414a12014-07-01 14:22:59 -0700295 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700296 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700297 mCurrentOpacity = getOpacityForFormat(format);
298
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800299 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
300 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
301 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700302
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800303 return NO_ERROR;
304}
305
Dan Stoza7dde5992015-05-22 09:51:44 -0700306/*
307 * The layer handle is just a BBinder object passed to the client
308 * (remote process) -- we don't keep any reference on our side such that
309 * the dtor is called when the remote side let go of its reference.
310 *
311 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
312 * this layer when the handle is destroyed.
313 */
314class Layer::Handle : public BBinder, public LayerCleaner {
315 public:
316 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
317 : LayerCleaner(flinger, layer), owner(layer) {}
318
319 wp<Layer> owner;
320};
321
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700322sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800323 Mutex::Autolock _l(mLock);
324
325 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700326 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800327
328 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700329
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700330 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800331}
332
Dan Stozab9b08832014-03-13 11:55:57 -0700333sp<IGraphicBufferProducer> Layer::getProducer() const {
334 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700335}
336
Mathias Agopian13127d82013-03-05 17:47:11 -0800337// ---------------------------------------------------------------------------
338// h/w composer set-up
339// ---------------------------------------------------------------------------
340
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800341Rect Layer::getContentCrop() const {
342 // this is the crop rectangle that applies to the buffer
343 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700344 Rect crop;
345 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800346 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700347 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800348 } else if (mActiveBuffer != NULL) {
349 // otherwise we use the whole buffer
350 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700351 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800352 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700353 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700354 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700355 return crop;
356}
357
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700358static Rect reduce(const Rect& win, const Region& exclude) {
359 if (CC_LIKELY(exclude.isEmpty())) {
360 return win;
361 }
362 if (exclude.isRect()) {
363 return win.reduce(exclude.getBounds());
364 }
365 return Region(win).subtract(exclude).getBounds();
366}
367
Mathias Agopian13127d82013-03-05 17:47:11 -0800368Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700369 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700370 return computeBounds(s.activeTransparentRegion);
371}
372
373Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
374 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800375 Rect win(s.active.w, s.active.h);
376 if (!s.active.crop.isEmpty()) {
377 win.intersect(s.active.crop, &win);
378 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700379 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700380 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800381}
382
Mathias Agopian6b442672013-07-09 21:24:52 -0700383FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800384 // the content crop is the area of the content that gets scaled to the
385 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700386 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800387
388 // the active.crop is the area of the window that gets cropped, but not
389 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700390 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800391
392 // apply the projection's clipping to the window crop in
393 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700394 // if there are no window scaling involved, this operation will map to full
395 // pixels in the buffer.
396 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
397 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700398
399 Rect activeCrop(s.active.w, s.active.h);
400 if (!s.active.crop.isEmpty()) {
401 activeCrop = s.active.crop;
402 }
403
Robert Carr3dcabfa2016-03-01 18:36:58 -0800404 activeCrop = s.active.transform.transform(activeCrop);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000405 if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
406 activeCrop.clear();
407 }
408 if (!s.active.finalCrop.isEmpty()) {
409 if(!activeCrop.intersect(s.active.finalCrop, &activeCrop)) {
410 activeCrop.clear();
411 }
412 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800413 activeCrop = s.active.transform.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;
432 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
433 /*
434 * the code below applies the display's inverse transform to the buffer
435 */
436 uint32_t invTransformOrient = hw->getOrientationTransform();
437 // calculate the inverse transform
438 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
439 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
440 NATIVE_WINDOW_TRANSFORM_FLIP_H;
441 // If the transform has been rotated the axis of flip has been swapped
442 // so we need to swap which flip operations we are performing
Michael Lentine7b902582014-08-19 18:14:06 -0700443 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
444 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000445 if (is_h_flipped != is_v_flipped) {
Michael Lentine7b902582014-08-19 18:14:06 -0700446 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
447 NATIVE_WINDOW_TRANSFORM_FLIP_H;
448 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800449 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000450 // and apply to the current transform
451 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
Mathias Agopian13127d82013-03-05 17:47:11 -0800452 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000453
454 int winWidth = s.active.w;
455 int winHeight = s.active.h;
456 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
457 // If the activeCrop has been rotate the ends are rotated but not
458 // the space itself so when transforming ends back we can't rely on
459 // a modification of the axes of rotation. To account for this we
460 // need to reorient the inverse rotation in terms of the current
461 // axes of rotation.
462 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
463 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
464 if (is_h_flipped == is_v_flipped) {
465 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
466 NATIVE_WINDOW_TRANSFORM_FLIP_H;
467 }
468 winWidth = s.active.h;
469 winHeight = s.active.w;
470 }
471 const Rect winCrop = activeCrop.transform(
472 invTransform, s.active.w, s.active.h);
473
474 // below, crop is intersected with winCrop expressed in crop's coordinate space
475 float xScale = crop.getWidth() / float(winWidth);
476 float yScale = crop.getHeight() / float(winHeight);
477
478 float insetL = winCrop.left * xScale;
479 float insetT = winCrop.top * yScale;
480 float insetR = (winWidth - winCrop.right ) * xScale;
481 float insetB = (winHeight - winCrop.bottom) * yScale;
482
483 crop.left += insetL;
484 crop.top += insetT;
485 crop.right -= insetR;
486 crop.bottom -= insetB;
487
Mathias Agopian13127d82013-03-05 17:47:11 -0800488 return crop;
489}
490
Dan Stoza9e56aa02015-11-02 13:00:03 -0800491#ifdef USE_HWC2
492void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
493#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700494void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700495 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700496 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800497#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700498{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800499#ifdef USE_HWC2
500 const auto hwcId = displayDevice->getHwcDisplayId();
501 auto& hwcInfo = mHwcLayers[hwcId];
502#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800503 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800504#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700505
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700506 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800507#ifdef USE_HWC2
508 hwcInfo.forceClientComposition = false;
509
510 if (isSecure() && !displayDevice->isSecure()) {
511 hwcInfo.forceClientComposition = true;
512 }
513
514 auto& hwcLayer = hwcInfo.layer;
515#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700516 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700517
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700518 if (isSecure() && !hw->isSecure()) {
519 layer.setSkip(true);
520 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800521#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700522
Mathias Agopian13127d82013-03-05 17:47:11 -0800523 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700524 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800525#ifdef USE_HWC2
526 if (!isOpaque(s) || s.alpha != 1.0f) {
527 auto blendMode = mPremultipliedAlpha ?
528 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
529 auto error = hwcLayer->setBlendMode(blendMode);
530 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
531 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
532 to_string(error).c_str(), static_cast<int32_t>(error));
533 }
534#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800535 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800536 layer.setBlending(mPremultipliedAlpha ?
537 HWC_BLENDING_PREMULT :
538 HWC_BLENDING_COVERAGE);
539 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800540#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800541
542 // apply the layer's transform, followed by the display's global transform
543 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700544 Region activeTransparentRegion(s.activeTransparentRegion);
545 if (!s.active.crop.isEmpty()) {
546 Rect activeCrop(s.active.crop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800547 activeCrop = s.active.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800548#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000549 if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800550#else
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000551 if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800552#endif
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000553 activeCrop.clear();
554 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800555 activeCrop = s.active.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800556 // This needs to be here as transform.transform(Rect) computes the
557 // transformed rect and then takes the bounding box of the result before
558 // returning. This means
559 // transform.inverse().transform(transform.transform(Rect)) != Rect
560 // in which case we need to make sure the final rect is clipped to the
561 // display bounds.
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000562 if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
563 activeCrop.clear();
564 }
Michael Lentine6c925ed2014-09-26 17:55:01 -0700565 // mark regions outside the crop as transparent
566 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
567 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
568 s.active.w, s.active.h));
569 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
570 activeCrop.left, activeCrop.bottom));
571 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
572 s.active.w, activeCrop.bottom));
573 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800574 Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000575 if (!s.active.finalCrop.isEmpty()) {
576 if(!frame.intersect(s.active.finalCrop, &frame)) {
577 frame.clear();
578 }
579 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800580#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000581 if (!frame.intersect(displayDevice->getViewport(), &frame)) {
582 frame.clear();
583 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800584 const Transform& tr(displayDevice->getTransform());
585 Rect transformedFrame = tr.transform(frame);
586 auto error = hwcLayer->setDisplayFrame(transformedFrame);
587 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
588 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
589 transformedFrame.top, transformedFrame.right,
590 transformedFrame.bottom, to_string(error).c_str(),
591 static_cast<int32_t>(error));
592
593 FloatRect sourceCrop = computeCrop(displayDevice);
594 error = hwcLayer->setSourceCrop(sourceCrop);
595 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
596 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
597 sourceCrop.left, sourceCrop.top, sourceCrop.right,
598 sourceCrop.bottom, to_string(error).c_str(),
599 static_cast<int32_t>(error));
600
601 error = hwcLayer->setPlaneAlpha(s.alpha);
602 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
603 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
604 static_cast<int32_t>(error));
605
606 error = hwcLayer->setZOrder(s.z);
607 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
608 mName.string(), s.z, to_string(error).c_str(),
609 static_cast<int32_t>(error));
610#else
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000611 if (!frame.intersect(hw->getViewport(), &frame)) {
612 frame.clear();
613 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800614 const Transform& tr(hw->getTransform());
615 layer.setFrame(tr.transform(frame));
616 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800617 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800618#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800619
Mathias Agopian29a367b2011-07-12 14:51:45 -0700620 /*
621 * Transformations are applied in this order:
622 * 1) buffer orientation/flip/mirror
623 * 2) state transformation (window manager)
624 * 3) layer orientation (screen orientation)
625 * (NOTE: the matrices are multiplied in reverse order)
626 */
627
628 const Transform bufferOrientation(mCurrentTransform);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800629 Transform transform(tr * s.active.transform * bufferOrientation);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700630
631 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
632 /*
633 * the code below applies the display's inverse transform to the buffer
634 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800635#ifdef USE_HWC2
636 uint32_t invTransform = displayDevice->getOrientationTransform();
637#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700638 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800639#endif
Michael Lentine14409632014-08-19 11:27:30 -0700640 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700641 // calculate the inverse transform
642 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
643 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
644 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700645 // If the transform has been rotated the axis of flip has been swapped
646 // so we need to swap which flip operations we are performing
647 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
648 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
649 if (is_h_flipped != is_v_flipped) {
650 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
651 NATIVE_WINDOW_TRANSFORM_FLIP_H;
652 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700653 }
654 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700655 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700656 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700657
658 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800659 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800660#ifdef USE_HWC2
661 if (orientation & Transform::ROT_INVALID) {
662 // we can only handle simple transformation
663 hwcInfo.forceClientComposition = true;
664 } else {
665 auto transform = static_cast<HWC2::Transform>(orientation);
666 auto error = hwcLayer->setTransform(transform);
667 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
668 "%s (%d)", mName.string(), to_string(transform).c_str(),
669 to_string(error).c_str(), static_cast<int32_t>(error));
670 }
671#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800672 if (orientation & Transform::ROT_INVALID) {
673 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700674 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700675 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800676 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700677 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800678#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700679}
680
Dan Stoza9e56aa02015-11-02 13:00:03 -0800681#ifdef USE_HWC2
682void Layer::forceClientComposition(int32_t hwcId) {
683 if (mHwcLayers.count(hwcId) == 0) {
684 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
685 return;
686 }
687
688 mHwcLayers[hwcId].forceClientComposition = true;
689}
690#endif
691
692#ifdef USE_HWC2
693void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
694 // Apply this display's projection's viewport to the visible region
695 // before giving it to the HWC HAL.
696 const Transform& tr = displayDevice->getTransform();
697 const auto& viewport = displayDevice->getViewport();
698 Region visible = tr.transform(visibleRegion.intersect(viewport));
699 auto hwcId = displayDevice->getHwcDisplayId();
700 auto& hwcLayer = mHwcLayers[hwcId].layer;
701 auto error = hwcLayer->setVisibleRegion(visible);
702 if (error != HWC2::Error::None) {
703 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
704 to_string(error).c_str(), static_cast<int32_t>(error));
705 visible.dump(LOG_TAG);
706 }
707
708 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
709 if (error != HWC2::Error::None) {
710 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
711 to_string(error).c_str(), static_cast<int32_t>(error));
712 surfaceDamageRegion.dump(LOG_TAG);
713 }
714
715 auto compositionType = HWC2::Composition::Invalid;
716 if (mSidebandStream.get()) {
717 compositionType = HWC2::Composition::Sideband;
718 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
719 if (error != HWC2::Error::None) {
720 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
721 mName.string(), mSidebandStream->handle(),
722 to_string(error).c_str(), static_cast<int32_t>(error));
723 return;
724 }
725 } else {
726 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
727 compositionType = HWC2::Composition::Client;
728 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
729 if (error != HWC2::Error::None) {
730 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
731 to_string(error).c_str(), static_cast<int32_t>(error));
732 return;
733 }
734 } else {
735 if (mPotentialCursor) {
736 compositionType = HWC2::Composition::Cursor;
737 }
738 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
739 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
740 acquireFence);
741 if (error != HWC2::Error::None) {
742 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
743 mActiveBuffer->handle, to_string(error).c_str(),
744 static_cast<int32_t>(error));
745 return;
746 }
747 // If it's not a cursor, default to device composition
748 }
749 }
750
751 if (mHwcLayers[hwcId].forceClientComposition) {
752 ALOGV("[%s] Forcing Client composition", mName.string());
753 setCompositionType(hwcId, HWC2::Composition::Client);
754 } else if (compositionType != HWC2::Composition::Invalid) {
755 ALOGV("[%s] Requesting %s composition", mName.string(),
756 to_string(compositionType).c_str());
757 setCompositionType(hwcId, compositionType);
758 } else {
759 ALOGV("[%s] Requesting Device composition", mName.string());
760 setCompositionType(hwcId, HWC2::Composition::Device);
761 }
762}
763#else
Mathias Agopian42977342012-08-05 00:40:46 -0700764void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700765 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800766 // we have to set the visible region on every frame because
767 // we currently free it during onLayerDisplayed(), which is called
768 // after HWComposer::commit() -- every frame.
769 // Apply this display's projection's viewport to the visible region
770 // before giving it to the HWC HAL.
771 const Transform& tr = hw->getTransform();
772 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
773 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700774 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700775
Jesse Hall399184a2014-03-03 15:42:54 -0800776 if (mSidebandStream.get()) {
777 layer.setSidebandStream(mSidebandStream);
778 } else {
779 // NOTE: buffer can be NULL if the client never drew into this
780 // layer yet, or if we ran out of memory
781 layer.setBuffer(mActiveBuffer);
782 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700783}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800784#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700785
Dan Stoza9e56aa02015-11-02 13:00:03 -0800786#ifdef USE_HWC2
787void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
788 auto hwcId = displayDevice->getHwcDisplayId();
789 if (mHwcLayers.count(hwcId) == 0 ||
790 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
791 return;
792 }
793
794 // This gives us only the "orientation" component of the transform
795 const State& s(getCurrentState());
796
797 // Apply the layer's transform, followed by the display's global transform
798 // Here we're guaranteed that the layer's transform preserves rects
799 Rect win(s.active.w, s.active.h);
800 if (!s.active.crop.isEmpty()) {
801 win.intersect(s.active.crop, &win);
802 }
803 // Subtract the transparent region and snap to the bounds
804 Rect bounds = reduce(win, s.activeTransparentRegion);
Dan Stozabaf416d2016-03-10 11:57:08 -0800805 Rect frame(s.active.transform.transform(bounds));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800806 frame.intersect(displayDevice->getViewport(), &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000807 if (!s.active.finalCrop.isEmpty()) {
808 frame.intersect(s.active.finalCrop, &frame);
809 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800810 auto& displayTransform(displayDevice->getTransform());
811 auto position = displayTransform.transform(frame);
812
813 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
814 position.top);
815 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
816 "to (%d, %d): %s (%d)", mName.string(), position.left,
817 position.top, to_string(error).c_str(),
818 static_cast<int32_t>(error));
819}
820#else
Dan Stozac7014012014-02-14 15:03:43 -0800821void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700822 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700823 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700824
825 // TODO: there is a possible optimization here: we only need to set the
826 // acquire fence the first time a new buffer is acquired on EACH display.
827
Riley Andrews03414a12014-07-01 14:22:59 -0700828 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800829 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800830 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700831 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700832 if (fenceFd == -1) {
833 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
834 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700835 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700836 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700837 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700838}
839
Riley Andrews03414a12014-07-01 14:22:59 -0700840Rect Layer::getPosition(
841 const sp<const DisplayDevice>& hw)
842{
843 // this gives us only the "orientation" component of the transform
844 const State& s(getCurrentState());
845
846 // apply the layer's transform, followed by the display's global transform
847 // here we're guaranteed that the layer's transform preserves rects
848 Rect win(s.active.w, s.active.h);
849 if (!s.active.crop.isEmpty()) {
850 win.intersect(s.active.crop, &win);
851 }
852 // subtract the transparent region and snap to the bounds
853 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800854 Rect frame(s.active.transform.transform(bounds));
Riley Andrews03414a12014-07-01 14:22:59 -0700855 frame.intersect(hw->getViewport(), &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000856 if (!s.active.finalCrop.isEmpty()) {
857 frame.intersect(s.active.finalCrop, &frame);
858 }
Riley Andrews03414a12014-07-01 14:22:59 -0700859 const Transform& tr(hw->getTransform());
860 return Rect(tr.transform(frame));
861}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800862#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700863
Mathias Agopian13127d82013-03-05 17:47:11 -0800864// ---------------------------------------------------------------------------
865// drawing...
866// ---------------------------------------------------------------------------
867
868void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800869 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800870}
871
Dan Stozac7014012014-02-14 15:03:43 -0800872void Layer::draw(const sp<const DisplayDevice>& hw,
873 bool useIdentityTransform) const {
874 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800875}
876
Dan Stozac7014012014-02-14 15:03:43 -0800877void Layer::draw(const sp<const DisplayDevice>& hw) const {
878 onDraw(hw, Region(hw->bounds()), false);
879}
880
881void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
882 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800883{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800884 ATRACE_CALL();
885
Mathias Agopiana67932f2011-04-20 14:20:59 -0700886 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800887 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700888 // in fact never been drawn into. This happens frequently with
889 // SurfaceView because the WindowManager can't know when the client
890 // has drawn the first time.
891
892 // If there is nothing under us, we paint the screen in black, otherwise
893 // we just skip this update.
894
895 // figure out if there is something below us
896 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700897 const SurfaceFlinger::LayerVector& drawingLayers(
898 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700899 const size_t count = drawingLayers.size();
900 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800901 const sp<Layer>& layer(drawingLayers[i]);
902 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700903 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700904 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700905 }
906 // if not everything below us is covered, we plug the holes!
907 Region holes(clip.subtract(under));
908 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700909 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700910 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800911 return;
912 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700913
Andy McFadden97eba892012-12-11 15:21:45 -0800914 // Bind the current buffer to the GL texture, and wait for it to be
915 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800916 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
917 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800918 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700919 // Go ahead and draw the buffer anyway; no matter what we do the screen
920 // is probably going to have something visibly wrong.
921 }
922
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700923 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
924
Mathias Agopian875d8e12013-06-07 15:35:48 -0700925 RenderEngine& engine(mFlinger->getRenderEngine());
926
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700927 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700928 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700929 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700930
931 // Query the texture matrix given our current filtering mode.
932 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800933 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
934 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700935
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700936 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
937
938 /*
939 * the code below applies the display's inverse transform to the texture transform
940 */
941
942 // create a 4x4 transform matrix from the display transform flags
943 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
944 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
945 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
946
947 mat4 tr;
948 uint32_t transform = hw->getOrientationTransform();
949 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
950 tr = tr * rot90;
951 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
952 tr = tr * flipH;
953 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
954 tr = tr * flipV;
955
956 // calculate the inverse
957 tr = inverse(tr);
958
959 // and finally apply it to the original texture matrix
960 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
961 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
962 }
963
Jamie Genniscbb1a952012-05-08 17:05:52 -0700964 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700965 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
966 mTexture.setFiltering(useFiltering);
967 mTexture.setMatrix(textureMatrix);
968
969 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700970 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700971 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700972 }
Dan Stozac7014012014-02-14 15:03:43 -0800973 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700974 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800975}
976
Mathias Agopian13127d82013-03-05 17:47:11 -0800977
Dan Stozac7014012014-02-14 15:03:43 -0800978void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
979 const Region& /* clip */, float red, float green, float blue,
980 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800981{
Mathias Agopian19733a32013-08-28 18:13:56 -0700982 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800983 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700984 engine.setupFillWithColor(red, green, blue, alpha);
985 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800986}
987
988void Layer::clearWithOpenGL(
989 const sp<const DisplayDevice>& hw, const Region& clip) const {
990 clearWithOpenGL(hw, clip, 0,0,0,0);
991}
992
Dan Stozac7014012014-02-14 15:03:43 -0800993void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
994 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700995 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800996
Dan Stozac7014012014-02-14 15:03:43 -0800997 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800998
Mathias Agopian13127d82013-03-05 17:47:11 -0800999 /*
1000 * NOTE: the way we compute the texture coordinates here produces
1001 * different results than when we take the HWC path -- in the later case
1002 * the "source crop" is rounded to texel boundaries.
1003 * This can produce significantly different results when the texture
1004 * is scaled by a large amount.
1005 *
1006 * The GL code below is more logical (imho), and the difference with
1007 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -07001008 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -08001009 * GL composition when a buffer scaling is applied (maybe with some
1010 * minimal value)? Or, we could make GL behave like HWC -- but this feel
1011 * like more of a hack.
1012 */
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001013 Rect win(computeBounds());
1014
1015 if (!s.active.finalCrop.isEmpty()) {
1016 win = s.active.transform.transform(win);
1017 if (!win.intersect(s.active.finalCrop, &win)) {
1018 win.clear();
1019 }
1020 win = s.active.transform.inverse().transform(win);
1021 if (!win.intersect(computeBounds(), &win)) {
1022 win.clear();
1023 }
1024 }
Mathias Agopian13127d82013-03-05 17:47:11 -08001025
Mathias Agopian3f844832013-08-07 21:24:32 -07001026 float left = float(win.left) / float(s.active.w);
1027 float top = float(win.top) / float(s.active.h);
1028 float right = float(win.right) / float(s.active.w);
1029 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -08001030
Mathias Agopian875d8e12013-06-07 15:35:48 -07001031 // TODO: we probably want to generate the texture coords with the mesh
1032 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -07001033 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1034 texCoords[0] = vec2(left, 1.0f - top);
1035 texCoords[1] = vec2(left, 1.0f - bottom);
1036 texCoords[2] = vec2(right, 1.0f - bottom);
1037 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -08001038
Mathias Agopian875d8e12013-06-07 15:35:48 -07001039 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -08001040 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001041 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001042 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001043}
1044
Dan Stoza9e56aa02015-11-02 13:00:03 -08001045#ifdef USE_HWC2
1046void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1047 bool callIntoHwc) {
1048 if (mHwcLayers.count(hwcId) == 0) {
1049 ALOGE("setCompositionType called without a valid HWC layer");
1050 return;
1051 }
1052 auto& hwcInfo = mHwcLayers[hwcId];
1053 auto& hwcLayer = hwcInfo.layer;
1054 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1055 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1056 if (hwcInfo.compositionType != type) {
1057 ALOGV(" actually setting");
1058 hwcInfo.compositionType = type;
1059 if (callIntoHwc) {
1060 auto error = hwcLayer->setCompositionType(type);
1061 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1062 "composition type %s: %s (%d)", mName.string(),
1063 to_string(type).c_str(), to_string(error).c_str(),
1064 static_cast<int32_t>(error));
1065 }
1066 }
1067}
1068
1069HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1070 if (mHwcLayers.count(hwcId) == 0) {
1071 ALOGE("getCompositionType called without a valid HWC layer");
1072 return HWC2::Composition::Invalid;
1073 }
1074 return mHwcLayers.at(hwcId).compositionType;
1075}
1076
1077void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1078 if (mHwcLayers.count(hwcId) == 0) {
1079 ALOGE("setClearClientTarget called without a valid HWC layer");
1080 return;
1081 }
1082 mHwcLayers[hwcId].clearClientTarget = clear;
1083}
1084
1085bool Layer::getClearClientTarget(int32_t hwcId) const {
1086 if (mHwcLayers.count(hwcId) == 0) {
1087 ALOGE("getClearClientTarget called without a valid HWC layer");
1088 return false;
1089 }
1090 return mHwcLayers.at(hwcId).clearClientTarget;
1091}
1092#endif
1093
Ruben Brunk1681d952014-06-27 15:51:55 -07001094uint32_t Layer::getProducerStickyTransform() const {
1095 int producerStickyTransform = 0;
1096 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1097 if (ret != OK) {
1098 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1099 strerror(-ret), ret);
1100 return 0;
1101 }
1102 return static_cast<uint32_t>(producerStickyTransform);
1103}
1104
Dan Stozacac35382016-01-27 12:21:06 -08001105uint64_t Layer::getHeadFrameNumber() const {
1106 Mutex::Autolock lock(mQueueItemLock);
1107 if (!mQueueItems.empty()) {
1108 return mQueueItems[0].mFrameNumber;
1109 } else {
1110 return mCurrentFrameNumber;
1111 }
1112}
1113
1114bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1115 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1116 // Don't bother with a SyncPoint, since we've already latched the
1117 // relevant frame
1118 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001119 }
1120
Dan Stozacac35382016-01-27 12:21:06 -08001121 Mutex::Autolock lock(mLocalSyncPointMutex);
1122 mLocalSyncPoints.push_back(point);
1123 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001124}
1125
Mathias Agopian13127d82013-03-05 17:47:11 -08001126void Layer::setFiltering(bool filtering) {
1127 mFiltering = filtering;
1128}
1129
1130bool Layer::getFiltering() const {
1131 return mFiltering;
1132}
1133
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001134// As documented in libhardware header, formats in the range
1135// 0x100 - 0x1FF are specific to the HAL implementation, and
1136// are known to have no alpha channel
1137// TODO: move definition for device-specific range into
1138// hardware.h, instead of using hard-coded values here.
1139#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1140
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001141bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001142 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1143 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001144 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001145 switch (format) {
1146 case HAL_PIXEL_FORMAT_RGBA_8888:
1147 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001148 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001149 }
1150 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001151 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001152}
1153
Mathias Agopian13127d82013-03-05 17:47:11 -08001154// ----------------------------------------------------------------------------
1155// local state
1156// ----------------------------------------------------------------------------
1157
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001158static void boundPoint(vec2* point, const Rect& crop) {
1159 if (point->x < crop.left) {
1160 point->x = crop.left;
1161 }
1162 if (point->x > crop.right) {
1163 point->x = crop.right;
1164 }
1165 if (point->y < crop.top) {
1166 point->y = crop.top;
1167 }
1168 if (point->y > crop.bottom) {
1169 point->y = crop.bottom;
1170 }
1171}
1172
Dan Stozac7014012014-02-14 15:03:43 -08001173void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1174 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001175{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001176 const Layer::State& s(getDrawingState());
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001177 const Transform tr(hw->getTransform());
Mathias Agopian13127d82013-03-05 17:47:11 -08001178 const uint32_t hw_h = hw->getHeight();
1179 Rect win(s.active.w, s.active.h);
1180 if (!s.active.crop.isEmpty()) {
1181 win.intersect(s.active.crop, &win);
1182 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001183 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001184 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001185
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001186 vec2 lt = vec2(win.left, win.top);
1187 vec2 lb = vec2(win.left, win.bottom);
1188 vec2 rb = vec2(win.right, win.bottom);
1189 vec2 rt = vec2(win.right, win.top);
1190
1191 if (!useIdentityTransform) {
1192 lt = s.active.transform.transform(lt);
1193 lb = s.active.transform.transform(lb);
1194 rb = s.active.transform.transform(rb);
1195 rt = s.active.transform.transform(rt);
1196 }
1197
1198 if (!s.active.finalCrop.isEmpty()) {
1199 boundPoint(&lt, s.active.finalCrop);
1200 boundPoint(&lb, s.active.finalCrop);
1201 boundPoint(&rb, s.active.finalCrop);
1202 boundPoint(&rt, s.active.finalCrop);
1203 }
1204
Mathias Agopianff2ed702013-09-01 21:36:12 -07001205 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001206 position[0] = tr.transform(lt);
1207 position[1] = tr.transform(lb);
1208 position[2] = tr.transform(rb);
1209 position[3] = tr.transform(rt);
Mathias Agopian3f844832013-08-07 21:24:32 -07001210 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001211 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001212 }
1213}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001214
Andy McFadden4125a4f2014-01-29 17:17:11 -08001215bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001216{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001217 // if we don't have a buffer yet, we're translucent regardless of the
1218 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001219 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001220 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001221 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001222
1223 // if the layer has the opaque flag, then we're always opaque,
1224 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001225 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001226}
1227
Dan Stoza23116082015-06-18 14:58:39 -07001228bool Layer::isSecure() const
1229{
1230 const Layer::State& s(mDrawingState);
1231 return (s.flags & layer_state_t::eLayerSecure);
1232}
1233
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001234bool Layer::isProtected() const
1235{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001236 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001237 return (activeBuffer != 0) &&
1238 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1239}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001240
Mathias Agopian13127d82013-03-05 17:47:11 -08001241bool Layer::isFixedSize() const {
1242 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1243}
1244
1245bool Layer::isCropped() const {
1246 return !mCurrentCrop.isEmpty();
1247}
1248
1249bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1250 return mNeedsFiltering || hw->needsFiltering();
1251}
1252
1253void Layer::setVisibleRegion(const Region& visibleRegion) {
1254 // always called from main thread
1255 this->visibleRegion = visibleRegion;
1256}
1257
1258void Layer::setCoveredRegion(const Region& coveredRegion) {
1259 // always called from main thread
1260 this->coveredRegion = coveredRegion;
1261}
1262
1263void Layer::setVisibleNonTransparentRegion(const Region&
1264 setVisibleNonTransparentRegion) {
1265 // always called from main thread
1266 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1267}
1268
1269// ----------------------------------------------------------------------------
1270// transaction
1271// ----------------------------------------------------------------------------
1272
Dan Stoza7dde5992015-05-22 09:51:44 -07001273void Layer::pushPendingState() {
1274 if (!mCurrentState.modified) {
1275 return;
1276 }
1277
Dan Stoza7dde5992015-05-22 09:51:44 -07001278 // If this transaction is waiting on the receipt of a frame, generate a sync
1279 // point and send it to the remote layer.
1280 if (mCurrentState.handle != nullptr) {
1281 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1282 sp<Layer> handleLayer = handle->owner.promote();
1283 if (handleLayer == nullptr) {
1284 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1285 // If we can't promote the layer we are intended to wait on,
1286 // then it is expired or otherwise invalid. Allow this transaction
1287 // to be applied as per normal (no synchronization).
1288 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001289 } else {
1290 auto syncPoint = std::make_shared<SyncPoint>(
1291 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001292 if (handleLayer->addSyncPoint(syncPoint)) {
1293 mRemoteSyncPoints.push_back(std::move(syncPoint));
1294 } else {
1295 // We already missed the frame we're supposed to synchronize
1296 // on, so go ahead and apply the state update
1297 mCurrentState.handle = nullptr;
1298 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001299 }
1300
Dan Stoza7dde5992015-05-22 09:51:44 -07001301 // Wake us up to check if the frame has been received
1302 setTransactionFlags(eTransactionNeeded);
1303 }
1304 mPendingStates.push_back(mCurrentState);
1305}
1306
1307void Layer::popPendingState() {
1308 auto oldFlags = mCurrentState.flags;
1309 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001310 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001311 (mCurrentState.flags & mCurrentState.mask);
1312
1313 mPendingStates.removeAt(0);
1314}
1315
1316bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001317 bool stateUpdateAvailable = false;
1318 while (!mPendingStates.empty()) {
1319 if (mPendingStates[0].handle != nullptr) {
1320 if (mRemoteSyncPoints.empty()) {
1321 // If we don't have a sync point for this, apply it anyway. It
1322 // will be visually wrong, but it should keep us from getting
1323 // into too much trouble.
1324 ALOGE("[%s] No local sync point found", mName.string());
1325 popPendingState();
1326 stateUpdateAvailable = true;
1327 continue;
1328 }
1329
Dan Stozacac35382016-01-27 12:21:06 -08001330 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1331 mPendingStates[0].frameNumber) {
1332 ALOGE("[%s] Unexpected sync point frame number found",
1333 mName.string());
1334
1335 // Signal our end of the sync point and then dispose of it
1336 mRemoteSyncPoints.front()->setTransactionApplied();
1337 mRemoteSyncPoints.pop_front();
1338 continue;
1339 }
1340
Dan Stoza7dde5992015-05-22 09:51:44 -07001341 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1342 // Apply the state update
1343 popPendingState();
1344 stateUpdateAvailable = true;
1345
1346 // Signal our end of the sync point and then dispose of it
1347 mRemoteSyncPoints.front()->setTransactionApplied();
1348 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001349 } else {
1350 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001351 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001352 } else {
1353 popPendingState();
1354 stateUpdateAvailable = true;
1355 }
1356 }
1357
1358 // If we still have pending updates, wake SurfaceFlinger back up and point
1359 // it at this layer so we can process them
1360 if (!mPendingStates.empty()) {
1361 setTransactionFlags(eTransactionNeeded);
1362 mFlinger->setTransactionFlags(eTraversalNeeded);
1363 }
1364
1365 mCurrentState.modified = false;
1366 return stateUpdateAvailable;
1367}
1368
1369void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001370 auto headFrameNumber = getHeadFrameNumber();
1371 Mutex::Autolock lock(mLocalSyncPointMutex);
1372 for (auto& point : mLocalSyncPoints) {
1373 if (headFrameNumber >= point->getFrameNumber()) {
1374 point->setFrameAvailable();
1375 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001376 }
1377}
1378
Mathias Agopian13127d82013-03-05 17:47:11 -08001379uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001380 ATRACE_CALL();
1381
Dan Stoza7dde5992015-05-22 09:51:44 -07001382 pushPendingState();
1383 if (!applyPendingStates()) {
1384 return 0;
1385 }
1386
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001387 const Layer::State& s(getDrawingState());
1388 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001389
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001390 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1391 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001392
1393 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001394 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001395 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001396 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001397 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1398 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1399 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1400 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001401 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1402 c.active.w, c.active.h,
1403 c.active.crop.left,
1404 c.active.crop.top,
1405 c.active.crop.right,
1406 c.active.crop.bottom,
1407 c.active.crop.getWidth(),
1408 c.active.crop.getHeight(),
1409 c.requested.w, c.requested.h,
1410 c.requested.crop.left,
1411 c.requested.crop.top,
1412 c.requested.crop.right,
1413 c.requested.crop.bottom,
1414 c.requested.crop.getWidth(),
1415 c.requested.crop.getHeight(),
1416 s.active.w, s.active.h,
1417 s.active.crop.left,
1418 s.active.crop.top,
1419 s.active.crop.right,
1420 s.active.crop.bottom,
1421 s.active.crop.getWidth(),
1422 s.active.crop.getHeight(),
1423 s.requested.w, s.requested.h,
1424 s.requested.crop.left,
1425 s.requested.crop.top,
1426 s.requested.crop.right,
1427 s.requested.crop.bottom,
1428 s.requested.crop.getWidth(),
1429 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001430
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001431 // record the new size, form this point on, when the client request
1432 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001433 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001434 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001435 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001436
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001437 if (!isFixedSize()) {
1438
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001439 const bool resizePending = (c.requested.w != c.active.w) ||
1440 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001441
Dan Stoza9e9b0442015-04-22 14:59:08 -07001442 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001443 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001444 // if we have a pending resize, unless we are in fixed-size mode.
1445 // the drawing state will be updated only once we receive a buffer
1446 // with the correct size.
1447 //
1448 // in particular, we want to make sure the clip (which is part
1449 // of the geometry state) is latched together with the size but is
1450 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001451 //
1452 // If a sideband stream is attached, however, we want to skip this
1453 // optimization so that transactions aren't missed when a buffer
1454 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001455
1456 flags |= eDontUpdateGeometryState;
1457 }
1458 }
1459
Mathias Agopian13127d82013-03-05 17:47:11 -08001460 // always set active to requested, unless we're asked not to
1461 // this is used by Layer, which special cases resizes.
1462 if (flags & eDontUpdateGeometryState) {
1463 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001464 Layer::State& editCurrentState(getCurrentState());
1465 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001466 }
1467
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001468 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001469 // invalidate and recompute the visible regions if needed
1470 flags |= Layer::eVisibleRegion;
1471 }
1472
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001473 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001474 // invalidate and recompute the visible regions if needed
1475 flags |= eVisibleRegion;
1476 this->contentDirty = true;
1477
1478 // we may use linear filtering, if the matrix scales us
Robert Carr3dcabfa2016-03-01 18:36:58 -08001479 const uint8_t type = c.active.transform.getType();
1480 mNeedsFiltering = (!c.active.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001481 (type >= Transform::SCALE));
1482 }
1483
1484 // Commit the transaction
1485 commitTransaction();
1486 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001487}
1488
Mathias Agopian13127d82013-03-05 17:47:11 -08001489void Layer::commitTransaction() {
1490 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001491}
1492
Mathias Agopian13127d82013-03-05 17:47:11 -08001493uint32_t Layer::getTransactionFlags(uint32_t flags) {
1494 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1495}
1496
1497uint32_t Layer::setTransactionFlags(uint32_t flags) {
1498 return android_atomic_or(flags, &mTransactionFlags);
1499}
1500
1501bool Layer::setPosition(float x, float y) {
Robert Carr3dcabfa2016-03-01 18:36:58 -08001502 if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
Mathias Agopian13127d82013-03-05 17:47:11 -08001503 return false;
1504 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001505 mCurrentState.requested.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001506 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001507 setTransactionFlags(eTransactionNeeded);
1508 return true;
1509}
1510bool Layer::setLayer(uint32_t z) {
1511 if (mCurrentState.z == z)
1512 return false;
1513 mCurrentState.sequence++;
1514 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001515 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001516 setTransactionFlags(eTransactionNeeded);
1517 return true;
1518}
1519bool Layer::setSize(uint32_t w, uint32_t h) {
1520 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1521 return false;
1522 mCurrentState.requested.w = w;
1523 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001524 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001525 setTransactionFlags(eTransactionNeeded);
1526 return true;
1527}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001528#ifdef USE_HWC2
1529bool Layer::setAlpha(float alpha) {
1530#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001531bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001532#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001533 if (mCurrentState.alpha == alpha)
1534 return false;
1535 mCurrentState.sequence++;
1536 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001537 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001538 setTransactionFlags(eTransactionNeeded);
1539 return true;
1540}
1541bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1542 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001543 mCurrentState.requested.transform.set(
Mathias Agopian13127d82013-03-05 17:47:11 -08001544 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001545 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001546 setTransactionFlags(eTransactionNeeded);
1547 return true;
1548}
1549bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001550 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001551 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001552 setTransactionFlags(eTransactionNeeded);
1553 return true;
1554}
1555bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1556 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1557 if (mCurrentState.flags == newFlags)
1558 return false;
1559 mCurrentState.sequence++;
1560 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001561 mCurrentState.mask = mask;
1562 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001563 setTransactionFlags(eTransactionNeeded);
1564 return true;
1565}
1566bool Layer::setCrop(const Rect& crop) {
1567 if (mCurrentState.requested.crop == crop)
1568 return false;
1569 mCurrentState.sequence++;
1570 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001571 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001572 setTransactionFlags(eTransactionNeeded);
1573 return true;
1574}
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001575bool Layer::setFinalCrop(const Rect& crop) {
1576 if (mCurrentState.requested.finalCrop == crop)
1577 return false;
1578 mCurrentState.sequence++;
1579 mCurrentState.requested.finalCrop = crop;
1580 mCurrentState.modified = true;
1581 setTransactionFlags(eTransactionNeeded);
1582 return true;
1583}
Mathias Agopian13127d82013-03-05 17:47:11 -08001584
1585bool Layer::setLayerStack(uint32_t layerStack) {
1586 if (mCurrentState.layerStack == layerStack)
1587 return false;
1588 mCurrentState.sequence++;
1589 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001590 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001591 setTransactionFlags(eTransactionNeeded);
1592 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001593}
1594
Dan Stoza7dde5992015-05-22 09:51:44 -07001595void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1596 uint64_t frameNumber) {
1597 mCurrentState.handle = handle;
1598 mCurrentState.frameNumber = frameNumber;
1599 // We don't set eTransactionNeeded, because just receiving a deferral
1600 // request without any other state updates shouldn't actually induce a delay
1601 mCurrentState.modified = true;
1602 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001603 mCurrentState.handle = nullptr;
1604 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001605 mCurrentState.modified = false;
1606}
1607
Dan Stozaee44edd2015-03-23 15:50:23 -07001608void Layer::useSurfaceDamage() {
1609 if (mFlinger->mForceFullDamage) {
1610 surfaceDamageRegion = Region::INVALID_REGION;
1611 } else {
1612 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1613 }
1614}
1615
1616void Layer::useEmptyDamage() {
1617 surfaceDamageRegion.clear();
1618}
1619
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001620// ----------------------------------------------------------------------------
1621// pageflip handling...
1622// ----------------------------------------------------------------------------
1623
Dan Stoza6b9454d2014-11-07 16:00:59 -08001624bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001625 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001626 return true;
1627 }
1628
Dan Stoza6b9454d2014-11-07 16:00:59 -08001629 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001630 if (mQueueItems.empty()) {
1631 return false;
1632 }
1633 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001634 nsecs_t expectedPresent =
1635 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001636
1637 // Ignore timestamps more than a second in the future
1638 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1639 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1640 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1641 expectedPresent);
1642
1643 bool isDue = timestamp < expectedPresent;
1644 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001645}
1646
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001647bool Layer::onPreComposition() {
1648 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001649 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001650}
1651
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001652void Layer::onPostComposition() {
1653 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001654 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001655 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1656
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001657 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001658 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001659 mFrameTracker.setFrameReadyFence(frameReadyFence);
1660 } else {
1661 // There was no fence for this frame, so assume that it was ready
1662 // to be presented at the desired present time.
1663 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1664 }
1665
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001666 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001667#ifdef USE_HWC2
1668 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1669#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001670 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001671#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001672 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001673 mFrameTracker.setActualPresentFence(presentFence);
1674 } else {
1675 // The HWC doesn't support present fences, so use the refresh
1676 // timestamp instead.
1677 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1678 mFrameTracker.setActualPresentTime(presentTime);
1679 }
1680
1681 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001682 mFrameLatencyNeeded = false;
1683 }
1684}
1685
Dan Stoza9e56aa02015-11-02 13:00:03 -08001686#ifdef USE_HWC2
1687void Layer::releasePendingBuffer() {
1688 mSurfaceFlingerConsumer->releasePendingBuffer();
1689}
1690#endif
1691
Mathias Agopianda27af92012-09-13 18:17:13 -07001692bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001693 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001694#ifdef USE_HWC2
1695 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1696 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1697#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001698 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001699 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001700#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001701}
1702
Mathias Agopian4fec8732012-06-29 14:12:52 -07001703Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001704{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001705 ATRACE_CALL();
1706
Jesse Hall399184a2014-03-03 15:42:54 -08001707 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1708 // mSidebandStreamChanged was true
1709 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001710 if (mSidebandStream != NULL) {
1711 setTransactionFlags(eTransactionNeeded);
1712 mFlinger->setTransactionFlags(eTraversalNeeded);
1713 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001714 recomputeVisibleRegions = true;
1715
1716 const State& s(getDrawingState());
Robert Carr3dcabfa2016-03-01 18:36:58 -08001717 return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001718 }
1719
Mathias Agopian4fec8732012-06-29 14:12:52 -07001720 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001721 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001722
1723 // if we've already called updateTexImage() without going through
1724 // a composition step, we have to skip this layer at this point
1725 // because we cannot call updateTeximage() without a corresponding
1726 // compositionComplete() call.
1727 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001728 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001729 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001730 }
1731
Jamie Gennis351a5132011-09-14 18:23:37 -07001732 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001733 const State& s(getDrawingState());
1734 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001735 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001736
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001737 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001738 Layer::State& front;
1739 Layer::State& current;
1740 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001741 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001742 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001743 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001744 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001745 recomputeVisibleRegions(recomputeVisibleRegions),
1746 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001747 }
1748
1749 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001750 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001751 if (buf == NULL) {
1752 return false;
1753 }
1754
1755 uint32_t bufWidth = buf->getWidth();
1756 uint32_t bufHeight = buf->getHeight();
1757
1758 // check that we received a buffer of the right size
1759 // (Take the buffer's orientation into account)
1760 if (item.mTransform & Transform::ROT_90) {
1761 swap(bufWidth, bufHeight);
1762 }
1763
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001764 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1765 if (front.active != front.requested) {
1766
1767 if (isFixedSize ||
1768 (bufWidth == front.requested.w &&
1769 bufHeight == front.requested.h))
1770 {
1771 // Here we pretend the transaction happened by updating the
1772 // current and drawing states. Drawing state is only accessed
1773 // in this thread, no need to have it locked
1774 front.active = front.requested;
1775
1776 // We also need to update the current state so that
1777 // we don't end-up overwriting the drawing state with
1778 // this stale current state during the next transaction
1779 //
1780 // NOTE: We don't need to hold the transaction lock here
1781 // because State::active is only accessed from this thread.
1782 current.active = front.active;
1783
1784 // recompute visible region
1785 recomputeVisibleRegions = true;
1786 }
1787
1788 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001789 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001790 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1791 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001792 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001793 front.active.w, front.active.h,
1794 front.active.crop.left,
1795 front.active.crop.top,
1796 front.active.crop.right,
1797 front.active.crop.bottom,
1798 front.active.crop.getWidth(),
1799 front.active.crop.getHeight(),
1800 front.requested.w, front.requested.h,
1801 front.requested.crop.left,
1802 front.requested.crop.top,
1803 front.requested.crop.right,
1804 front.requested.crop.bottom,
1805 front.requested.crop.getWidth(),
1806 front.requested.crop.getHeight());
1807 }
1808
Ruben Brunk1681d952014-06-27 15:51:55 -07001809 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001810 if (front.active.w != bufWidth ||
1811 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001812 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001813 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1814 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001815 return true;
1816 }
1817 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001818
1819 // if the transparent region has changed (this test is
1820 // conservative, but that's fine, worst case we're doing
1821 // a bit of extra work), we latch the new one and we
1822 // trigger a visible-region recompute.
1823 if (!front.activeTransparentRegion.isTriviallyEqual(
1824 front.requestedTransparentRegion)) {
1825 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001826
1827 // We also need to update the current state so that
1828 // we don't end-up overwriting the drawing state with
1829 // this stale current state during the next transaction
1830 //
1831 // NOTE: We don't need to hold the transaction lock here
1832 // because State::active is only accessed from this thread.
1833 current.activeTransparentRegion = front.activeTransparentRegion;
1834
1835 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001836 recomputeVisibleRegions = true;
1837 }
1838
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001839 return false;
1840 }
1841 };
1842
Ruben Brunk1681d952014-06-27 15:51:55 -07001843 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1844 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001845
Dan Stozacac35382016-01-27 12:21:06 -08001846
1847 // Check all of our local sync points to ensure that all transactions
1848 // which need to have been applied prior to the frame which is about to
1849 // be latched have signaled
1850
1851 auto headFrameNumber = getHeadFrameNumber();
1852 bool matchingFramesFound = false;
1853 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001854 {
Dan Stozacac35382016-01-27 12:21:06 -08001855 Mutex::Autolock lock(mLocalSyncPointMutex);
1856 for (auto& point : mLocalSyncPoints) {
1857 if (point->getFrameNumber() > headFrameNumber) {
1858 break;
1859 }
1860
1861 matchingFramesFound = true;
1862
1863 if (!point->frameIsAvailable()) {
1864 // We haven't notified the remote layer that the frame for
1865 // this point is available yet. Notify it now, and then
1866 // abort this attempt to latch.
1867 point->setFrameAvailable();
1868 allTransactionsApplied = false;
1869 break;
1870 }
1871
1872 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001873 }
1874 }
1875
Dan Stozacac35382016-01-27 12:21:06 -08001876 if (matchingFramesFound && !allTransactionsApplied) {
1877 mFlinger->signalLayerUpdate();
1878 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001879 }
1880
Pablo Ceballos06312182015-10-07 16:32:12 -07001881 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1882 // of the buffer queue isn't modified when the buffer queue is returning
1883 // BufferItem's that weren't actually queued. This can happen in single
1884 // buffer mode.
1885 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001886 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001887 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001888 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001889 if (updateResult == BufferQueue::PRESENT_LATER) {
1890 // Producer doesn't want buffer to be displayed yet. Signal a
1891 // layer update so we check again at the next opportunity.
1892 mFlinger->signalLayerUpdate();
1893 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001894 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1895 // If the buffer has been rejected, remove it from the shadow queue
1896 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001897 if (queuedBuffer) {
1898 Mutex::Autolock lock(mQueueItemLock);
1899 mQueueItems.removeAt(0);
1900 android_atomic_dec(&mQueuedFrames);
1901 }
Dan Stozaecc50402015-04-28 14:42:06 -07001902 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001903 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1904 // This can occur if something goes wrong when trying to create the
1905 // EGLImage for this buffer. If this happens, the buffer has already
1906 // been released, so we need to clean up the queue and bug out
1907 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001908 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001909 Mutex::Autolock lock(mQueueItemLock);
1910 mQueueItems.clear();
1911 android_atomic_and(0, &mQueuedFrames);
1912 }
1913
1914 // Once we have hit this state, the shadow queue may no longer
1915 // correctly reflect the incoming BufferQueue's contents, so even if
1916 // updateTexImage starts working, the only safe course of action is
1917 // to continue to ignore updates.
1918 mUpdateTexImageFailed = true;
1919
1920 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001921 }
1922
Pablo Ceballos06312182015-10-07 16:32:12 -07001923 if (queuedBuffer) {
1924 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001925 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1926
Dan Stoza6b9454d2014-11-07 16:00:59 -08001927 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001928
1929 // Remove any stale buffers that have been dropped during
1930 // updateTexImage
1931 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1932 mQueueItems.removeAt(0);
1933 android_atomic_dec(&mQueuedFrames);
1934 }
1935
Dan Stoza6b9454d2014-11-07 16:00:59 -08001936 mQueueItems.removeAt(0);
1937 }
1938
Dan Stozaecc50402015-04-28 14:42:06 -07001939
Andy McFadden1585c4d2013-06-28 13:52:40 -07001940 // Decrement the queued-frames count. Signal another event if we
1941 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001942 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001943 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001944 mFlinger->signalLayerUpdate();
1945 }
1946
1947 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001948 // something happened!
1949 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001950 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001951 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001952
Jamie Gennis351a5132011-09-14 18:23:37 -07001953 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001954 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001955 if (mActiveBuffer == NULL) {
1956 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001957 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001958 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001959
Mathias Agopian4824d402012-06-04 18:16:30 -07001960 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001961 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001962 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001963 // the first time we receive a buffer, we need to trigger a
1964 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001965 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001966 }
1967
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001968 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1969 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1970 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001971 if ((crop != mCurrentCrop) ||
1972 (transform != mCurrentTransform) ||
1973 (scalingMode != mCurrentScalingMode))
1974 {
1975 mCurrentCrop = crop;
1976 mCurrentTransform = transform;
1977 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001978 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001979 }
1980
1981 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001982 uint32_t bufWidth = mActiveBuffer->getWidth();
1983 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001984 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1985 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001986 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001987 }
1988 }
1989
1990 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001991 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001992 recomputeVisibleRegions = true;
1993 }
1994
Dan Stozacac35382016-01-27 12:21:06 -08001995 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1996
1997 // Remove any sync points corresponding to the buffer which was just
1998 // latched
1999 {
2000 Mutex::Autolock lock(mLocalSyncPointMutex);
2001 auto point = mLocalSyncPoints.begin();
2002 while (point != mLocalSyncPoints.end()) {
2003 if (!(*point)->frameIsAvailable() ||
2004 !(*point)->transactionIsApplied()) {
2005 // This sync point must have been added since we started
2006 // latching. Don't drop it yet.
2007 ++point;
2008 continue;
2009 }
2010
2011 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2012 point = mLocalSyncPoints.erase(point);
2013 } else {
2014 ++point;
2015 }
2016 }
2017 }
2018
Mathias Agopian4fec8732012-06-29 14:12:52 -07002019 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07002020 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07002021
2022 // transform the dirty region to window-manager space
Robert Carr3dcabfa2016-03-01 18:36:58 -08002023 outDirtyRegion = (s.active.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07002024 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07002025 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002026}
2027
Mathias Agopiana67932f2011-04-20 14:20:59 -07002028uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07002029{
Mathias Agopiana67932f2011-04-20 14:20:59 -07002030 // TODO: should we do something special if mSecure is set?
2031 if (mProtectedByApp) {
2032 // need a hardware-protected path to external video sink
2033 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07002034 }
Riley Andrews03414a12014-07-01 14:22:59 -07002035 if (mPotentialCursor) {
2036 usage |= GraphicBuffer::USAGE_CURSOR;
2037 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07002038 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07002039 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07002040}
2041
Mathias Agopian84300952012-11-21 16:02:13 -08002042void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07002043 uint32_t orientation = 0;
2044 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08002045 // The transform hint is used to improve performance, but we can
2046 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07002047 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07002048 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07002049 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07002050 if (orientation & Transform::ROT_INVALID) {
2051 orientation = 0;
2052 }
2053 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08002054 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07002055}
2056
Mathias Agopian13127d82013-03-05 17:47:11 -08002057// ----------------------------------------------------------------------------
2058// debugging
2059// ----------------------------------------------------------------------------
2060
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002061void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08002062{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07002063 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08002064
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002065 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02002066 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002067 "+ %s %p (%s)\n",
2068 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002069 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002070
Mathias Agopian2ca79392013-04-02 18:30:32 -07002071 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08002072 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07002073 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08002074 sp<Client> client(mClientRef.promote());
2075
Mathias Agopian74d211a2013-04-22 16:55:35 +02002076 result.appendFormat( " "
Pablo Ceballosacbe6782016-03-04 17:54:21 +00002077 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2078 "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
Mathias Agopian13127d82013-03-05 17:47:11 -08002079 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08002080#ifdef USE_HWC2
2081 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
2082#else
Mathias Agopian13127d82013-03-05 17:47:11 -08002083 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08002084#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002085 " client=%p\n",
Robert Carr3dcabfa2016-03-01 18:36:58 -08002086 s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
Mathias Agopian13127d82013-03-05 17:47:11 -08002087 s.active.crop.left, s.active.crop.top,
2088 s.active.crop.right, s.active.crop.bottom,
Pablo Ceballosacbe6782016-03-04 17:54:21 +00002089 s.active.finalCrop.left, s.active.finalCrop.top,
2090 s.active.finalCrop.right, s.active.finalCrop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002091 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002092 s.alpha, s.flags,
Robert Carr3dcabfa2016-03-01 18:36:58 -08002093 s.active.transform[0][0], s.active.transform[0][1],
2094 s.active.transform[1][0], s.active.transform[1][1],
Mathias Agopian13127d82013-03-05 17:47:11 -08002095 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002096
2097 sp<const GraphicBuffer> buf0(mActiveBuffer);
2098 uint32_t w0=0, h0=0, s0=0, f0=0;
2099 if (buf0 != 0) {
2100 w0 = buf0->getWidth();
2101 h0 = buf0->getHeight();
2102 s0 = buf0->getStride();
2103 f0 = buf0->format;
2104 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002105 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002106 " "
2107 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2108 " queued-frames=%d, mRefreshPending=%d\n",
2109 mFormat, w0, h0, s0,f0,
2110 mQueuedFrames, mRefreshPending);
2111
Mathias Agopian13127d82013-03-05 17:47:11 -08002112 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002113 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002114 }
2115}
2116
Svetoslavd85084b2014-03-20 10:28:31 -07002117void Layer::dumpFrameStats(String8& result) const {
2118 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002119}
2120
Svetoslavd85084b2014-03-20 10:28:31 -07002121void Layer::clearFrameStats() {
2122 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002123}
2124
Jamie Gennis6547ff42013-07-16 20:12:42 -07002125void Layer::logFrameStats() {
2126 mFrameTracker.logAndResetStats(mName);
2127}
2128
Svetoslavd85084b2014-03-20 10:28:31 -07002129void Layer::getFrameStats(FrameStats* outStats) const {
2130 mFrameTracker.getStats(outStats);
2131}
2132
Mathias Agopian13127d82013-03-05 17:47:11 -08002133// ---------------------------------------------------------------------------
2134
2135Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2136 const sp<Layer>& layer)
2137 : mFlinger(flinger), mLayer(layer) {
2138}
2139
2140Layer::LayerCleaner::~LayerCleaner() {
2141 // destroy client resources
2142 mFlinger->onLayerDestroyed(mLayer);
2143}
2144
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002145// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002146}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002147
2148#if defined(__gl_h_)
2149#error "don't include gl/gl.h in this file"
2150#endif
2151
2152#if defined(__gl2_h_)
2153#error "don't include gl2/gl2.h in this file"
2154#endif