blob: 80012a6e32f9cfb6caa448c9d17702f9f1f375e9 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dan Stoza9e56aa02015-11-02 13:00:03 -080017//#define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "Layer"
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080020#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080022#include <stdlib.h>
23#include <stdint.h>
24#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080025#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026
Mathias Agopiana67932f2011-04-20 14:20:59 -070027#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070028#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070029#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080030
31#include <utils/Errors.h>
32#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080033#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080035#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080036
Mathias Agopian3330b202009-10-05 17:07:12 -070037#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080039
Dan Stoza6b9454d2014-11-07 16:00:59 -080040#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080041#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042
43#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020044#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070045#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070047#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049
Mathias Agopian1b031492012-06-20 17:51:20 -070050#include "DisplayHardware/HWComposer.h"
51
Mathias Agopian875d8e12013-06-07 15:35:48 -070052#include "RenderEngine/RenderEngine.h"
53
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080054#define DEBUG_RESIZE 0
55
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080056namespace android {
57
58// ---------------------------------------------------------------------------
59
Mathias Agopian13127d82013-03-05 17:47:11 -080060int32_t Layer::sSequence = 1;
61
Mathias Agopian4d9b8222013-03-12 17:11:48 -070062Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
63 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080064 : contentDirty(false),
65 sequence(uint32_t(android_atomic_inc(&sSequence))),
66 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070067 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mPremultipliedAlpha(true),
69 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080070 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080071 mTransactionFlags(0),
Dan Stoza7dde5992015-05-22 09:51:44 -070072 mPendingStateMutex(),
73 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070074 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080075 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070076 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070077 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070078 mCurrentOpacity(true),
Dan Stozacac35382016-01-27 12:21:06 -080079 mCurrentFrameNumber(0),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080080 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080081 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080082 mFiltering(false),
83 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070084 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Pablo Ceballos40845df2016-01-25 17:41:15 -080085#ifndef USE_HWC2
86 mIsGlesComposition(false),
87#endif
Mathias Agopian13127d82013-03-05 17:47:11 -080088 mProtectedByApp(false),
89 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070090 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070091 mPotentialCursor(false),
92 mQueueItemLock(),
93 mQueueItemCondition(),
94 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070095 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080096 mUpdateTexImageFailed(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080097 mAutoRefresh(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080098{
Dan Stoza9e56aa02015-11-02 13:00:03 -080099#ifdef USE_HWC2
100 ALOGV("Creating Layer %s", name.string());
101#endif
102
Mathias Agopiana67932f2011-04-20 14:20:59 -0700103 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -0700104 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -0700105 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700106
107 uint32_t layerFlags = 0;
108 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -0800109 layerFlags |= layer_state_t::eLayerHidden;
110 if (flags & ISurfaceComposerClient::eOpaque)
111 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700112 if (flags & ISurfaceComposerClient::eSecure)
113 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700114
115 if (flags & ISurfaceComposerClient::eNonPremultiplied)
116 mPremultipliedAlpha = false;
117
118 mName = name;
119
120 mCurrentState.active.w = w;
121 mCurrentState.active.h = h;
Robert Carr3dcabfa2016-03-01 18:36:58 -0800122 mCurrentState.active.transform.set(0, 0);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700123 mCurrentState.active.crop.makeInvalid();
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000124 mCurrentState.active.finalCrop.makeInvalid();
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700125 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800126#ifdef USE_HWC2
127 mCurrentState.alpha = 1.0f;
128#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700129 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800130#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700131 mCurrentState.layerStack = 0;
132 mCurrentState.flags = layerFlags;
133 mCurrentState.sequence = 0;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700134 mCurrentState.requested = mCurrentState.active;
135
136 // drawing state & current state are identical
137 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700138
Dan Stoza9e56aa02015-11-02 13:00:03 -0800139#ifdef USE_HWC2
140 const auto& hwc = flinger->getHwComposer();
141 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
142 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
143#else
Jamie Gennis6547ff42013-07-16 20:12:42 -0700144 nsecs_t displayPeriod =
145 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800146#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700147 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800148}
149
Mathias Agopian3f844832013-08-07 21:24:32 -0700150void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800151 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700152 sp<IGraphicBufferProducer> producer;
153 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700154 BufferQueue::createBufferQueue(&producer, &consumer);
155 mProducer = new MonitoredProducer(producer, mFlinger);
156 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800157 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800158 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700159 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800160
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700161#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
162#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700163#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700164 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800165#endif
Andy McFadden69052052012-09-14 16:10:11 -0700166
Mathias Agopian84300952012-11-21 16:02:13 -0800167 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
168 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700169}
170
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700171Layer::~Layer() {
Pablo Ceballos8ea4e7b2016-03-03 15:20:02 -0800172 sp<Client> c(mClientRef.promote());
173 if (c != 0) {
174 c->detachLayer(this);
175 }
176
Dan Stozacac35382016-01-27 12:21:06 -0800177 for (auto& point : mRemoteSyncPoints) {
178 point->setTransactionApplied();
179 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700180 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700181 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700182}
183
Mathias Agopian13127d82013-03-05 17:47:11 -0800184// ---------------------------------------------------------------------------
185// callbacks
186// ---------------------------------------------------------------------------
187
Dan Stoza9e56aa02015-11-02 13:00:03 -0800188#ifdef USE_HWC2
189void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
190 if (mHwcLayers.empty()) {
191 return;
192 }
193 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
194}
195#else
Dan Stozac7014012014-02-14 15:03:43 -0800196void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800197 HWComposer::HWCLayerInterface* layer) {
198 if (layer) {
199 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700200 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800201 }
202}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800203#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800204
Dan Stoza6b9454d2014-11-07 16:00:59 -0800205void Layer::onFrameAvailable(const BufferItem& item) {
206 // Add this buffer from our internal queue tracker
207 { // Autolock scope
208 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700209
210 // Reset the frame number tracker when we receive the first buffer after
211 // a frame number reset
212 if (item.mFrameNumber == 1) {
213 mLastFrameNumberReceived = 0;
214 }
215
216 // Ensure that callbacks are handled in order
217 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
218 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
219 ms2ns(500));
220 if (result != NO_ERROR) {
221 ALOGE("[%s] Timed out waiting on callback", mName.string());
222 }
223 }
224
Dan Stoza6b9454d2014-11-07 16:00:59 -0800225 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700226 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700227
228 // Wake up any pending callbacks
229 mLastFrameNumberReceived = item.mFrameNumber;
230 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800231 }
232
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800233 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700234}
235
Dan Stoza6b9454d2014-11-07 16:00:59 -0800236void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700237 { // Autolock scope
238 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700239
Dan Stoza7dde5992015-05-22 09:51:44 -0700240 // Ensure that callbacks are handled in order
241 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
242 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
243 ms2ns(500));
244 if (result != NO_ERROR) {
245 ALOGE("[%s] Timed out waiting on callback", mName.string());
246 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700247 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700248
249 if (mQueueItems.empty()) {
250 ALOGE("Can't replace a frame on an empty queue");
251 return;
252 }
253 mQueueItems.editItemAt(0) = item;
254
255 // Wake up any pending callbacks
256 mLastFrameNumberReceived = item.mFrameNumber;
257 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700258 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800259}
260
Jesse Hall399184a2014-03-03 15:42:54 -0800261void Layer::onSidebandStreamChanged() {
262 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
263 // mSidebandStreamChanged was false
264 mFlinger->signalLayerUpdate();
265 }
266}
267
Mathias Agopian67106042013-03-14 19:18:13 -0700268// called with SurfaceFlinger::mStateLock from the drawing thread after
269// the layer has been remove from the current state list (and just before
270// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800271void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800272 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700273}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700274
Mathias Agopian13127d82013-03-05 17:47:11 -0800275// ---------------------------------------------------------------------------
276// set-up
277// ---------------------------------------------------------------------------
278
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700279const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800280 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800281}
282
Mathias Agopianf9d93272009-06-19 17:00:27 -0700283status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800284 PixelFormat format, uint32_t flags)
285{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700286 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700287 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700288
289 // never allow a surface larger than what our underlying GL implementation
290 // can handle.
291 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800292 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700293 return BAD_VALUE;
294 }
295
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700296 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700297
Riley Andrews03414a12014-07-01 14:22:59 -0700298 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700299 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700300 mCurrentOpacity = getOpacityForFormat(format);
301
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800302 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
303 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
304 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700305
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800306 return NO_ERROR;
307}
308
Dan Stoza7dde5992015-05-22 09:51:44 -0700309/*
310 * The layer handle is just a BBinder object passed to the client
311 * (remote process) -- we don't keep any reference on our side such that
312 * the dtor is called when the remote side let go of its reference.
313 *
314 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
315 * this layer when the handle is destroyed.
316 */
317class Layer::Handle : public BBinder, public LayerCleaner {
318 public:
319 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
320 : LayerCleaner(flinger, layer), owner(layer) {}
321
322 wp<Layer> owner;
323};
324
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700325sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800326 Mutex::Autolock _l(mLock);
327
328 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700329 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800330
331 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700332
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700333 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800334}
335
Dan Stozab9b08832014-03-13 11:55:57 -0700336sp<IGraphicBufferProducer> Layer::getProducer() const {
337 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700338}
339
Mathias Agopian13127d82013-03-05 17:47:11 -0800340// ---------------------------------------------------------------------------
341// h/w composer set-up
342// ---------------------------------------------------------------------------
343
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800344Rect Layer::getContentCrop() const {
345 // this is the crop rectangle that applies to the buffer
346 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700347 Rect crop;
348 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800349 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700350 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800351 } else if (mActiveBuffer != NULL) {
352 // otherwise we use the whole buffer
353 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700354 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800355 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700356 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700357 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700358 return crop;
359}
360
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700361static Rect reduce(const Rect& win, const Region& exclude) {
362 if (CC_LIKELY(exclude.isEmpty())) {
363 return win;
364 }
365 if (exclude.isRect()) {
366 return win.reduce(exclude.getBounds());
367 }
368 return Region(win).subtract(exclude).getBounds();
369}
370
Mathias Agopian13127d82013-03-05 17:47:11 -0800371Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700372 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700373 return computeBounds(s.activeTransparentRegion);
374}
375
376Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
377 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800378 Rect win(s.active.w, s.active.h);
379 if (!s.active.crop.isEmpty()) {
380 win.intersect(s.active.crop, &win);
381 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700382 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700383 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800384}
385
Mathias Agopian6b442672013-07-09 21:24:52 -0700386FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800387 // the content crop is the area of the content that gets scaled to the
388 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700389 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800390
391 // the active.crop is the area of the window that gets cropped, but not
392 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700393 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800394
395 // apply the projection's clipping to the window crop in
396 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700397 // if there are no window scaling involved, this operation will map to full
398 // pixels in the buffer.
399 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
400 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700401
402 Rect activeCrop(s.active.w, s.active.h);
403 if (!s.active.crop.isEmpty()) {
404 activeCrop = s.active.crop;
405 }
406
Robert Carr3dcabfa2016-03-01 18:36:58 -0800407 activeCrop = s.active.transform.transform(activeCrop);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000408 if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
409 activeCrop.clear();
410 }
411 if (!s.active.finalCrop.isEmpty()) {
412 if(!activeCrop.intersect(s.active.finalCrop, &activeCrop)) {
413 activeCrop.clear();
414 }
415 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800416 activeCrop = s.active.transform.inverse().transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800417
Michael Lentine28ea2172014-11-19 18:32:37 -0800418 // This needs to be here as transform.transform(Rect) computes the
419 // transformed rect and then takes the bounding box of the result before
420 // returning. This means
421 // transform.inverse().transform(transform.transform(Rect)) != Rect
422 // in which case we need to make sure the final rect is clipped to the
423 // display bounds.
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000424 if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
425 activeCrop.clear();
426 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800427
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700428 // subtract the transparent region and snap to the bounds
429 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
430
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000431 // Transform the window crop to match the buffer coordinate system,
432 // which means using the inverse of the current transform set on the
433 // SurfaceFlingerConsumer.
434 uint32_t invTransform = mCurrentTransform;
435 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
436 /*
437 * the code below applies the display's inverse transform to the buffer
438 */
439 uint32_t invTransformOrient = hw->getOrientationTransform();
440 // calculate the inverse transform
441 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
442 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
443 NATIVE_WINDOW_TRANSFORM_FLIP_H;
444 // If the transform has been rotated the axis of flip has been swapped
445 // so we need to swap which flip operations we are performing
Michael Lentine7b902582014-08-19 18:14:06 -0700446 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
447 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000448 if (is_h_flipped != is_v_flipped) {
Michael Lentine7b902582014-08-19 18:14:06 -0700449 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
450 NATIVE_WINDOW_TRANSFORM_FLIP_H;
451 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800452 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000453 // and apply to the current transform
454 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
Mathias Agopian13127d82013-03-05 17:47:11 -0800455 }
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000456
457 int winWidth = s.active.w;
458 int winHeight = s.active.h;
459 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
460 // If the activeCrop has been rotate the ends are rotated but not
461 // the space itself so when transforming ends back we can't rely on
462 // a modification of the axes of rotation. To account for this we
463 // need to reorient the inverse rotation in terms of the current
464 // axes of rotation.
465 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
466 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
467 if (is_h_flipped == is_v_flipped) {
468 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
469 NATIVE_WINDOW_TRANSFORM_FLIP_H;
470 }
471 winWidth = s.active.h;
472 winHeight = s.active.w;
473 }
474 const Rect winCrop = activeCrop.transform(
475 invTransform, s.active.w, s.active.h);
476
477 // below, crop is intersected with winCrop expressed in crop's coordinate space
478 float xScale = crop.getWidth() / float(winWidth);
479 float yScale = crop.getHeight() / float(winHeight);
480
481 float insetL = winCrop.left * xScale;
482 float insetT = winCrop.top * yScale;
483 float insetR = (winWidth - winCrop.right ) * xScale;
484 float insetB = (winHeight - winCrop.bottom) * yScale;
485
486 crop.left += insetL;
487 crop.top += insetT;
488 crop.right -= insetR;
489 crop.bottom -= insetB;
490
Mathias Agopian13127d82013-03-05 17:47:11 -0800491 return crop;
492}
493
Dan Stoza9e56aa02015-11-02 13:00:03 -0800494#ifdef USE_HWC2
495void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
496#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700497void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700498 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700499 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800500#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700501{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800502#ifdef USE_HWC2
503 const auto hwcId = displayDevice->getHwcDisplayId();
504 auto& hwcInfo = mHwcLayers[hwcId];
505#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800506 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800507#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700508
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700509 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800510#ifdef USE_HWC2
511 hwcInfo.forceClientComposition = false;
512
513 if (isSecure() && !displayDevice->isSecure()) {
514 hwcInfo.forceClientComposition = true;
515 }
516
517 auto& hwcLayer = hwcInfo.layer;
518#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700519 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700520
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700521 if (isSecure() && !hw->isSecure()) {
522 layer.setSkip(true);
523 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800524#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700525
Mathias Agopian13127d82013-03-05 17:47:11 -0800526 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700527 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800528#ifdef USE_HWC2
529 if (!isOpaque(s) || s.alpha != 1.0f) {
530 auto blendMode = mPremultipliedAlpha ?
531 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
532 auto error = hwcLayer->setBlendMode(blendMode);
533 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
534 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
535 to_string(error).c_str(), static_cast<int32_t>(error));
536 }
537#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800538 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800539 layer.setBlending(mPremultipliedAlpha ?
540 HWC_BLENDING_PREMULT :
541 HWC_BLENDING_COVERAGE);
542 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800543#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800544
545 // apply the layer's transform, followed by the display's global transform
546 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700547 Region activeTransparentRegion(s.activeTransparentRegion);
548 if (!s.active.crop.isEmpty()) {
549 Rect activeCrop(s.active.crop);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800550 activeCrop = s.active.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800551#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000552 if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800553#else
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000554 if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800555#endif
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000556 activeCrop.clear();
557 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800558 activeCrop = s.active.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800559 // This needs to be here as transform.transform(Rect) computes the
560 // transformed rect and then takes the bounding box of the result before
561 // returning. This means
562 // transform.inverse().transform(transform.transform(Rect)) != Rect
563 // in which case we need to make sure the final rect is clipped to the
564 // display bounds.
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000565 if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
566 activeCrop.clear();
567 }
Michael Lentine6c925ed2014-09-26 17:55:01 -0700568 // mark regions outside the crop as transparent
569 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
570 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
571 s.active.w, s.active.h));
572 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
573 activeCrop.left, activeCrop.bottom));
574 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
575 s.active.w, activeCrop.bottom));
576 }
Robert Carr3dcabfa2016-03-01 18:36:58 -0800577 Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000578 if (!s.active.finalCrop.isEmpty()) {
579 if(!frame.intersect(s.active.finalCrop, &frame)) {
580 frame.clear();
581 }
582 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800583#ifdef USE_HWC2
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000584 if (!frame.intersect(displayDevice->getViewport(), &frame)) {
585 frame.clear();
586 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800587 const Transform& tr(displayDevice->getTransform());
588 Rect transformedFrame = tr.transform(frame);
589 auto error = hwcLayer->setDisplayFrame(transformedFrame);
590 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
591 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
592 transformedFrame.top, transformedFrame.right,
593 transformedFrame.bottom, to_string(error).c_str(),
594 static_cast<int32_t>(error));
595
596 FloatRect sourceCrop = computeCrop(displayDevice);
597 error = hwcLayer->setSourceCrop(sourceCrop);
598 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
599 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
600 sourceCrop.left, sourceCrop.top, sourceCrop.right,
601 sourceCrop.bottom, to_string(error).c_str(),
602 static_cast<int32_t>(error));
603
604 error = hwcLayer->setPlaneAlpha(s.alpha);
605 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
606 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
607 static_cast<int32_t>(error));
608
609 error = hwcLayer->setZOrder(s.z);
610 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
611 mName.string(), s.z, to_string(error).c_str(),
612 static_cast<int32_t>(error));
613#else
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000614 if (!frame.intersect(hw->getViewport(), &frame)) {
615 frame.clear();
616 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800617 const Transform& tr(hw->getTransform());
618 layer.setFrame(tr.transform(frame));
619 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800620 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800621#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800622
Mathias Agopian29a367b2011-07-12 14:51:45 -0700623 /*
624 * Transformations are applied in this order:
625 * 1) buffer orientation/flip/mirror
626 * 2) state transformation (window manager)
627 * 3) layer orientation (screen orientation)
628 * (NOTE: the matrices are multiplied in reverse order)
629 */
630
631 const Transform bufferOrientation(mCurrentTransform);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800632 Transform transform(tr * s.active.transform * bufferOrientation);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700633
634 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
635 /*
636 * the code below applies the display's inverse transform to the buffer
637 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800638#ifdef USE_HWC2
639 uint32_t invTransform = displayDevice->getOrientationTransform();
640#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700641 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800642#endif
Michael Lentine14409632014-08-19 11:27:30 -0700643 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700644 // calculate the inverse transform
645 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
646 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
647 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700648 // If the transform has been rotated the axis of flip has been swapped
649 // so we need to swap which flip operations we are performing
650 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
651 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
652 if (is_h_flipped != is_v_flipped) {
653 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
654 NATIVE_WINDOW_TRANSFORM_FLIP_H;
655 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700656 }
657 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700658 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700659 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700660
661 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800662 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800663#ifdef USE_HWC2
664 if (orientation & Transform::ROT_INVALID) {
665 // we can only handle simple transformation
666 hwcInfo.forceClientComposition = true;
667 } else {
668 auto transform = static_cast<HWC2::Transform>(orientation);
669 auto error = hwcLayer->setTransform(transform);
670 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
671 "%s (%d)", mName.string(), to_string(transform).c_str(),
672 to_string(error).c_str(), static_cast<int32_t>(error));
673 }
674#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800675 if (orientation & Transform::ROT_INVALID) {
676 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700677 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700678 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800679 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700680 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800681#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700682}
683
Dan Stoza9e56aa02015-11-02 13:00:03 -0800684#ifdef USE_HWC2
685void Layer::forceClientComposition(int32_t hwcId) {
686 if (mHwcLayers.count(hwcId) == 0) {
687 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
688 return;
689 }
690
691 mHwcLayers[hwcId].forceClientComposition = true;
692}
693#endif
694
695#ifdef USE_HWC2
696void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
697 // Apply this display's projection's viewport to the visible region
698 // before giving it to the HWC HAL.
699 const Transform& tr = displayDevice->getTransform();
700 const auto& viewport = displayDevice->getViewport();
701 Region visible = tr.transform(visibleRegion.intersect(viewport));
702 auto hwcId = displayDevice->getHwcDisplayId();
703 auto& hwcLayer = mHwcLayers[hwcId].layer;
704 auto error = hwcLayer->setVisibleRegion(visible);
705 if (error != HWC2::Error::None) {
706 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
707 to_string(error).c_str(), static_cast<int32_t>(error));
708 visible.dump(LOG_TAG);
709 }
710
711 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
712 if (error != HWC2::Error::None) {
713 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
714 to_string(error).c_str(), static_cast<int32_t>(error));
715 surfaceDamageRegion.dump(LOG_TAG);
716 }
717
718 auto compositionType = HWC2::Composition::Invalid;
719 if (mSidebandStream.get()) {
720 compositionType = HWC2::Composition::Sideband;
721 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
722 if (error != HWC2::Error::None) {
723 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
724 mName.string(), mSidebandStream->handle(),
725 to_string(error).c_str(), static_cast<int32_t>(error));
726 return;
727 }
728 } else {
729 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
730 compositionType = HWC2::Composition::Client;
731 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
732 if (error != HWC2::Error::None) {
733 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
734 to_string(error).c_str(), static_cast<int32_t>(error));
735 return;
736 }
737 } else {
738 if (mPotentialCursor) {
739 compositionType = HWC2::Composition::Cursor;
740 }
741 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
742 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
743 acquireFence);
744 if (error != HWC2::Error::None) {
745 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
746 mActiveBuffer->handle, to_string(error).c_str(),
747 static_cast<int32_t>(error));
748 return;
749 }
750 // If it's not a cursor, default to device composition
751 }
752 }
753
754 if (mHwcLayers[hwcId].forceClientComposition) {
755 ALOGV("[%s] Forcing Client composition", mName.string());
756 setCompositionType(hwcId, HWC2::Composition::Client);
757 } else if (compositionType != HWC2::Composition::Invalid) {
758 ALOGV("[%s] Requesting %s composition", mName.string(),
759 to_string(compositionType).c_str());
760 setCompositionType(hwcId, compositionType);
761 } else {
762 ALOGV("[%s] Requesting Device composition", mName.string());
763 setCompositionType(hwcId, HWC2::Composition::Device);
764 }
765}
766#else
Mathias Agopian42977342012-08-05 00:40:46 -0700767void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700768 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800769 // we have to set the visible region on every frame because
770 // we currently free it during onLayerDisplayed(), which is called
771 // after HWComposer::commit() -- every frame.
772 // Apply this display's projection's viewport to the visible region
773 // before giving it to the HWC HAL.
774 const Transform& tr = hw->getTransform();
775 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
776 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700777 layer.setSurfaceDamage(surfaceDamageRegion);
Pablo Ceballos40845df2016-01-25 17:41:15 -0800778 mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
Dan Stozaee44edd2015-03-23 15:50:23 -0700779
Jesse Hall399184a2014-03-03 15:42:54 -0800780 if (mSidebandStream.get()) {
781 layer.setSidebandStream(mSidebandStream);
782 } else {
783 // NOTE: buffer can be NULL if the client never drew into this
784 // layer yet, or if we ran out of memory
785 layer.setBuffer(mActiveBuffer);
786 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700787}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800788#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700789
Dan Stoza9e56aa02015-11-02 13:00:03 -0800790#ifdef USE_HWC2
791void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
792 auto hwcId = displayDevice->getHwcDisplayId();
793 if (mHwcLayers.count(hwcId) == 0 ||
794 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
795 return;
796 }
797
798 // This gives us only the "orientation" component of the transform
799 const State& s(getCurrentState());
800
801 // Apply the layer's transform, followed by the display's global transform
802 // Here we're guaranteed that the layer's transform preserves rects
803 Rect win(s.active.w, s.active.h);
804 if (!s.active.crop.isEmpty()) {
805 win.intersect(s.active.crop, &win);
806 }
807 // Subtract the transparent region and snap to the bounds
808 Rect bounds = reduce(win, s.activeTransparentRegion);
Dan Stozabaf416d2016-03-10 11:57:08 -0800809 Rect frame(s.active.transform.transform(bounds));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800810 frame.intersect(displayDevice->getViewport(), &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000811 if (!s.active.finalCrop.isEmpty()) {
812 frame.intersect(s.active.finalCrop, &frame);
813 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800814 auto& displayTransform(displayDevice->getTransform());
815 auto position = displayTransform.transform(frame);
816
817 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
818 position.top);
819 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
820 "to (%d, %d): %s (%d)", mName.string(), position.left,
821 position.top, to_string(error).c_str(),
822 static_cast<int32_t>(error));
823}
824#else
Dan Stozac7014012014-02-14 15:03:43 -0800825void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700826 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700827 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700828
829 // TODO: there is a possible optimization here: we only need to set the
830 // acquire fence the first time a new buffer is acquired on EACH display.
831
Riley Andrews03414a12014-07-01 14:22:59 -0700832 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800833 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800834 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700835 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700836 if (fenceFd == -1) {
837 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
838 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700839 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700840 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700841 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700842}
843
Riley Andrews03414a12014-07-01 14:22:59 -0700844Rect Layer::getPosition(
845 const sp<const DisplayDevice>& hw)
846{
847 // this gives us only the "orientation" component of the transform
848 const State& s(getCurrentState());
849
850 // apply the layer's transform, followed by the display's global transform
851 // here we're guaranteed that the layer's transform preserves rects
852 Rect win(s.active.w, s.active.h);
853 if (!s.active.crop.isEmpty()) {
854 win.intersect(s.active.crop, &win);
855 }
856 // subtract the transparent region and snap to the bounds
857 Rect bounds = reduce(win, s.activeTransparentRegion);
Robert Carr3dcabfa2016-03-01 18:36:58 -0800858 Rect frame(s.active.transform.transform(bounds));
Riley Andrews03414a12014-07-01 14:22:59 -0700859 frame.intersect(hw->getViewport(), &frame);
Pablo Ceballosacbe6782016-03-04 17:54:21 +0000860 if (!s.active.finalCrop.isEmpty()) {
861 frame.intersect(s.active.finalCrop, &frame);
862 }
Riley Andrews03414a12014-07-01 14:22:59 -0700863 const Transform& tr(hw->getTransform());
864 return Rect(tr.transform(frame));
865}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800866#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700867
Mathias Agopian13127d82013-03-05 17:47:11 -0800868// ---------------------------------------------------------------------------
869// drawing...
870// ---------------------------------------------------------------------------
871
872void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800873 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800874}
875
Dan Stozac7014012014-02-14 15:03:43 -0800876void Layer::draw(const sp<const DisplayDevice>& hw,
877 bool useIdentityTransform) const {
878 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800879}
880
Dan Stozac7014012014-02-14 15:03:43 -0800881void Layer::draw(const sp<const DisplayDevice>& hw) const {
882 onDraw(hw, Region(hw->bounds()), false);
883}
884
885void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
886 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800887{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800888 ATRACE_CALL();
889
Mathias Agopiana67932f2011-04-20 14:20:59 -0700890 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800891 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700892 // in fact never been drawn into. This happens frequently with
893 // SurfaceView because the WindowManager can't know when the client
894 // has drawn the first time.
895
896 // If there is nothing under us, we paint the screen in black, otherwise
897 // we just skip this update.
898
899 // figure out if there is something below us
900 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700901 const SurfaceFlinger::LayerVector& drawingLayers(
902 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700903 const size_t count = drawingLayers.size();
904 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800905 const sp<Layer>& layer(drawingLayers[i]);
906 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700907 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700908 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700909 }
910 // if not everything below us is covered, we plug the holes!
911 Region holes(clip.subtract(under));
912 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700913 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700914 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800915 return;
916 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700917
Andy McFadden97eba892012-12-11 15:21:45 -0800918 // Bind the current buffer to the GL texture, and wait for it to be
919 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800920 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
921 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800922 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700923 // Go ahead and draw the buffer anyway; no matter what we do the screen
924 // is probably going to have something visibly wrong.
925 }
926
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700927 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
928
Mathias Agopian875d8e12013-06-07 15:35:48 -0700929 RenderEngine& engine(mFlinger->getRenderEngine());
930
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700931 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700932 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700933 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700934
935 // Query the texture matrix given our current filtering mode.
936 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800937 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
938 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700939
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700940 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
941
942 /*
943 * the code below applies the display's inverse transform to the texture transform
944 */
945
946 // create a 4x4 transform matrix from the display transform flags
947 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
948 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
949 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
950
951 mat4 tr;
952 uint32_t transform = hw->getOrientationTransform();
953 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
954 tr = tr * rot90;
955 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
956 tr = tr * flipH;
957 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
958 tr = tr * flipV;
959
960 // calculate the inverse
961 tr = inverse(tr);
962
963 // and finally apply it to the original texture matrix
964 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
965 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
966 }
967
Jamie Genniscbb1a952012-05-08 17:05:52 -0700968 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700969 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
970 mTexture.setFiltering(useFiltering);
971 mTexture.setMatrix(textureMatrix);
972
973 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700974 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700975 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700976 }
Dan Stozac7014012014-02-14 15:03:43 -0800977 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700978 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800979}
980
Mathias Agopian13127d82013-03-05 17:47:11 -0800981
Dan Stozac7014012014-02-14 15:03:43 -0800982void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
983 const Region& /* clip */, float red, float green, float blue,
984 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800985{
Mathias Agopian19733a32013-08-28 18:13:56 -0700986 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800987 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700988 engine.setupFillWithColor(red, green, blue, alpha);
989 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800990}
991
992void Layer::clearWithOpenGL(
993 const sp<const DisplayDevice>& hw, const Region& clip) const {
994 clearWithOpenGL(hw, clip, 0,0,0,0);
995}
996
Dan Stozac7014012014-02-14 15:03:43 -0800997void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
998 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700999 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001000
Dan Stozac7014012014-02-14 15:03:43 -08001001 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -08001002
Mathias Agopian13127d82013-03-05 17:47:11 -08001003 /*
1004 * NOTE: the way we compute the texture coordinates here produces
1005 * different results than when we take the HWC path -- in the later case
1006 * the "source crop" is rounded to texel boundaries.
1007 * This can produce significantly different results when the texture
1008 * is scaled by a large amount.
1009 *
1010 * The GL code below is more logical (imho), and the difference with
1011 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -07001012 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -08001013 * GL composition when a buffer scaling is applied (maybe with some
1014 * minimal value)? Or, we could make GL behave like HWC -- but this feel
1015 * like more of a hack.
1016 */
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001017 Rect win(computeBounds());
1018
1019 if (!s.active.finalCrop.isEmpty()) {
1020 win = s.active.transform.transform(win);
1021 if (!win.intersect(s.active.finalCrop, &win)) {
1022 win.clear();
1023 }
1024 win = s.active.transform.inverse().transform(win);
1025 if (!win.intersect(computeBounds(), &win)) {
1026 win.clear();
1027 }
1028 }
Mathias Agopian13127d82013-03-05 17:47:11 -08001029
Mathias Agopian3f844832013-08-07 21:24:32 -07001030 float left = float(win.left) / float(s.active.w);
1031 float top = float(win.top) / float(s.active.h);
1032 float right = float(win.right) / float(s.active.w);
1033 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -08001034
Mathias Agopian875d8e12013-06-07 15:35:48 -07001035 // TODO: we probably want to generate the texture coords with the mesh
1036 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -07001037 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
1038 texCoords[0] = vec2(left, 1.0f - top);
1039 texCoords[1] = vec2(left, 1.0f - bottom);
1040 texCoords[2] = vec2(right, 1.0f - bottom);
1041 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -08001042
Mathias Agopian875d8e12013-06-07 15:35:48 -07001043 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -08001044 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001045 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001046 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001047}
1048
Dan Stoza9e56aa02015-11-02 13:00:03 -08001049#ifdef USE_HWC2
1050void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1051 bool callIntoHwc) {
1052 if (mHwcLayers.count(hwcId) == 0) {
1053 ALOGE("setCompositionType called without a valid HWC layer");
1054 return;
1055 }
1056 auto& hwcInfo = mHwcLayers[hwcId];
1057 auto& hwcLayer = hwcInfo.layer;
1058 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1059 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1060 if (hwcInfo.compositionType != type) {
1061 ALOGV(" actually setting");
1062 hwcInfo.compositionType = type;
1063 if (callIntoHwc) {
1064 auto error = hwcLayer->setCompositionType(type);
1065 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1066 "composition type %s: %s (%d)", mName.string(),
1067 to_string(type).c_str(), to_string(error).c_str(),
1068 static_cast<int32_t>(error));
1069 }
1070 }
1071}
1072
1073HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1074 if (mHwcLayers.count(hwcId) == 0) {
1075 ALOGE("getCompositionType called without a valid HWC layer");
1076 return HWC2::Composition::Invalid;
1077 }
1078 return mHwcLayers.at(hwcId).compositionType;
1079}
1080
1081void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1082 if (mHwcLayers.count(hwcId) == 0) {
1083 ALOGE("setClearClientTarget called without a valid HWC layer");
1084 return;
1085 }
1086 mHwcLayers[hwcId].clearClientTarget = clear;
1087}
1088
1089bool Layer::getClearClientTarget(int32_t hwcId) const {
1090 if (mHwcLayers.count(hwcId) == 0) {
1091 ALOGE("getClearClientTarget called without a valid HWC layer");
1092 return false;
1093 }
1094 return mHwcLayers.at(hwcId).clearClientTarget;
1095}
1096#endif
1097
Ruben Brunk1681d952014-06-27 15:51:55 -07001098uint32_t Layer::getProducerStickyTransform() const {
1099 int producerStickyTransform = 0;
1100 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1101 if (ret != OK) {
1102 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1103 strerror(-ret), ret);
1104 return 0;
1105 }
1106 return static_cast<uint32_t>(producerStickyTransform);
1107}
1108
Dan Stozacac35382016-01-27 12:21:06 -08001109uint64_t Layer::getHeadFrameNumber() const {
1110 Mutex::Autolock lock(mQueueItemLock);
1111 if (!mQueueItems.empty()) {
1112 return mQueueItems[0].mFrameNumber;
1113 } else {
1114 return mCurrentFrameNumber;
1115 }
1116}
1117
1118bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1119 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1120 // Don't bother with a SyncPoint, since we've already latched the
1121 // relevant frame
1122 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001123 }
1124
Dan Stozacac35382016-01-27 12:21:06 -08001125 Mutex::Autolock lock(mLocalSyncPointMutex);
1126 mLocalSyncPoints.push_back(point);
1127 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001128}
1129
Mathias Agopian13127d82013-03-05 17:47:11 -08001130void Layer::setFiltering(bool filtering) {
1131 mFiltering = filtering;
1132}
1133
1134bool Layer::getFiltering() const {
1135 return mFiltering;
1136}
1137
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001138// As documented in libhardware header, formats in the range
1139// 0x100 - 0x1FF are specific to the HAL implementation, and
1140// are known to have no alpha channel
1141// TODO: move definition for device-specific range into
1142// hardware.h, instead of using hard-coded values here.
1143#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1144
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001145bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001146 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1147 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001148 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001149 switch (format) {
1150 case HAL_PIXEL_FORMAT_RGBA_8888:
1151 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001152 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001153 }
1154 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001155 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001156}
1157
Mathias Agopian13127d82013-03-05 17:47:11 -08001158// ----------------------------------------------------------------------------
1159// local state
1160// ----------------------------------------------------------------------------
1161
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001162static void boundPoint(vec2* point, const Rect& crop) {
1163 if (point->x < crop.left) {
1164 point->x = crop.left;
1165 }
1166 if (point->x > crop.right) {
1167 point->x = crop.right;
1168 }
1169 if (point->y < crop.top) {
1170 point->y = crop.top;
1171 }
1172 if (point->y > crop.bottom) {
1173 point->y = crop.bottom;
1174 }
1175}
1176
Dan Stozac7014012014-02-14 15:03:43 -08001177void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1178 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001179{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001180 const Layer::State& s(getDrawingState());
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001181 const Transform tr(hw->getTransform());
Mathias Agopian13127d82013-03-05 17:47:11 -08001182 const uint32_t hw_h = hw->getHeight();
1183 Rect win(s.active.w, s.active.h);
1184 if (!s.active.crop.isEmpty()) {
1185 win.intersect(s.active.crop, &win);
1186 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001187 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001188 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001189
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001190 vec2 lt = vec2(win.left, win.top);
1191 vec2 lb = vec2(win.left, win.bottom);
1192 vec2 rb = vec2(win.right, win.bottom);
1193 vec2 rt = vec2(win.right, win.top);
1194
1195 if (!useIdentityTransform) {
1196 lt = s.active.transform.transform(lt);
1197 lb = s.active.transform.transform(lb);
1198 rb = s.active.transform.transform(rb);
1199 rt = s.active.transform.transform(rt);
1200 }
1201
1202 if (!s.active.finalCrop.isEmpty()) {
1203 boundPoint(&lt, s.active.finalCrop);
1204 boundPoint(&lb, s.active.finalCrop);
1205 boundPoint(&rb, s.active.finalCrop);
1206 boundPoint(&rt, s.active.finalCrop);
1207 }
1208
Mathias Agopianff2ed702013-09-01 21:36:12 -07001209 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001210 position[0] = tr.transform(lt);
1211 position[1] = tr.transform(lb);
1212 position[2] = tr.transform(rb);
1213 position[3] = tr.transform(rt);
Mathias Agopian3f844832013-08-07 21:24:32 -07001214 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001215 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001216 }
1217}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001218
Andy McFadden4125a4f2014-01-29 17:17:11 -08001219bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001220{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001221 // if we don't have a buffer yet, we're translucent regardless of the
1222 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001223 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001224 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001225 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001226
1227 // if the layer has the opaque flag, then we're always opaque,
1228 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001229 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001230}
1231
Dan Stoza23116082015-06-18 14:58:39 -07001232bool Layer::isSecure() const
1233{
1234 const Layer::State& s(mDrawingState);
1235 return (s.flags & layer_state_t::eLayerSecure);
1236}
1237
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001238bool Layer::isProtected() const
1239{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001240 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001241 return (activeBuffer != 0) &&
1242 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1243}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001244
Mathias Agopian13127d82013-03-05 17:47:11 -08001245bool Layer::isFixedSize() const {
1246 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1247}
1248
1249bool Layer::isCropped() const {
1250 return !mCurrentCrop.isEmpty();
1251}
1252
1253bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1254 return mNeedsFiltering || hw->needsFiltering();
1255}
1256
1257void Layer::setVisibleRegion(const Region& visibleRegion) {
1258 // always called from main thread
1259 this->visibleRegion = visibleRegion;
1260}
1261
1262void Layer::setCoveredRegion(const Region& coveredRegion) {
1263 // always called from main thread
1264 this->coveredRegion = coveredRegion;
1265}
1266
1267void Layer::setVisibleNonTransparentRegion(const Region&
1268 setVisibleNonTransparentRegion) {
1269 // always called from main thread
1270 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1271}
1272
1273// ----------------------------------------------------------------------------
1274// transaction
1275// ----------------------------------------------------------------------------
1276
Dan Stoza7dde5992015-05-22 09:51:44 -07001277void Layer::pushPendingState() {
1278 if (!mCurrentState.modified) {
1279 return;
1280 }
1281
Dan Stoza7dde5992015-05-22 09:51:44 -07001282 // If this transaction is waiting on the receipt of a frame, generate a sync
1283 // point and send it to the remote layer.
1284 if (mCurrentState.handle != nullptr) {
1285 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1286 sp<Layer> handleLayer = handle->owner.promote();
1287 if (handleLayer == nullptr) {
1288 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1289 // If we can't promote the layer we are intended to wait on,
1290 // then it is expired or otherwise invalid. Allow this transaction
1291 // to be applied as per normal (no synchronization).
1292 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001293 } else {
1294 auto syncPoint = std::make_shared<SyncPoint>(
1295 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001296 if (handleLayer->addSyncPoint(syncPoint)) {
1297 mRemoteSyncPoints.push_back(std::move(syncPoint));
1298 } else {
1299 // We already missed the frame we're supposed to synchronize
1300 // on, so go ahead and apply the state update
1301 mCurrentState.handle = nullptr;
1302 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001303 }
1304
Dan Stoza7dde5992015-05-22 09:51:44 -07001305 // Wake us up to check if the frame has been received
1306 setTransactionFlags(eTransactionNeeded);
1307 }
1308 mPendingStates.push_back(mCurrentState);
1309}
1310
1311void Layer::popPendingState() {
1312 auto oldFlags = mCurrentState.flags;
1313 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001314 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001315 (mCurrentState.flags & mCurrentState.mask);
1316
1317 mPendingStates.removeAt(0);
1318}
1319
1320bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001321 bool stateUpdateAvailable = false;
1322 while (!mPendingStates.empty()) {
1323 if (mPendingStates[0].handle != nullptr) {
1324 if (mRemoteSyncPoints.empty()) {
1325 // If we don't have a sync point for this, apply it anyway. It
1326 // will be visually wrong, but it should keep us from getting
1327 // into too much trouble.
1328 ALOGE("[%s] No local sync point found", mName.string());
1329 popPendingState();
1330 stateUpdateAvailable = true;
1331 continue;
1332 }
1333
Dan Stozacac35382016-01-27 12:21:06 -08001334 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1335 mPendingStates[0].frameNumber) {
1336 ALOGE("[%s] Unexpected sync point frame number found",
1337 mName.string());
1338
1339 // Signal our end of the sync point and then dispose of it
1340 mRemoteSyncPoints.front()->setTransactionApplied();
1341 mRemoteSyncPoints.pop_front();
1342 continue;
1343 }
1344
Dan Stoza7dde5992015-05-22 09:51:44 -07001345 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1346 // Apply the state update
1347 popPendingState();
1348 stateUpdateAvailable = true;
1349
1350 // Signal our end of the sync point and then dispose of it
1351 mRemoteSyncPoints.front()->setTransactionApplied();
1352 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001353 } else {
1354 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001355 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001356 } else {
1357 popPendingState();
1358 stateUpdateAvailable = true;
1359 }
1360 }
1361
1362 // If we still have pending updates, wake SurfaceFlinger back up and point
1363 // it at this layer so we can process them
1364 if (!mPendingStates.empty()) {
1365 setTransactionFlags(eTransactionNeeded);
1366 mFlinger->setTransactionFlags(eTraversalNeeded);
1367 }
1368
1369 mCurrentState.modified = false;
1370 return stateUpdateAvailable;
1371}
1372
1373void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001374 auto headFrameNumber = getHeadFrameNumber();
1375 Mutex::Autolock lock(mLocalSyncPointMutex);
1376 for (auto& point : mLocalSyncPoints) {
1377 if (headFrameNumber >= point->getFrameNumber()) {
1378 point->setFrameAvailable();
1379 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001380 }
1381}
1382
Mathias Agopian13127d82013-03-05 17:47:11 -08001383uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001384 ATRACE_CALL();
1385
Dan Stoza7dde5992015-05-22 09:51:44 -07001386 pushPendingState();
1387 if (!applyPendingStates()) {
1388 return 0;
1389 }
1390
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001391 const Layer::State& s(getDrawingState());
1392 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001393
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001394 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1395 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001396
1397 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001398 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001399 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001400 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001401 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1402 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1403 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1404 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001405 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1406 c.active.w, c.active.h,
1407 c.active.crop.left,
1408 c.active.crop.top,
1409 c.active.crop.right,
1410 c.active.crop.bottom,
1411 c.active.crop.getWidth(),
1412 c.active.crop.getHeight(),
1413 c.requested.w, c.requested.h,
1414 c.requested.crop.left,
1415 c.requested.crop.top,
1416 c.requested.crop.right,
1417 c.requested.crop.bottom,
1418 c.requested.crop.getWidth(),
1419 c.requested.crop.getHeight(),
1420 s.active.w, s.active.h,
1421 s.active.crop.left,
1422 s.active.crop.top,
1423 s.active.crop.right,
1424 s.active.crop.bottom,
1425 s.active.crop.getWidth(),
1426 s.active.crop.getHeight(),
1427 s.requested.w, s.requested.h,
1428 s.requested.crop.left,
1429 s.requested.crop.top,
1430 s.requested.crop.right,
1431 s.requested.crop.bottom,
1432 s.requested.crop.getWidth(),
1433 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001434
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001435 // record the new size, form this point on, when the client request
1436 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001437 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001438 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001439 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001440
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001441 if (!isFixedSize()) {
1442
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001443 const bool resizePending = (c.requested.w != c.active.w) ||
1444 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001445
Dan Stoza9e9b0442015-04-22 14:59:08 -07001446 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001447 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001448 // if we have a pending resize, unless we are in fixed-size mode.
1449 // the drawing state will be updated only once we receive a buffer
1450 // with the correct size.
1451 //
1452 // in particular, we want to make sure the clip (which is part
1453 // of the geometry state) is latched together with the size but is
1454 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001455 //
1456 // If a sideband stream is attached, however, we want to skip this
1457 // optimization so that transactions aren't missed when a buffer
1458 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001459
1460 flags |= eDontUpdateGeometryState;
1461 }
1462 }
1463
Mathias Agopian13127d82013-03-05 17:47:11 -08001464 // always set active to requested, unless we're asked not to
1465 // this is used by Layer, which special cases resizes.
1466 if (flags & eDontUpdateGeometryState) {
1467 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001468 Layer::State& editCurrentState(getCurrentState());
1469 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001470 }
1471
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001472 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001473 // invalidate and recompute the visible regions if needed
1474 flags |= Layer::eVisibleRegion;
1475 }
1476
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001477 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001478 // invalidate and recompute the visible regions if needed
1479 flags |= eVisibleRegion;
1480 this->contentDirty = true;
1481
1482 // we may use linear filtering, if the matrix scales us
Robert Carr3dcabfa2016-03-01 18:36:58 -08001483 const uint8_t type = c.active.transform.getType();
1484 mNeedsFiltering = (!c.active.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001485 (type >= Transform::SCALE));
1486 }
1487
1488 // Commit the transaction
1489 commitTransaction();
1490 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001491}
1492
Mathias Agopian13127d82013-03-05 17:47:11 -08001493void Layer::commitTransaction() {
1494 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001495}
1496
Mathias Agopian13127d82013-03-05 17:47:11 -08001497uint32_t Layer::getTransactionFlags(uint32_t flags) {
1498 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1499}
1500
1501uint32_t Layer::setTransactionFlags(uint32_t flags) {
1502 return android_atomic_or(flags, &mTransactionFlags);
1503}
1504
1505bool Layer::setPosition(float x, float y) {
Robert Carr3dcabfa2016-03-01 18:36:58 -08001506 if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
Mathias Agopian13127d82013-03-05 17:47:11 -08001507 return false;
1508 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001509 mCurrentState.requested.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001510 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001511 setTransactionFlags(eTransactionNeeded);
1512 return true;
1513}
1514bool Layer::setLayer(uint32_t z) {
1515 if (mCurrentState.z == z)
1516 return false;
1517 mCurrentState.sequence++;
1518 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001519 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001520 setTransactionFlags(eTransactionNeeded);
1521 return true;
1522}
1523bool Layer::setSize(uint32_t w, uint32_t h) {
1524 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1525 return false;
1526 mCurrentState.requested.w = w;
1527 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001528 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001529 setTransactionFlags(eTransactionNeeded);
1530 return true;
1531}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001532#ifdef USE_HWC2
1533bool Layer::setAlpha(float alpha) {
1534#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001535bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001536#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001537 if (mCurrentState.alpha == alpha)
1538 return false;
1539 mCurrentState.sequence++;
1540 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001541 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001542 setTransactionFlags(eTransactionNeeded);
1543 return true;
1544}
1545bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1546 mCurrentState.sequence++;
Robert Carr3dcabfa2016-03-01 18:36:58 -08001547 mCurrentState.requested.transform.set(
Mathias Agopian13127d82013-03-05 17:47:11 -08001548 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001549 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001550 setTransactionFlags(eTransactionNeeded);
1551 return true;
1552}
1553bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001554 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001555 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001556 setTransactionFlags(eTransactionNeeded);
1557 return true;
1558}
1559bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1560 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1561 if (mCurrentState.flags == newFlags)
1562 return false;
1563 mCurrentState.sequence++;
1564 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001565 mCurrentState.mask = mask;
1566 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001567 setTransactionFlags(eTransactionNeeded);
1568 return true;
1569}
1570bool Layer::setCrop(const Rect& crop) {
1571 if (mCurrentState.requested.crop == crop)
1572 return false;
1573 mCurrentState.sequence++;
1574 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001575 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001576 setTransactionFlags(eTransactionNeeded);
1577 return true;
1578}
Pablo Ceballosacbe6782016-03-04 17:54:21 +00001579bool Layer::setFinalCrop(const Rect& crop) {
1580 if (mCurrentState.requested.finalCrop == crop)
1581 return false;
1582 mCurrentState.sequence++;
1583 mCurrentState.requested.finalCrop = crop;
1584 mCurrentState.modified = true;
1585 setTransactionFlags(eTransactionNeeded);
1586 return true;
1587}
Mathias Agopian13127d82013-03-05 17:47:11 -08001588
1589bool Layer::setLayerStack(uint32_t layerStack) {
1590 if (mCurrentState.layerStack == layerStack)
1591 return false;
1592 mCurrentState.sequence++;
1593 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001594 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001595 setTransactionFlags(eTransactionNeeded);
1596 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001597}
1598
Dan Stoza7dde5992015-05-22 09:51:44 -07001599void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1600 uint64_t frameNumber) {
1601 mCurrentState.handle = handle;
1602 mCurrentState.frameNumber = frameNumber;
1603 // We don't set eTransactionNeeded, because just receiving a deferral
1604 // request without any other state updates shouldn't actually induce a delay
1605 mCurrentState.modified = true;
1606 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001607 mCurrentState.handle = nullptr;
1608 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001609 mCurrentState.modified = false;
1610}
1611
Dan Stozaee44edd2015-03-23 15:50:23 -07001612void Layer::useSurfaceDamage() {
1613 if (mFlinger->mForceFullDamage) {
1614 surfaceDamageRegion = Region::INVALID_REGION;
1615 } else {
1616 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1617 }
1618}
1619
1620void Layer::useEmptyDamage() {
1621 surfaceDamageRegion.clear();
1622}
1623
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001624// ----------------------------------------------------------------------------
1625// pageflip handling...
1626// ----------------------------------------------------------------------------
1627
Dan Stoza6b9454d2014-11-07 16:00:59 -08001628bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001629 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001630 return true;
1631 }
1632
Dan Stoza6b9454d2014-11-07 16:00:59 -08001633 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001634 if (mQueueItems.empty()) {
1635 return false;
1636 }
1637 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001638 nsecs_t expectedPresent =
1639 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001640
1641 // Ignore timestamps more than a second in the future
1642 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1643 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1644 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1645 expectedPresent);
1646
1647 bool isDue = timestamp < expectedPresent;
1648 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001649}
1650
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001651bool Layer::onPreComposition() {
1652 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001653 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001654}
1655
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001656void Layer::onPostComposition() {
1657 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001658 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001659 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1660
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001661 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001662 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001663 mFrameTracker.setFrameReadyFence(frameReadyFence);
1664 } else {
1665 // There was no fence for this frame, so assume that it was ready
1666 // to be presented at the desired present time.
1667 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1668 }
1669
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001670 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001671#ifdef USE_HWC2
1672 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1673#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001674 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001675#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001676 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001677 mFrameTracker.setActualPresentFence(presentFence);
1678 } else {
1679 // The HWC doesn't support present fences, so use the refresh
1680 // timestamp instead.
1681 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1682 mFrameTracker.setActualPresentTime(presentTime);
1683 }
1684
1685 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001686 mFrameLatencyNeeded = false;
1687 }
1688}
1689
Dan Stoza9e56aa02015-11-02 13:00:03 -08001690#ifdef USE_HWC2
1691void Layer::releasePendingBuffer() {
1692 mSurfaceFlingerConsumer->releasePendingBuffer();
1693}
1694#endif
1695
Mathias Agopianda27af92012-09-13 18:17:13 -07001696bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001697 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001698#ifdef USE_HWC2
1699 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1700 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1701#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001702 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001703 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001704#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001705}
1706
Mathias Agopian4fec8732012-06-29 14:12:52 -07001707Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001708{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001709 ATRACE_CALL();
1710
Jesse Hall399184a2014-03-03 15:42:54 -08001711 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1712 // mSidebandStreamChanged was true
1713 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001714 if (mSidebandStream != NULL) {
1715 setTransactionFlags(eTransactionNeeded);
1716 mFlinger->setTransactionFlags(eTraversalNeeded);
1717 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001718 recomputeVisibleRegions = true;
1719
1720 const State& s(getDrawingState());
Robert Carr3dcabfa2016-03-01 18:36:58 -08001721 return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001722 }
1723
Mathias Agopian4fec8732012-06-29 14:12:52 -07001724 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001725 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001726
1727 // if we've already called updateTexImage() without going through
1728 // a composition step, we have to skip this layer at this point
1729 // because we cannot call updateTeximage() without a corresponding
1730 // compositionComplete() call.
1731 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001732 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001733 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001734 }
1735
Jamie Gennis351a5132011-09-14 18:23:37 -07001736 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001737 const State& s(getDrawingState());
1738 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001739 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001740
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001741 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001742 Layer::State& front;
1743 Layer::State& current;
1744 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001745 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001746 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001747 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001748 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001749 recomputeVisibleRegions(recomputeVisibleRegions),
1750 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001751 }
1752
1753 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001754 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001755 if (buf == NULL) {
1756 return false;
1757 }
1758
1759 uint32_t bufWidth = buf->getWidth();
1760 uint32_t bufHeight = buf->getHeight();
1761
1762 // check that we received a buffer of the right size
1763 // (Take the buffer's orientation into account)
1764 if (item.mTransform & Transform::ROT_90) {
1765 swap(bufWidth, bufHeight);
1766 }
1767
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001768 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1769 if (front.active != front.requested) {
1770
1771 if (isFixedSize ||
1772 (bufWidth == front.requested.w &&
1773 bufHeight == front.requested.h))
1774 {
1775 // Here we pretend the transaction happened by updating the
1776 // current and drawing states. Drawing state is only accessed
1777 // in this thread, no need to have it locked
1778 front.active = front.requested;
1779
1780 // We also need to update the current state so that
1781 // we don't end-up overwriting the drawing state with
1782 // this stale current state during the next transaction
1783 //
1784 // NOTE: We don't need to hold the transaction lock here
1785 // because State::active is only accessed from this thread.
1786 current.active = front.active;
1787
1788 // recompute visible region
1789 recomputeVisibleRegions = true;
1790 }
1791
1792 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001793 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001794 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1795 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001796 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001797 front.active.w, front.active.h,
1798 front.active.crop.left,
1799 front.active.crop.top,
1800 front.active.crop.right,
1801 front.active.crop.bottom,
1802 front.active.crop.getWidth(),
1803 front.active.crop.getHeight(),
1804 front.requested.w, front.requested.h,
1805 front.requested.crop.left,
1806 front.requested.crop.top,
1807 front.requested.crop.right,
1808 front.requested.crop.bottom,
1809 front.requested.crop.getWidth(),
1810 front.requested.crop.getHeight());
1811 }
1812
Ruben Brunk1681d952014-06-27 15:51:55 -07001813 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001814 if (front.active.w != bufWidth ||
1815 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001816 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001817 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1818 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001819 return true;
1820 }
1821 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001822
1823 // if the transparent region has changed (this test is
1824 // conservative, but that's fine, worst case we're doing
1825 // a bit of extra work), we latch the new one and we
1826 // trigger a visible-region recompute.
1827 if (!front.activeTransparentRegion.isTriviallyEqual(
1828 front.requestedTransparentRegion)) {
1829 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001830
1831 // We also need to update the current state so that
1832 // we don't end-up overwriting the drawing state with
1833 // this stale current state during the next transaction
1834 //
1835 // NOTE: We don't need to hold the transaction lock here
1836 // because State::active is only accessed from this thread.
1837 current.activeTransparentRegion = front.activeTransparentRegion;
1838
1839 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001840 recomputeVisibleRegions = true;
1841 }
1842
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001843 return false;
1844 }
1845 };
1846
Ruben Brunk1681d952014-06-27 15:51:55 -07001847 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1848 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001849
Dan Stozacac35382016-01-27 12:21:06 -08001850
1851 // Check all of our local sync points to ensure that all transactions
1852 // which need to have been applied prior to the frame which is about to
1853 // be latched have signaled
1854
1855 auto headFrameNumber = getHeadFrameNumber();
1856 bool matchingFramesFound = false;
1857 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001858 {
Dan Stozacac35382016-01-27 12:21:06 -08001859 Mutex::Autolock lock(mLocalSyncPointMutex);
1860 for (auto& point : mLocalSyncPoints) {
1861 if (point->getFrameNumber() > headFrameNumber) {
1862 break;
1863 }
1864
1865 matchingFramesFound = true;
1866
1867 if (!point->frameIsAvailable()) {
1868 // We haven't notified the remote layer that the frame for
1869 // this point is available yet. Notify it now, and then
1870 // abort this attempt to latch.
1871 point->setFrameAvailable();
1872 allTransactionsApplied = false;
1873 break;
1874 }
1875
1876 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001877 }
1878 }
1879
Dan Stozacac35382016-01-27 12:21:06 -08001880 if (matchingFramesFound && !allTransactionsApplied) {
1881 mFlinger->signalLayerUpdate();
1882 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001883 }
1884
Pablo Ceballos06312182015-10-07 16:32:12 -07001885 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1886 // of the buffer queue isn't modified when the buffer queue is returning
1887 // BufferItem's that weren't actually queued. This can happen in single
1888 // buffer mode.
1889 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001890 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001891 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001892 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001893 if (updateResult == BufferQueue::PRESENT_LATER) {
1894 // Producer doesn't want buffer to be displayed yet. Signal a
1895 // layer update so we check again at the next opportunity.
1896 mFlinger->signalLayerUpdate();
1897 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001898 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1899 // If the buffer has been rejected, remove it from the shadow queue
1900 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001901 if (queuedBuffer) {
1902 Mutex::Autolock lock(mQueueItemLock);
1903 mQueueItems.removeAt(0);
1904 android_atomic_dec(&mQueuedFrames);
1905 }
Dan Stozaecc50402015-04-28 14:42:06 -07001906 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001907 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1908 // This can occur if something goes wrong when trying to create the
1909 // EGLImage for this buffer. If this happens, the buffer has already
1910 // been released, so we need to clean up the queue and bug out
1911 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001912 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001913 Mutex::Autolock lock(mQueueItemLock);
1914 mQueueItems.clear();
1915 android_atomic_and(0, &mQueuedFrames);
1916 }
1917
1918 // Once we have hit this state, the shadow queue may no longer
1919 // correctly reflect the incoming BufferQueue's contents, so even if
1920 // updateTexImage starts working, the only safe course of action is
1921 // to continue to ignore updates.
1922 mUpdateTexImageFailed = true;
1923
1924 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001925 }
1926
Pablo Ceballos06312182015-10-07 16:32:12 -07001927 if (queuedBuffer) {
1928 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001929 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1930
Dan Stoza6b9454d2014-11-07 16:00:59 -08001931 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001932
1933 // Remove any stale buffers that have been dropped during
1934 // updateTexImage
1935 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1936 mQueueItems.removeAt(0);
1937 android_atomic_dec(&mQueuedFrames);
1938 }
1939
Dan Stoza6b9454d2014-11-07 16:00:59 -08001940 mQueueItems.removeAt(0);
1941 }
1942
Dan Stozaecc50402015-04-28 14:42:06 -07001943
Andy McFadden1585c4d2013-06-28 13:52:40 -07001944 // Decrement the queued-frames count. Signal another event if we
1945 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001946 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001947 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001948 mFlinger->signalLayerUpdate();
1949 }
1950
1951 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001952 // something happened!
1953 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001954 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001955 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001956
Jamie Gennis351a5132011-09-14 18:23:37 -07001957 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001958 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001959 if (mActiveBuffer == NULL) {
1960 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001961 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001962 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001963
Mathias Agopian4824d402012-06-04 18:16:30 -07001964 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001965 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001966 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001967 // the first time we receive a buffer, we need to trigger a
1968 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001969 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001970 }
1971
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001972 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1973 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1974 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001975 if ((crop != mCurrentCrop) ||
1976 (transform != mCurrentTransform) ||
1977 (scalingMode != mCurrentScalingMode))
1978 {
1979 mCurrentCrop = crop;
1980 mCurrentTransform = transform;
1981 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001982 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001983 }
1984
1985 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001986 uint32_t bufWidth = mActiveBuffer->getWidth();
1987 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001988 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1989 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001990 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001991 }
1992 }
1993
1994 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001995 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001996 recomputeVisibleRegions = true;
1997 }
1998
Dan Stozacac35382016-01-27 12:21:06 -08001999 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2000
2001 // Remove any sync points corresponding to the buffer which was just
2002 // latched
2003 {
2004 Mutex::Autolock lock(mLocalSyncPointMutex);
2005 auto point = mLocalSyncPoints.begin();
2006 while (point != mLocalSyncPoints.end()) {
2007 if (!(*point)->frameIsAvailable() ||
2008 !(*point)->transactionIsApplied()) {
2009 // This sync point must have been added since we started
2010 // latching. Don't drop it yet.
2011 ++point;
2012 continue;
2013 }
2014
2015 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
2016 point = mLocalSyncPoints.erase(point);
2017 } else {
2018 ++point;
2019 }
2020 }
2021 }
2022
Mathias Agopian4fec8732012-06-29 14:12:52 -07002023 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07002024 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07002025
2026 // transform the dirty region to window-manager space
Robert Carr3dcabfa2016-03-01 18:36:58 -08002027 outDirtyRegion = (s.active.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07002028 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07002029 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002030}
2031
Mathias Agopiana67932f2011-04-20 14:20:59 -07002032uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07002033{
Mathias Agopiana67932f2011-04-20 14:20:59 -07002034 // TODO: should we do something special if mSecure is set?
2035 if (mProtectedByApp) {
2036 // need a hardware-protected path to external video sink
2037 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07002038 }
Riley Andrews03414a12014-07-01 14:22:59 -07002039 if (mPotentialCursor) {
2040 usage |= GraphicBuffer::USAGE_CURSOR;
2041 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07002042 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07002043 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07002044}
2045
Mathias Agopian84300952012-11-21 16:02:13 -08002046void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07002047 uint32_t orientation = 0;
2048 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08002049 // The transform hint is used to improve performance, but we can
2050 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07002051 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07002052 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07002053 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07002054 if (orientation & Transform::ROT_INVALID) {
2055 orientation = 0;
2056 }
2057 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08002058 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07002059}
2060
Mathias Agopian13127d82013-03-05 17:47:11 -08002061// ----------------------------------------------------------------------------
2062// debugging
2063// ----------------------------------------------------------------------------
2064
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002065void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08002066{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07002067 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08002068
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002069 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02002070 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002071 "+ %s %p (%s)\n",
2072 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02002073 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002074
Mathias Agopian2ca79392013-04-02 18:30:32 -07002075 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08002076 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07002077 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08002078 sp<Client> client(mClientRef.promote());
2079
Mathias Agopian74d211a2013-04-22 16:55:35 +02002080 result.appendFormat( " "
Pablo Ceballosacbe6782016-03-04 17:54:21 +00002081 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
2082 "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
Mathias Agopian13127d82013-03-05 17:47:11 -08002083 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08002084#ifdef USE_HWC2
2085 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
2086#else
Mathias Agopian13127d82013-03-05 17:47:11 -08002087 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08002088#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002089 " client=%p\n",
Robert Carr3dcabfa2016-03-01 18:36:58 -08002090 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 -08002091 s.active.crop.left, s.active.crop.top,
2092 s.active.crop.right, s.active.crop.bottom,
Pablo Ceballosacbe6782016-03-04 17:54:21 +00002093 s.active.finalCrop.left, s.active.finalCrop.top,
2094 s.active.finalCrop.right, s.active.finalCrop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002095 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002096 s.alpha, s.flags,
Robert Carr3dcabfa2016-03-01 18:36:58 -08002097 s.active.transform[0][0], s.active.transform[0][1],
2098 s.active.transform[1][0], s.active.transform[1][1],
Mathias Agopian13127d82013-03-05 17:47:11 -08002099 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002100
2101 sp<const GraphicBuffer> buf0(mActiveBuffer);
2102 uint32_t w0=0, h0=0, s0=0, f0=0;
2103 if (buf0 != 0) {
2104 w0 = buf0->getWidth();
2105 h0 = buf0->getHeight();
2106 s0 = buf0->getStride();
2107 f0 = buf0->format;
2108 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002109 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002110 " "
2111 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2112 " queued-frames=%d, mRefreshPending=%d\n",
2113 mFormat, w0, h0, s0,f0,
2114 mQueuedFrames, mRefreshPending);
2115
Mathias Agopian13127d82013-03-05 17:47:11 -08002116 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002117 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002118 }
2119}
2120
Svetoslavd85084b2014-03-20 10:28:31 -07002121void Layer::dumpFrameStats(String8& result) const {
2122 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002123}
2124
Svetoslavd85084b2014-03-20 10:28:31 -07002125void Layer::clearFrameStats() {
2126 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002127}
2128
Jamie Gennis6547ff42013-07-16 20:12:42 -07002129void Layer::logFrameStats() {
2130 mFrameTracker.logAndResetStats(mName);
2131}
2132
Svetoslavd85084b2014-03-20 10:28:31 -07002133void Layer::getFrameStats(FrameStats* outStats) const {
2134 mFrameTracker.getStats(outStats);
2135}
2136
Pablo Ceballos40845df2016-01-25 17:41:15 -08002137void Layer::getFenceData(String8* outName, uint64_t* outFrameNumber,
2138 bool* outIsGlesComposition, nsecs_t* outPostedTime,
2139 sp<Fence>* outAcquireFence, sp<Fence>* outPrevReleaseFence) const {
2140 *outName = mName;
2141 *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
2142
2143#ifdef USE_HWC2
2144 *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
2145 mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
2146 HWC2::Composition::Client : true;
2147#else
2148 *outIsGlesComposition = mIsGlesComposition;
2149#endif
2150 *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
2151 *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
2152 *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
2153}
Mathias Agopian13127d82013-03-05 17:47:11 -08002154// ---------------------------------------------------------------------------
2155
2156Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2157 const sp<Layer>& layer)
2158 : mFlinger(flinger), mLayer(layer) {
2159}
2160
2161Layer::LayerCleaner::~LayerCleaner() {
2162 // destroy client resources
2163 mFlinger->onLayerDestroyed(mLayer);
2164}
2165
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002166// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002167}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002168
2169#if defined(__gl_h_)
2170#error "don't include gl/gl.h in this file"
2171#endif
2172
2173#if defined(__gl2_h_)
2174#error "don't include gl2/gl2.h in this file"
2175#endif