blob: 4e7e9bef3e89efd04efbbeae2bd48422432ef51e [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dan Stoza9e56aa02015-11-02 13:00:03 -080017//#define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "Layer"
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080020#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080022#include <stdlib.h>
23#include <stdint.h>
24#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080025#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026
Mathias Agopiana67932f2011-04-20 14:20:59 -070027#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070028#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070029#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080030
31#include <utils/Errors.h>
32#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080033#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080035#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080036
Mathias Agopian3330b202009-10-05 17:07:12 -070037#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080039
Dan Stoza6b9454d2014-11-07 16:00:59 -080040#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080041#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042
43#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020044#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070045#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070047#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049
Mathias Agopian1b031492012-06-20 17:51:20 -070050#include "DisplayHardware/HWComposer.h"
51
Mathias Agopian875d8e12013-06-07 15:35:48 -070052#include "RenderEngine/RenderEngine.h"
53
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080054#define DEBUG_RESIZE 0
55
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080056namespace android {
57
58// ---------------------------------------------------------------------------
59
Mathias Agopian13127d82013-03-05 17:47:11 -080060int32_t Layer::sSequence = 1;
61
Mathias Agopian4d9b8222013-03-12 17:11:48 -070062Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
63 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080064 : contentDirty(false),
65 sequence(uint32_t(android_atomic_inc(&sSequence))),
66 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070067 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mPremultipliedAlpha(true),
69 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080070 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080071 mTransactionFlags(0),
Dan Stoza7dde5992015-05-22 09:51:44 -070072 mPendingStateMutex(),
73 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070074 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080075 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070076 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070077 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070078 mCurrentOpacity(true),
Dan Stozacac35382016-01-27 12:21:06 -080079 mCurrentFrameNumber(0),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080080 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080081 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080082 mFiltering(false),
83 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070084 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080085 mProtectedByApp(false),
86 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070087 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070088 mPotentialCursor(false),
89 mQueueItemLock(),
90 mQueueItemCondition(),
91 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070092 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080093 mUpdateTexImageFailed(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080094 mAutoRefresh(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080095{
Dan Stoza9e56aa02015-11-02 13:00:03 -080096#ifdef USE_HWC2
97 ALOGV("Creating Layer %s", name.string());
98#endif
99
Mathias Agopiana67932f2011-04-20 14:20:59 -0700100 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -0700101 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -0700102 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700103
104 uint32_t layerFlags = 0;
105 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -0800106 layerFlags |= layer_state_t::eLayerHidden;
107 if (flags & ISurfaceComposerClient::eOpaque)
108 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700109 if (flags & ISurfaceComposerClient::eSecure)
110 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700111
112 if (flags & ISurfaceComposerClient::eNonPremultiplied)
113 mPremultipliedAlpha = false;
114
115 mName = name;
116
117 mCurrentState.active.w = w;
118 mCurrentState.active.h = h;
119 mCurrentState.active.crop.makeInvalid();
120 mCurrentState.z = 0;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800121#ifdef USE_HWC2
122 mCurrentState.alpha = 1.0f;
123#else
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700124 mCurrentState.alpha = 0xFF;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800125#endif
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700126 mCurrentState.layerStack = 0;
127 mCurrentState.flags = layerFlags;
128 mCurrentState.sequence = 0;
129 mCurrentState.transform.set(0, 0);
130 mCurrentState.requested = mCurrentState.active;
131
132 // drawing state & current state are identical
133 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700134
Dan Stoza9e56aa02015-11-02 13:00:03 -0800135#ifdef USE_HWC2
136 const auto& hwc = flinger->getHwComposer();
137 const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
138 nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
139#else
Jamie Gennis6547ff42013-07-16 20:12:42 -0700140 nsecs_t displayPeriod =
141 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800142#endif
Jamie Gennis6547ff42013-07-16 20:12:42 -0700143 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800144}
145
Mathias Agopian3f844832013-08-07 21:24:32 -0700146void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800147 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700148 sp<IGraphicBufferProducer> producer;
149 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700150 BufferQueue::createBufferQueue(&producer, &consumer);
151 mProducer = new MonitoredProducer(producer, mFlinger);
152 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800153 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800154 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700155 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800156
Dan Stozac9d97202016-03-03 08:20:27 -0800157#ifndef TARGET_DISABLE_TRIPLE_BUFFERING
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700158 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800159#endif
Andy McFadden69052052012-09-14 16:10:11 -0700160
Mathias Agopian84300952012-11-21 16:02:13 -0800161 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
162 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700163}
164
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700165Layer::~Layer() {
Dan Stozacac35382016-01-27 12:21:06 -0800166 for (auto& point : mRemoteSyncPoints) {
167 point->setTransactionApplied();
168 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700169 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700170 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700171}
172
Mathias Agopian13127d82013-03-05 17:47:11 -0800173// ---------------------------------------------------------------------------
174// callbacks
175// ---------------------------------------------------------------------------
176
Dan Stoza9e56aa02015-11-02 13:00:03 -0800177#ifdef USE_HWC2
178void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
179 if (mHwcLayers.empty()) {
180 return;
181 }
182 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
183}
184#else
Dan Stozac7014012014-02-14 15:03:43 -0800185void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800186 HWComposer::HWCLayerInterface* layer) {
187 if (layer) {
188 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700189 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800190 }
191}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800192#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800193
Dan Stoza6b9454d2014-11-07 16:00:59 -0800194void Layer::onFrameAvailable(const BufferItem& item) {
195 // Add this buffer from our internal queue tracker
196 { // Autolock scope
197 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700198
199 // Reset the frame number tracker when we receive the first buffer after
200 // a frame number reset
201 if (item.mFrameNumber == 1) {
202 mLastFrameNumberReceived = 0;
203 }
204
205 // Ensure that callbacks are handled in order
206 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
207 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
208 ms2ns(500));
209 if (result != NO_ERROR) {
210 ALOGE("[%s] Timed out waiting on callback", mName.string());
211 }
212 }
213
Dan Stoza6b9454d2014-11-07 16:00:59 -0800214 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700215 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700216
217 // Wake up any pending callbacks
218 mLastFrameNumberReceived = item.mFrameNumber;
219 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800220 }
221
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800222 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700223}
224
Dan Stoza6b9454d2014-11-07 16:00:59 -0800225void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700226 { // Autolock scope
227 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700228
Dan Stoza7dde5992015-05-22 09:51:44 -0700229 // Ensure that callbacks are handled in order
230 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
231 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
232 ms2ns(500));
233 if (result != NO_ERROR) {
234 ALOGE("[%s] Timed out waiting on callback", mName.string());
235 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700236 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700237
238 if (mQueueItems.empty()) {
239 ALOGE("Can't replace a frame on an empty queue");
240 return;
241 }
242 mQueueItems.editItemAt(0) = item;
243
244 // Wake up any pending callbacks
245 mLastFrameNumberReceived = item.mFrameNumber;
246 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700247 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800248}
249
Jesse Hall399184a2014-03-03 15:42:54 -0800250void Layer::onSidebandStreamChanged() {
251 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
252 // mSidebandStreamChanged was false
253 mFlinger->signalLayerUpdate();
254 }
255}
256
Mathias Agopian67106042013-03-14 19:18:13 -0700257// called with SurfaceFlinger::mStateLock from the drawing thread after
258// the layer has been remove from the current state list (and just before
259// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800260void Layer::onRemoved() {
Pablo Ceballose338df12015-12-03 11:44:46 -0800261 sp<Client> c(mClientRef.promote());
262 if (c != 0) {
263 c->detachLayer(this);
264 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800265 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700266}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700267
Mathias Agopian13127d82013-03-05 17:47:11 -0800268// ---------------------------------------------------------------------------
269// set-up
270// ---------------------------------------------------------------------------
271
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700272const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800273 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800274}
275
Mathias Agopianf9d93272009-06-19 17:00:27 -0700276status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800277 PixelFormat format, uint32_t flags)
278{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700279 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700280 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700281
282 // never allow a surface larger than what our underlying GL implementation
283 // can handle.
284 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800285 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700286 return BAD_VALUE;
287 }
288
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700289 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700290
Riley Andrews03414a12014-07-01 14:22:59 -0700291 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700292 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700293 mCurrentOpacity = getOpacityForFormat(format);
294
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800295 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
296 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
297 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700298
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800299 return NO_ERROR;
300}
301
Dan Stoza7dde5992015-05-22 09:51:44 -0700302/*
303 * The layer handle is just a BBinder object passed to the client
304 * (remote process) -- we don't keep any reference on our side such that
305 * the dtor is called when the remote side let go of its reference.
306 *
307 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
308 * this layer when the handle is destroyed.
309 */
310class Layer::Handle : public BBinder, public LayerCleaner {
311 public:
312 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
313 : LayerCleaner(flinger, layer), owner(layer) {}
314
315 wp<Layer> owner;
316};
317
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700318sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800319 Mutex::Autolock _l(mLock);
320
321 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700322 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800323
324 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700325
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700326 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800327}
328
Dan Stozab9b08832014-03-13 11:55:57 -0700329sp<IGraphicBufferProducer> Layer::getProducer() const {
330 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700331}
332
Mathias Agopian13127d82013-03-05 17:47:11 -0800333// ---------------------------------------------------------------------------
334// h/w composer set-up
335// ---------------------------------------------------------------------------
336
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800337Rect Layer::getContentCrop() const {
338 // this is the crop rectangle that applies to the buffer
339 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700340 Rect crop;
341 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800342 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700343 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800344 } else if (mActiveBuffer != NULL) {
345 // otherwise we use the whole buffer
346 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700347 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800348 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700349 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700350 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700351 return crop;
352}
353
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700354static Rect reduce(const Rect& win, const Region& exclude) {
355 if (CC_LIKELY(exclude.isEmpty())) {
356 return win;
357 }
358 if (exclude.isRect()) {
359 return win.reduce(exclude.getBounds());
360 }
361 return Region(win).subtract(exclude).getBounds();
362}
363
Mathias Agopian13127d82013-03-05 17:47:11 -0800364Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700365 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700366 return computeBounds(s.activeTransparentRegion);
367}
368
369Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
370 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800371 Rect win(s.active.w, s.active.h);
372 if (!s.active.crop.isEmpty()) {
373 win.intersect(s.active.crop, &win);
374 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700375 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700376 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800377}
378
Mathias Agopian6b442672013-07-09 21:24:52 -0700379FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800380 // the content crop is the area of the content that gets scaled to the
381 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700382 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800383
384 // the active.crop is the area of the window that gets cropped, but not
385 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700386 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800387
388 // apply the projection's clipping to the window crop in
389 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700390 // if there are no window scaling involved, this operation will map to full
391 // pixels in the buffer.
392 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
393 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700394
395 Rect activeCrop(s.active.w, s.active.h);
396 if (!s.active.crop.isEmpty()) {
397 activeCrop = s.active.crop;
398 }
399
400 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800401 activeCrop.intersect(hw->getViewport(), &activeCrop);
402 activeCrop = s.transform.inverse().transform(activeCrop);
403
Michael Lentine28ea2172014-11-19 18:32:37 -0800404 // This needs to be here as transform.transform(Rect) computes the
405 // transformed rect and then takes the bounding box of the result before
406 // returning. This means
407 // transform.inverse().transform(transform.transform(Rect)) != Rect
408 // in which case we need to make sure the final rect is clipped to the
409 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800410 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
411
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700412 // subtract the transparent region and snap to the bounds
413 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
414
Mathias Agopian13127d82013-03-05 17:47:11 -0800415 if (!activeCrop.isEmpty()) {
416 // Transform the window crop to match the buffer coordinate system,
417 // which means using the inverse of the current transform set on the
418 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700419 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700420 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
421 /*
422 * the code below applies the display's inverse transform to the buffer
423 */
424 uint32_t invTransformOrient = hw->getOrientationTransform();
425 // calculate the inverse transform
426 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
427 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
428 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700429 // If the transform has been rotated the axis of flip has been swapped
430 // so we need to swap which flip operations we are performing
431 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
432 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
433 if (is_h_flipped != is_v_flipped) {
434 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
435 NATIVE_WINDOW_TRANSFORM_FLIP_H;
436 }
Michael Lentinef7551402014-08-18 16:35:43 -0700437 }
438 // and apply to the current transform
439 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
440 }
441
Mathias Agopian13127d82013-03-05 17:47:11 -0800442 int winWidth = s.active.w;
443 int winHeight = s.active.h;
444 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700445 // If the activeCrop has been rotate the ends are rotated but not
446 // the space itself so when transforming ends back we can't rely on
447 // a modification of the axes of rotation. To account for this we
448 // need to reorient the inverse rotation in terms of the current
449 // axes of rotation.
450 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
451 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
452 if (is_h_flipped == is_v_flipped) {
453 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
454 NATIVE_WINDOW_TRANSFORM_FLIP_H;
455 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800456 winWidth = s.active.h;
457 winHeight = s.active.w;
458 }
459 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700460 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800461
Mathias Agopian6b442672013-07-09 21:24:52 -0700462 // below, crop is intersected with winCrop expressed in crop's coordinate space
463 float xScale = crop.getWidth() / float(winWidth);
464 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800465
Michael Lentinef7551402014-08-18 16:35:43 -0700466 float insetL = winCrop.left * xScale;
467 float insetT = winCrop.top * yScale;
468 float insetR = (winWidth - winCrop.right ) * xScale;
469 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800470
471 crop.left += insetL;
472 crop.top += insetT;
473 crop.right -= insetR;
474 crop.bottom -= insetB;
475 }
476 return crop;
477}
478
Dan Stoza9e56aa02015-11-02 13:00:03 -0800479#ifdef USE_HWC2
480void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
481#else
Mathias Agopian4fec8732012-06-29 14:12:52 -0700482void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700483 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700484 HWComposer::HWCLayerInterface& layer)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800485#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700486{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800487#ifdef USE_HWC2
488 const auto hwcId = displayDevice->getHwcDisplayId();
489 auto& hwcInfo = mHwcLayers[hwcId];
490#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800491 layer.setDefaultState();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800492#endif
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700493
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700494 // enable this layer
Dan Stoza9e56aa02015-11-02 13:00:03 -0800495#ifdef USE_HWC2
496 hwcInfo.forceClientComposition = false;
497
498 if (isSecure() && !displayDevice->isSecure()) {
499 hwcInfo.forceClientComposition = true;
500 }
501
502 auto& hwcLayer = hwcInfo.layer;
503#else
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700504 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700505
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700506 if (isSecure() && !hw->isSecure()) {
507 layer.setSkip(true);
508 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800509#endif
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700510
Mathias Agopian13127d82013-03-05 17:47:11 -0800511 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700512 const State& s(getDrawingState());
Dan Stoza9e56aa02015-11-02 13:00:03 -0800513#ifdef USE_HWC2
514 if (!isOpaque(s) || s.alpha != 1.0f) {
515 auto blendMode = mPremultipliedAlpha ?
516 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
517 auto error = hwcLayer->setBlendMode(blendMode);
518 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
519 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
520 to_string(error).c_str(), static_cast<int32_t>(error));
521 }
522#else
Andy McFadden4125a4f2014-01-29 17:17:11 -0800523 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800524 layer.setBlending(mPremultipliedAlpha ?
525 HWC_BLENDING_PREMULT :
526 HWC_BLENDING_COVERAGE);
527 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800528#endif
Mathias Agopian13127d82013-03-05 17:47:11 -0800529
530 // apply the layer's transform, followed by the display's global transform
531 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700532 Region activeTransparentRegion(s.activeTransparentRegion);
533 if (!s.active.crop.isEmpty()) {
534 Rect activeCrop(s.active.crop);
535 activeCrop = s.transform.transform(activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800536#ifdef USE_HWC2
537 activeCrop.intersect(displayDevice->getViewport(), &activeCrop);
538#else
Michael Lentine6c925ed2014-09-26 17:55:01 -0700539 activeCrop.intersect(hw->getViewport(), &activeCrop);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800540#endif
Michael Lentine6c925ed2014-09-26 17:55:01 -0700541 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800542 // This needs to be here as transform.transform(Rect) computes the
543 // transformed rect and then takes the bounding box of the result before
544 // returning. This means
545 // transform.inverse().transform(transform.transform(Rect)) != Rect
546 // in which case we need to make sure the final rect is clipped to the
547 // display bounds.
548 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700549 // mark regions outside the crop as transparent
550 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
551 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
552 s.active.w, s.active.h));
553 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
554 activeCrop.left, activeCrop.bottom));
555 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
556 s.active.w, activeCrop.bottom));
557 }
558 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800559#ifdef USE_HWC2
560 frame.intersect(displayDevice->getViewport(), &frame);
561 const Transform& tr(displayDevice->getTransform());
562 Rect transformedFrame = tr.transform(frame);
563 auto error = hwcLayer->setDisplayFrame(transformedFrame);
564 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
565 "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
566 transformedFrame.top, transformedFrame.right,
567 transformedFrame.bottom, to_string(error).c_str(),
568 static_cast<int32_t>(error));
569
570 FloatRect sourceCrop = computeCrop(displayDevice);
571 error = hwcLayer->setSourceCrop(sourceCrop);
572 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
573 "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
574 sourceCrop.left, sourceCrop.top, sourceCrop.right,
575 sourceCrop.bottom, to_string(error).c_str(),
576 static_cast<int32_t>(error));
577
578 error = hwcLayer->setPlaneAlpha(s.alpha);
579 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
580 "%s (%d)", mName.string(), s.alpha, to_string(error).c_str(),
581 static_cast<int32_t>(error));
582
583 error = hwcLayer->setZOrder(s.z);
584 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
585 mName.string(), s.z, to_string(error).c_str(),
586 static_cast<int32_t>(error));
587#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800588 frame.intersect(hw->getViewport(), &frame);
589 const Transform& tr(hw->getTransform());
590 layer.setFrame(tr.transform(frame));
591 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800592 layer.setPlaneAlpha(s.alpha);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800593#endif
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800594
Mathias Agopian29a367b2011-07-12 14:51:45 -0700595 /*
596 * Transformations are applied in this order:
597 * 1) buffer orientation/flip/mirror
598 * 2) state transformation (window manager)
599 * 3) layer orientation (screen orientation)
600 * (NOTE: the matrices are multiplied in reverse order)
601 */
602
603 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700604 Transform transform(tr * s.transform * bufferOrientation);
605
606 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
607 /*
608 * the code below applies the display's inverse transform to the buffer
609 */
Dan Stoza9e56aa02015-11-02 13:00:03 -0800610#ifdef USE_HWC2
611 uint32_t invTransform = displayDevice->getOrientationTransform();
612#else
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700613 uint32_t invTransform = hw->getOrientationTransform();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800614#endif
Michael Lentine14409632014-08-19 11:27:30 -0700615 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700616 // calculate the inverse transform
617 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
618 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
619 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700620 // If the transform has been rotated the axis of flip has been swapped
621 // so we need to swap which flip operations we are performing
622 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
623 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
624 if (is_h_flipped != is_v_flipped) {
625 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
626 NATIVE_WINDOW_TRANSFORM_FLIP_H;
627 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700628 }
629 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700630 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700631 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700632
633 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800634 const uint32_t orientation = transform.getOrientation();
Dan Stoza9e56aa02015-11-02 13:00:03 -0800635#ifdef USE_HWC2
636 if (orientation & Transform::ROT_INVALID) {
637 // we can only handle simple transformation
638 hwcInfo.forceClientComposition = true;
639 } else {
640 auto transform = static_cast<HWC2::Transform>(orientation);
641 auto error = hwcLayer->setTransform(transform);
642 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
643 "%s (%d)", mName.string(), to_string(transform).c_str(),
644 to_string(error).c_str(), static_cast<int32_t>(error));
645 }
646#else
Mathias Agopian13127d82013-03-05 17:47:11 -0800647 if (orientation & Transform::ROT_INVALID) {
648 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700649 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700650 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800651 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700652 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800653#endif
Mathias Agopiana350ff92010-08-10 17:14:02 -0700654}
655
Dan Stoza9e56aa02015-11-02 13:00:03 -0800656#ifdef USE_HWC2
657void Layer::forceClientComposition(int32_t hwcId) {
658 if (mHwcLayers.count(hwcId) == 0) {
659 ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
660 return;
661 }
662
663 mHwcLayers[hwcId].forceClientComposition = true;
664}
665#endif
666
667#ifdef USE_HWC2
668void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
669 // Apply this display's projection's viewport to the visible region
670 // before giving it to the HWC HAL.
671 const Transform& tr = displayDevice->getTransform();
672 const auto& viewport = displayDevice->getViewport();
673 Region visible = tr.transform(visibleRegion.intersect(viewport));
674 auto hwcId = displayDevice->getHwcDisplayId();
675 auto& hwcLayer = mHwcLayers[hwcId].layer;
676 auto error = hwcLayer->setVisibleRegion(visible);
677 if (error != HWC2::Error::None) {
678 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
679 to_string(error).c_str(), static_cast<int32_t>(error));
680 visible.dump(LOG_TAG);
681 }
682
683 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
684 if (error != HWC2::Error::None) {
685 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
686 to_string(error).c_str(), static_cast<int32_t>(error));
687 surfaceDamageRegion.dump(LOG_TAG);
688 }
689
690 auto compositionType = HWC2::Composition::Invalid;
691 if (mSidebandStream.get()) {
692 compositionType = HWC2::Composition::Sideband;
693 auto error = hwcLayer->setSidebandStream(mSidebandStream->handle());
694 if (error != HWC2::Error::None) {
695 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
696 mName.string(), mSidebandStream->handle(),
697 to_string(error).c_str(), static_cast<int32_t>(error));
698 return;
699 }
700 } else {
701 if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr) {
702 compositionType = HWC2::Composition::Client;
703 auto error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
704 if (error != HWC2::Error::None) {
705 ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
706 to_string(error).c_str(), static_cast<int32_t>(error));
707 return;
708 }
709 } else {
710 if (mPotentialCursor) {
711 compositionType = HWC2::Composition::Cursor;
712 }
713 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
714 auto error = hwcLayer->setBuffer(mActiveBuffer->handle,
715 acquireFence);
716 if (error != HWC2::Error::None) {
717 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
718 mActiveBuffer->handle, to_string(error).c_str(),
719 static_cast<int32_t>(error));
720 return;
721 }
722 // If it's not a cursor, default to device composition
723 }
724 }
725
726 if (mHwcLayers[hwcId].forceClientComposition) {
727 ALOGV("[%s] Forcing Client composition", mName.string());
728 setCompositionType(hwcId, HWC2::Composition::Client);
729 } else if (compositionType != HWC2::Composition::Invalid) {
730 ALOGV("[%s] Requesting %s composition", mName.string(),
731 to_string(compositionType).c_str());
732 setCompositionType(hwcId, compositionType);
733 } else {
734 ALOGV("[%s] Requesting Device composition", mName.string());
735 setCompositionType(hwcId, HWC2::Composition::Device);
736 }
737}
738#else
Mathias Agopian42977342012-08-05 00:40:46 -0700739void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700740 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800741 // we have to set the visible region on every frame because
742 // we currently free it during onLayerDisplayed(), which is called
743 // after HWComposer::commit() -- every frame.
744 // Apply this display's projection's viewport to the visible region
745 // before giving it to the HWC HAL.
746 const Transform& tr = hw->getTransform();
747 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
748 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700749 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700750
Jesse Hall399184a2014-03-03 15:42:54 -0800751 if (mSidebandStream.get()) {
752 layer.setSidebandStream(mSidebandStream);
753 } else {
754 // NOTE: buffer can be NULL if the client never drew into this
755 // layer yet, or if we ran out of memory
756 layer.setBuffer(mActiveBuffer);
757 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700758}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800759#endif
Jesse Halldc5b4852012-06-29 15:21:18 -0700760
Dan Stoza9e56aa02015-11-02 13:00:03 -0800761#ifdef USE_HWC2
762void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
763 auto hwcId = displayDevice->getHwcDisplayId();
764 if (mHwcLayers.count(hwcId) == 0 ||
765 getCompositionType(hwcId) != HWC2::Composition::Cursor) {
766 return;
767 }
768
769 // This gives us only the "orientation" component of the transform
770 const State& s(getCurrentState());
771
772 // Apply the layer's transform, followed by the display's global transform
773 // Here we're guaranteed that the layer's transform preserves rects
774 Rect win(s.active.w, s.active.h);
775 if (!s.active.crop.isEmpty()) {
776 win.intersect(s.active.crop, &win);
777 }
778 // Subtract the transparent region and snap to the bounds
779 Rect bounds = reduce(win, s.activeTransparentRegion);
780 Rect frame(s.transform.transform(bounds));
781 frame.intersect(displayDevice->getViewport(), &frame);
782 auto& displayTransform(displayDevice->getTransform());
783 auto position = displayTransform.transform(frame);
784
785 auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
786 position.top);
787 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
788 "to (%d, %d): %s (%d)", mName.string(), position.left,
789 position.top, to_string(error).c_str(),
790 static_cast<int32_t>(error));
791}
792#else
Dan Stozac7014012014-02-14 15:03:43 -0800793void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700794 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700795 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700796
797 // TODO: there is a possible optimization here: we only need to set the
798 // acquire fence the first time a new buffer is acquired on EACH display.
799
Riley Andrews03414a12014-07-01 14:22:59 -0700800 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800801 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800802 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700803 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700804 if (fenceFd == -1) {
805 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
806 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700807 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700808 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700809 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700810}
811
Riley Andrews03414a12014-07-01 14:22:59 -0700812Rect Layer::getPosition(
813 const sp<const DisplayDevice>& hw)
814{
815 // this gives us only the "orientation" component of the transform
816 const State& s(getCurrentState());
817
818 // apply the layer's transform, followed by the display's global transform
819 // here we're guaranteed that the layer's transform preserves rects
820 Rect win(s.active.w, s.active.h);
821 if (!s.active.crop.isEmpty()) {
822 win.intersect(s.active.crop, &win);
823 }
824 // subtract the transparent region and snap to the bounds
825 Rect bounds = reduce(win, s.activeTransparentRegion);
826 Rect frame(s.transform.transform(bounds));
827 frame.intersect(hw->getViewport(), &frame);
828 const Transform& tr(hw->getTransform());
829 return Rect(tr.transform(frame));
830}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800831#endif
Riley Andrews03414a12014-07-01 14:22:59 -0700832
Mathias Agopian13127d82013-03-05 17:47:11 -0800833// ---------------------------------------------------------------------------
834// drawing...
835// ---------------------------------------------------------------------------
836
837void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800838 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800839}
840
Dan Stozac7014012014-02-14 15:03:43 -0800841void Layer::draw(const sp<const DisplayDevice>& hw,
842 bool useIdentityTransform) const {
843 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800844}
845
Dan Stozac7014012014-02-14 15:03:43 -0800846void Layer::draw(const sp<const DisplayDevice>& hw) const {
847 onDraw(hw, Region(hw->bounds()), false);
848}
849
850void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
851 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800852{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800853 ATRACE_CALL();
854
Mathias Agopiana67932f2011-04-20 14:20:59 -0700855 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800856 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700857 // in fact never been drawn into. This happens frequently with
858 // SurfaceView because the WindowManager can't know when the client
859 // has drawn the first time.
860
861 // If there is nothing under us, we paint the screen in black, otherwise
862 // we just skip this update.
863
864 // figure out if there is something below us
865 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700866 const SurfaceFlinger::LayerVector& drawingLayers(
867 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700868 const size_t count = drawingLayers.size();
869 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800870 const sp<Layer>& layer(drawingLayers[i]);
871 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700872 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700873 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700874 }
875 // if not everything below us is covered, we plug the holes!
876 Region holes(clip.subtract(under));
877 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700878 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700879 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800880 return;
881 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700882
Andy McFadden97eba892012-12-11 15:21:45 -0800883 // Bind the current buffer to the GL texture, and wait for it to be
884 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800885 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
886 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800887 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700888 // Go ahead and draw the buffer anyway; no matter what we do the screen
889 // is probably going to have something visibly wrong.
890 }
891
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700892 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
893
Mathias Agopian875d8e12013-06-07 15:35:48 -0700894 RenderEngine& engine(mFlinger->getRenderEngine());
895
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700896 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700897 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700898 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700899
900 // Query the texture matrix given our current filtering mode.
901 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800902 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
903 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700904
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700905 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
906
907 /*
908 * the code below applies the display's inverse transform to the texture transform
909 */
910
911 // create a 4x4 transform matrix from the display transform flags
912 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
913 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
914 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
915
916 mat4 tr;
917 uint32_t transform = hw->getOrientationTransform();
918 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
919 tr = tr * rot90;
920 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
921 tr = tr * flipH;
922 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
923 tr = tr * flipV;
924
925 // calculate the inverse
926 tr = inverse(tr);
927
928 // and finally apply it to the original texture matrix
929 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
930 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
931 }
932
Jamie Genniscbb1a952012-05-08 17:05:52 -0700933 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700934 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
935 mTexture.setFiltering(useFiltering);
936 mTexture.setMatrix(textureMatrix);
937
938 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700939 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700940 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700941 }
Dan Stozac7014012014-02-14 15:03:43 -0800942 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700943 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800944}
945
Mathias Agopian13127d82013-03-05 17:47:11 -0800946
Dan Stozac7014012014-02-14 15:03:43 -0800947void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
948 const Region& /* clip */, float red, float green, float blue,
949 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800950{
Mathias Agopian19733a32013-08-28 18:13:56 -0700951 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800952 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700953 engine.setupFillWithColor(red, green, blue, alpha);
954 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800955}
956
957void Layer::clearWithOpenGL(
958 const sp<const DisplayDevice>& hw, const Region& clip) const {
959 clearWithOpenGL(hw, clip, 0,0,0,0);
960}
961
Dan Stozac7014012014-02-14 15:03:43 -0800962void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
963 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700964 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800965
Dan Stozac7014012014-02-14 15:03:43 -0800966 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800967
Mathias Agopian13127d82013-03-05 17:47:11 -0800968 /*
969 * NOTE: the way we compute the texture coordinates here produces
970 * different results than when we take the HWC path -- in the later case
971 * the "source crop" is rounded to texel boundaries.
972 * This can produce significantly different results when the texture
973 * is scaled by a large amount.
974 *
975 * The GL code below is more logical (imho), and the difference with
976 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700977 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800978 * GL composition when a buffer scaling is applied (maybe with some
979 * minimal value)? Or, we could make GL behave like HWC -- but this feel
980 * like more of a hack.
981 */
982 const Rect win(computeBounds());
983
Mathias Agopian3f844832013-08-07 21:24:32 -0700984 float left = float(win.left) / float(s.active.w);
985 float top = float(win.top) / float(s.active.h);
986 float right = float(win.right) / float(s.active.w);
987 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800988
Mathias Agopian875d8e12013-06-07 15:35:48 -0700989 // TODO: we probably want to generate the texture coords with the mesh
990 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700991 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
992 texCoords[0] = vec2(left, 1.0f - top);
993 texCoords[1] = vec2(left, 1.0f - bottom);
994 texCoords[2] = vec2(right, 1.0f - bottom);
995 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800996
Mathias Agopian875d8e12013-06-07 15:35:48 -0700997 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800998 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700999 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -07001000 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -08001001}
1002
Dan Stoza9e56aa02015-11-02 13:00:03 -08001003#ifdef USE_HWC2
1004void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
1005 bool callIntoHwc) {
1006 if (mHwcLayers.count(hwcId) == 0) {
1007 ALOGE("setCompositionType called without a valid HWC layer");
1008 return;
1009 }
1010 auto& hwcInfo = mHwcLayers[hwcId];
1011 auto& hwcLayer = hwcInfo.layer;
1012 ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
1013 to_string(type).c_str(), static_cast<int>(callIntoHwc));
1014 if (hwcInfo.compositionType != type) {
1015 ALOGV(" actually setting");
1016 hwcInfo.compositionType = type;
1017 if (callIntoHwc) {
1018 auto error = hwcLayer->setCompositionType(type);
1019 ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
1020 "composition type %s: %s (%d)", mName.string(),
1021 to_string(type).c_str(), to_string(error).c_str(),
1022 static_cast<int32_t>(error));
1023 }
1024 }
1025}
1026
1027HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
1028 if (mHwcLayers.count(hwcId) == 0) {
1029 ALOGE("getCompositionType called without a valid HWC layer");
1030 return HWC2::Composition::Invalid;
1031 }
1032 return mHwcLayers.at(hwcId).compositionType;
1033}
1034
1035void Layer::setClearClientTarget(int32_t hwcId, bool clear) {
1036 if (mHwcLayers.count(hwcId) == 0) {
1037 ALOGE("setClearClientTarget called without a valid HWC layer");
1038 return;
1039 }
1040 mHwcLayers[hwcId].clearClientTarget = clear;
1041}
1042
1043bool Layer::getClearClientTarget(int32_t hwcId) const {
1044 if (mHwcLayers.count(hwcId) == 0) {
1045 ALOGE("getClearClientTarget called without a valid HWC layer");
1046 return false;
1047 }
1048 return mHwcLayers.at(hwcId).clearClientTarget;
1049}
1050#endif
1051
Ruben Brunk1681d952014-06-27 15:51:55 -07001052uint32_t Layer::getProducerStickyTransform() const {
1053 int producerStickyTransform = 0;
1054 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
1055 if (ret != OK) {
1056 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
1057 strerror(-ret), ret);
1058 return 0;
1059 }
1060 return static_cast<uint32_t>(producerStickyTransform);
1061}
1062
Dan Stozacac35382016-01-27 12:21:06 -08001063uint64_t Layer::getHeadFrameNumber() const {
1064 Mutex::Autolock lock(mQueueItemLock);
1065 if (!mQueueItems.empty()) {
1066 return mQueueItems[0].mFrameNumber;
1067 } else {
1068 return mCurrentFrameNumber;
1069 }
1070}
1071
1072bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
1073 if (point->getFrameNumber() <= mCurrentFrameNumber) {
1074 // Don't bother with a SyncPoint, since we've already latched the
1075 // relevant frame
1076 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -07001077 }
1078
Dan Stozacac35382016-01-27 12:21:06 -08001079 Mutex::Autolock lock(mLocalSyncPointMutex);
1080 mLocalSyncPoints.push_back(point);
1081 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -07001082}
1083
Mathias Agopian13127d82013-03-05 17:47:11 -08001084void Layer::setFiltering(bool filtering) {
1085 mFiltering = filtering;
1086}
1087
1088bool Layer::getFiltering() const {
1089 return mFiltering;
1090}
1091
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001092// As documented in libhardware header, formats in the range
1093// 0x100 - 0x1FF are specific to the HAL implementation, and
1094// are known to have no alpha channel
1095// TODO: move definition for device-specific range into
1096// hardware.h, instead of using hard-coded values here.
1097#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
1098
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001099bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001100 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
1101 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001102 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001103 switch (format) {
1104 case HAL_PIXEL_FORMAT_RGBA_8888:
1105 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -07001106 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -07001107 }
1108 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -07001109 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001110}
1111
Mathias Agopian13127d82013-03-05 17:47:11 -08001112// ----------------------------------------------------------------------------
1113// local state
1114// ----------------------------------------------------------------------------
1115
Dan Stozac7014012014-02-14 15:03:43 -08001116void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
1117 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001118{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001119 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -08001120 const Transform tr(useIdentityTransform ?
1121 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -08001122 const uint32_t hw_h = hw->getHeight();
1123 Rect win(s.active.w, s.active.h);
1124 if (!s.active.crop.isEmpty()) {
1125 win.intersect(s.active.crop, &win);
1126 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -07001127 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -07001128 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -07001129
Mathias Agopianff2ed702013-09-01 21:36:12 -07001130 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
1131 position[0] = tr.transform(win.left, win.top);
1132 position[1] = tr.transform(win.left, win.bottom);
1133 position[2] = tr.transform(win.right, win.bottom);
1134 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -07001135 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -07001136 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -08001137 }
1138}
Eric Hassoldac45e6b2011-02-10 14:41:26 -08001139
Andy McFadden4125a4f2014-01-29 17:17:11 -08001140bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -07001141{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001142 // if we don't have a buffer yet, we're translucent regardless of the
1143 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001144 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001145 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001146 }
Mathias Agopiana67932f2011-04-20 14:20:59 -07001147
1148 // if the layer has the opaque flag, then we're always opaque,
1149 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -08001150 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -07001151}
1152
Dan Stoza23116082015-06-18 14:58:39 -07001153bool Layer::isSecure() const
1154{
1155 const Layer::State& s(mDrawingState);
1156 return (s.flags & layer_state_t::eLayerSecure);
1157}
1158
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001159bool Layer::isProtected() const
1160{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001161 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -08001162 return (activeBuffer != 0) &&
1163 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
1164}
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001165
Mathias Agopian13127d82013-03-05 17:47:11 -08001166bool Layer::isFixedSize() const {
1167 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1168}
1169
1170bool Layer::isCropped() const {
1171 return !mCurrentCrop.isEmpty();
1172}
1173
1174bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
1175 return mNeedsFiltering || hw->needsFiltering();
1176}
1177
1178void Layer::setVisibleRegion(const Region& visibleRegion) {
1179 // always called from main thread
1180 this->visibleRegion = visibleRegion;
1181}
1182
1183void Layer::setCoveredRegion(const Region& coveredRegion) {
1184 // always called from main thread
1185 this->coveredRegion = coveredRegion;
1186}
1187
1188void Layer::setVisibleNonTransparentRegion(const Region&
1189 setVisibleNonTransparentRegion) {
1190 // always called from main thread
1191 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
1192}
1193
1194// ----------------------------------------------------------------------------
1195// transaction
1196// ----------------------------------------------------------------------------
1197
Dan Stoza7dde5992015-05-22 09:51:44 -07001198void Layer::pushPendingState() {
1199 if (!mCurrentState.modified) {
1200 return;
1201 }
1202
Dan Stoza7dde5992015-05-22 09:51:44 -07001203 // If this transaction is waiting on the receipt of a frame, generate a sync
1204 // point and send it to the remote layer.
1205 if (mCurrentState.handle != nullptr) {
1206 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
1207 sp<Layer> handleLayer = handle->owner.promote();
1208 if (handleLayer == nullptr) {
1209 ALOGE("[%s] Unable to promote Layer handle", mName.string());
1210 // If we can't promote the layer we are intended to wait on,
1211 // then it is expired or otherwise invalid. Allow this transaction
1212 // to be applied as per normal (no synchronization).
1213 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -08001214 } else {
1215 auto syncPoint = std::make_shared<SyncPoint>(
1216 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -08001217 if (handleLayer->addSyncPoint(syncPoint)) {
1218 mRemoteSyncPoints.push_back(std::move(syncPoint));
1219 } else {
1220 // We already missed the frame we're supposed to synchronize
1221 // on, so go ahead and apply the state update
1222 mCurrentState.handle = nullptr;
1223 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001224 }
1225
Dan Stoza7dde5992015-05-22 09:51:44 -07001226 // Wake us up to check if the frame has been received
1227 setTransactionFlags(eTransactionNeeded);
1228 }
1229 mPendingStates.push_back(mCurrentState);
1230}
1231
1232void Layer::popPendingState() {
1233 auto oldFlags = mCurrentState.flags;
1234 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -08001235 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -07001236 (mCurrentState.flags & mCurrentState.mask);
1237
1238 mPendingStates.removeAt(0);
1239}
1240
1241bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -07001242 bool stateUpdateAvailable = false;
1243 while (!mPendingStates.empty()) {
1244 if (mPendingStates[0].handle != nullptr) {
1245 if (mRemoteSyncPoints.empty()) {
1246 // If we don't have a sync point for this, apply it anyway. It
1247 // will be visually wrong, but it should keep us from getting
1248 // into too much trouble.
1249 ALOGE("[%s] No local sync point found", mName.string());
1250 popPendingState();
1251 stateUpdateAvailable = true;
1252 continue;
1253 }
1254
Dan Stozacac35382016-01-27 12:21:06 -08001255 if (mRemoteSyncPoints.front()->getFrameNumber() !=
1256 mPendingStates[0].frameNumber) {
1257 ALOGE("[%s] Unexpected sync point frame number found",
1258 mName.string());
1259
1260 // Signal our end of the sync point and then dispose of it
1261 mRemoteSyncPoints.front()->setTransactionApplied();
1262 mRemoteSyncPoints.pop_front();
1263 continue;
1264 }
1265
Dan Stoza7dde5992015-05-22 09:51:44 -07001266 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
1267 // Apply the state update
1268 popPendingState();
1269 stateUpdateAvailable = true;
1270
1271 // Signal our end of the sync point and then dispose of it
1272 mRemoteSyncPoints.front()->setTransactionApplied();
1273 mRemoteSyncPoints.pop_front();
Dan Stoza792e5292016-02-11 11:43:58 -08001274 } else {
1275 break;
Dan Stoza7dde5992015-05-22 09:51:44 -07001276 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001277 } else {
1278 popPendingState();
1279 stateUpdateAvailable = true;
1280 }
1281 }
1282
1283 // If we still have pending updates, wake SurfaceFlinger back up and point
1284 // it at this layer so we can process them
1285 if (!mPendingStates.empty()) {
1286 setTransactionFlags(eTransactionNeeded);
1287 mFlinger->setTransactionFlags(eTraversalNeeded);
1288 }
1289
1290 mCurrentState.modified = false;
1291 return stateUpdateAvailable;
1292}
1293
1294void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001295 auto headFrameNumber = getHeadFrameNumber();
1296 Mutex::Autolock lock(mLocalSyncPointMutex);
1297 for (auto& point : mLocalSyncPoints) {
1298 if (headFrameNumber >= point->getFrameNumber()) {
1299 point->setFrameAvailable();
1300 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001301 }
1302}
1303
Mathias Agopian13127d82013-03-05 17:47:11 -08001304uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001305 ATRACE_CALL();
1306
Dan Stoza7dde5992015-05-22 09:51:44 -07001307 pushPendingState();
1308 if (!applyPendingStates()) {
1309 return 0;
1310 }
1311
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001312 const Layer::State& s(getDrawingState());
1313 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001314
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001315 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1316 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001317
1318 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001319 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001320 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001321 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001322 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1323 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1324 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1325 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001326 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1327 c.active.w, c.active.h,
1328 c.active.crop.left,
1329 c.active.crop.top,
1330 c.active.crop.right,
1331 c.active.crop.bottom,
1332 c.active.crop.getWidth(),
1333 c.active.crop.getHeight(),
1334 c.requested.w, c.requested.h,
1335 c.requested.crop.left,
1336 c.requested.crop.top,
1337 c.requested.crop.right,
1338 c.requested.crop.bottom,
1339 c.requested.crop.getWidth(),
1340 c.requested.crop.getHeight(),
1341 s.active.w, s.active.h,
1342 s.active.crop.left,
1343 s.active.crop.top,
1344 s.active.crop.right,
1345 s.active.crop.bottom,
1346 s.active.crop.getWidth(),
1347 s.active.crop.getHeight(),
1348 s.requested.w, s.requested.h,
1349 s.requested.crop.left,
1350 s.requested.crop.top,
1351 s.requested.crop.right,
1352 s.requested.crop.bottom,
1353 s.requested.crop.getWidth(),
1354 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001355
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001356 // record the new size, form this point on, when the client request
1357 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001358 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001359 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001360 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001361
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001362 if (!isFixedSize()) {
1363
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001364 const bool resizePending = (c.requested.w != c.active.w) ||
1365 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001366
Dan Stoza9e9b0442015-04-22 14:59:08 -07001367 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001368 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001369 // if we have a pending resize, unless we are in fixed-size mode.
1370 // the drawing state will be updated only once we receive a buffer
1371 // with the correct size.
1372 //
1373 // in particular, we want to make sure the clip (which is part
1374 // of the geometry state) is latched together with the size but is
1375 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001376 //
1377 // If a sideband stream is attached, however, we want to skip this
1378 // optimization so that transactions aren't missed when a buffer
1379 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001380
1381 flags |= eDontUpdateGeometryState;
1382 }
1383 }
1384
Mathias Agopian13127d82013-03-05 17:47:11 -08001385 // always set active to requested, unless we're asked not to
1386 // this is used by Layer, which special cases resizes.
1387 if (flags & eDontUpdateGeometryState) {
1388 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001389 Layer::State& editCurrentState(getCurrentState());
1390 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001391 }
1392
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001393 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001394 // invalidate and recompute the visible regions if needed
1395 flags |= Layer::eVisibleRegion;
1396 }
1397
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001398 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001399 // invalidate and recompute the visible regions if needed
1400 flags |= eVisibleRegion;
1401 this->contentDirty = true;
1402
1403 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001404 const uint8_t type = c.transform.getType();
1405 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001406 (type >= Transform::SCALE));
1407 }
1408
1409 // Commit the transaction
1410 commitTransaction();
1411 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001412}
1413
Mathias Agopian13127d82013-03-05 17:47:11 -08001414void Layer::commitTransaction() {
1415 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001416}
1417
Mathias Agopian13127d82013-03-05 17:47:11 -08001418uint32_t Layer::getTransactionFlags(uint32_t flags) {
1419 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1420}
1421
1422uint32_t Layer::setTransactionFlags(uint32_t flags) {
1423 return android_atomic_or(flags, &mTransactionFlags);
1424}
1425
1426bool Layer::setPosition(float x, float y) {
1427 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1428 return false;
1429 mCurrentState.sequence++;
1430 mCurrentState.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001431 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001432 setTransactionFlags(eTransactionNeeded);
1433 return true;
1434}
1435bool Layer::setLayer(uint32_t z) {
1436 if (mCurrentState.z == z)
1437 return false;
1438 mCurrentState.sequence++;
1439 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001440 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001441 setTransactionFlags(eTransactionNeeded);
1442 return true;
1443}
1444bool Layer::setSize(uint32_t w, uint32_t h) {
1445 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1446 return false;
1447 mCurrentState.requested.w = w;
1448 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001449 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001450 setTransactionFlags(eTransactionNeeded);
1451 return true;
1452}
Dan Stoza9e56aa02015-11-02 13:00:03 -08001453#ifdef USE_HWC2
1454bool Layer::setAlpha(float alpha) {
1455#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001456bool Layer::setAlpha(uint8_t alpha) {
Dan Stoza9e56aa02015-11-02 13:00:03 -08001457#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08001458 if (mCurrentState.alpha == alpha)
1459 return false;
1460 mCurrentState.sequence++;
1461 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001462 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001463 setTransactionFlags(eTransactionNeeded);
1464 return true;
1465}
1466bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1467 mCurrentState.sequence++;
1468 mCurrentState.transform.set(
1469 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001470 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001471 setTransactionFlags(eTransactionNeeded);
1472 return true;
1473}
1474bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001475 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001476 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001477 setTransactionFlags(eTransactionNeeded);
1478 return true;
1479}
1480bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1481 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1482 if (mCurrentState.flags == newFlags)
1483 return false;
1484 mCurrentState.sequence++;
1485 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001486 mCurrentState.mask = mask;
1487 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001488 setTransactionFlags(eTransactionNeeded);
1489 return true;
1490}
1491bool Layer::setCrop(const Rect& crop) {
1492 if (mCurrentState.requested.crop == crop)
1493 return false;
1494 mCurrentState.sequence++;
1495 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001496 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001497 setTransactionFlags(eTransactionNeeded);
1498 return true;
1499}
1500
1501bool Layer::setLayerStack(uint32_t layerStack) {
1502 if (mCurrentState.layerStack == layerStack)
1503 return false;
1504 mCurrentState.sequence++;
1505 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001506 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001507 setTransactionFlags(eTransactionNeeded);
1508 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001509}
1510
Dan Stoza7dde5992015-05-22 09:51:44 -07001511void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1512 uint64_t frameNumber) {
1513 mCurrentState.handle = handle;
1514 mCurrentState.frameNumber = frameNumber;
1515 // We don't set eTransactionNeeded, because just receiving a deferral
1516 // request without any other state updates shouldn't actually induce a delay
1517 mCurrentState.modified = true;
1518 pushPendingState();
Dan Stoza792e5292016-02-11 11:43:58 -08001519 mCurrentState.handle = nullptr;
1520 mCurrentState.frameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001521 mCurrentState.modified = false;
1522}
1523
Dan Stozaee44edd2015-03-23 15:50:23 -07001524void Layer::useSurfaceDamage() {
1525 if (mFlinger->mForceFullDamage) {
1526 surfaceDamageRegion = Region::INVALID_REGION;
1527 } else {
1528 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1529 }
1530}
1531
1532void Layer::useEmptyDamage() {
1533 surfaceDamageRegion.clear();
1534}
1535
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001536// ----------------------------------------------------------------------------
1537// pageflip handling...
1538// ----------------------------------------------------------------------------
1539
Dan Stoza6b9454d2014-11-07 16:00:59 -08001540bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001541 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001542 return true;
1543 }
1544
Dan Stoza6b9454d2014-11-07 16:00:59 -08001545 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001546 if (mQueueItems.empty()) {
1547 return false;
1548 }
1549 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001550 nsecs_t expectedPresent =
1551 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001552
1553 // Ignore timestamps more than a second in the future
1554 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1555 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1556 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1557 expectedPresent);
1558
1559 bool isDue = timestamp < expectedPresent;
1560 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001561}
1562
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001563bool Layer::onPreComposition() {
1564 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001565 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001566}
1567
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001568void Layer::onPostComposition() {
1569 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001570 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001571 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1572
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001573 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001574 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001575 mFrameTracker.setFrameReadyFence(frameReadyFence);
1576 } else {
1577 // There was no fence for this frame, so assume that it was ready
1578 // to be presented at the desired present time.
1579 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1580 }
1581
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001582 const HWComposer& hwc = mFlinger->getHwComposer();
Dan Stoza9e56aa02015-11-02 13:00:03 -08001583#ifdef USE_HWC2
1584 sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
1585#else
Jamie Gennis82dbc742012-11-08 19:23:28 -08001586 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001587#endif
Jamie Gennis789a6c32013-02-25 13:37:54 -08001588 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001589 mFrameTracker.setActualPresentFence(presentFence);
1590 } else {
1591 // The HWC doesn't support present fences, so use the refresh
1592 // timestamp instead.
1593 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1594 mFrameTracker.setActualPresentTime(presentTime);
1595 }
1596
1597 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001598 mFrameLatencyNeeded = false;
1599 }
1600}
1601
Dan Stoza9e56aa02015-11-02 13:00:03 -08001602#ifdef USE_HWC2
1603void Layer::releasePendingBuffer() {
1604 mSurfaceFlingerConsumer->releasePendingBuffer();
1605}
1606#endif
1607
Mathias Agopianda27af92012-09-13 18:17:13 -07001608bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001609 const Layer::State& s(mDrawingState);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001610#ifdef USE_HWC2
1611 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
1612 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1613#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001614 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001615 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Dan Stoza9e56aa02015-11-02 13:00:03 -08001616#endif
Mathias Agopianda27af92012-09-13 18:17:13 -07001617}
1618
Mathias Agopian4fec8732012-06-29 14:12:52 -07001619Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001620{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001621 ATRACE_CALL();
1622
Jesse Hall399184a2014-03-03 15:42:54 -08001623 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1624 // mSidebandStreamChanged was true
1625 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001626 if (mSidebandStream != NULL) {
1627 setTransactionFlags(eTransactionNeeded);
1628 mFlinger->setTransactionFlags(eTraversalNeeded);
1629 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001630 recomputeVisibleRegions = true;
1631
1632 const State& s(getDrawingState());
1633 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001634 }
1635
Mathias Agopian4fec8732012-06-29 14:12:52 -07001636 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001637 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001638
1639 // if we've already called updateTexImage() without going through
1640 // a composition step, we have to skip this layer at this point
1641 // because we cannot call updateTeximage() without a corresponding
1642 // compositionComplete() call.
1643 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001644 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001645 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001646 }
1647
Jamie Gennis351a5132011-09-14 18:23:37 -07001648 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001649 const State& s(getDrawingState());
1650 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001651 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001652
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001653 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001654 Layer::State& front;
1655 Layer::State& current;
1656 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001657 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001658 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001659 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001660 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001661 recomputeVisibleRegions(recomputeVisibleRegions),
1662 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001663 }
1664
1665 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001666 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001667 if (buf == NULL) {
1668 return false;
1669 }
1670
1671 uint32_t bufWidth = buf->getWidth();
1672 uint32_t bufHeight = buf->getHeight();
1673
1674 // check that we received a buffer of the right size
1675 // (Take the buffer's orientation into account)
1676 if (item.mTransform & Transform::ROT_90) {
1677 swap(bufWidth, bufHeight);
1678 }
1679
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001680 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1681 if (front.active != front.requested) {
1682
1683 if (isFixedSize ||
1684 (bufWidth == front.requested.w &&
1685 bufHeight == front.requested.h))
1686 {
1687 // Here we pretend the transaction happened by updating the
1688 // current and drawing states. Drawing state is only accessed
1689 // in this thread, no need to have it locked
1690 front.active = front.requested;
1691
1692 // We also need to update the current state so that
1693 // we don't end-up overwriting the drawing state with
1694 // this stale current state during the next transaction
1695 //
1696 // NOTE: We don't need to hold the transaction lock here
1697 // because State::active is only accessed from this thread.
1698 current.active = front.active;
1699
1700 // recompute visible region
1701 recomputeVisibleRegions = true;
1702 }
1703
1704 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001705 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001706 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1707 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001708 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001709 front.active.w, front.active.h,
1710 front.active.crop.left,
1711 front.active.crop.top,
1712 front.active.crop.right,
1713 front.active.crop.bottom,
1714 front.active.crop.getWidth(),
1715 front.active.crop.getHeight(),
1716 front.requested.w, front.requested.h,
1717 front.requested.crop.left,
1718 front.requested.crop.top,
1719 front.requested.crop.right,
1720 front.requested.crop.bottom,
1721 front.requested.crop.getWidth(),
1722 front.requested.crop.getHeight());
1723 }
1724
Ruben Brunk1681d952014-06-27 15:51:55 -07001725 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001726 if (front.active.w != bufWidth ||
1727 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001728 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001729 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1730 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001731 return true;
1732 }
1733 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001734
1735 // if the transparent region has changed (this test is
1736 // conservative, but that's fine, worst case we're doing
1737 // a bit of extra work), we latch the new one and we
1738 // trigger a visible-region recompute.
1739 if (!front.activeTransparentRegion.isTriviallyEqual(
1740 front.requestedTransparentRegion)) {
1741 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001742
1743 // We also need to update the current state so that
1744 // we don't end-up overwriting the drawing state with
1745 // this stale current state during the next transaction
1746 //
1747 // NOTE: We don't need to hold the transaction lock here
1748 // because State::active is only accessed from this thread.
1749 current.activeTransparentRegion = front.activeTransparentRegion;
1750
1751 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001752 recomputeVisibleRegions = true;
1753 }
1754
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001755 return false;
1756 }
1757 };
1758
Ruben Brunk1681d952014-06-27 15:51:55 -07001759 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1760 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001761
Dan Stozacac35382016-01-27 12:21:06 -08001762
1763 // Check all of our local sync points to ensure that all transactions
1764 // which need to have been applied prior to the frame which is about to
1765 // be latched have signaled
1766
1767 auto headFrameNumber = getHeadFrameNumber();
1768 bool matchingFramesFound = false;
1769 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001770 {
Dan Stozacac35382016-01-27 12:21:06 -08001771 Mutex::Autolock lock(mLocalSyncPointMutex);
1772 for (auto& point : mLocalSyncPoints) {
1773 if (point->getFrameNumber() > headFrameNumber) {
1774 break;
1775 }
1776
1777 matchingFramesFound = true;
1778
1779 if (!point->frameIsAvailable()) {
1780 // We haven't notified the remote layer that the frame for
1781 // this point is available yet. Notify it now, and then
1782 // abort this attempt to latch.
1783 point->setFrameAvailable();
1784 allTransactionsApplied = false;
1785 break;
1786 }
1787
1788 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001789 }
1790 }
1791
Dan Stozacac35382016-01-27 12:21:06 -08001792 if (matchingFramesFound && !allTransactionsApplied) {
1793 mFlinger->signalLayerUpdate();
1794 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001795 }
1796
Pablo Ceballos06312182015-10-07 16:32:12 -07001797 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1798 // of the buffer queue isn't modified when the buffer queue is returning
1799 // BufferItem's that weren't actually queued. This can happen in single
1800 // buffer mode.
1801 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001802 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001803 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001804 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001805 if (updateResult == BufferQueue::PRESENT_LATER) {
1806 // Producer doesn't want buffer to be displayed yet. Signal a
1807 // layer update so we check again at the next opportunity.
1808 mFlinger->signalLayerUpdate();
1809 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001810 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1811 // If the buffer has been rejected, remove it from the shadow queue
1812 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001813 if (queuedBuffer) {
1814 Mutex::Autolock lock(mQueueItemLock);
1815 mQueueItems.removeAt(0);
1816 android_atomic_dec(&mQueuedFrames);
1817 }
Dan Stozaecc50402015-04-28 14:42:06 -07001818 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001819 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1820 // This can occur if something goes wrong when trying to create the
1821 // EGLImage for this buffer. If this happens, the buffer has already
1822 // been released, so we need to clean up the queue and bug out
1823 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001824 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001825 Mutex::Autolock lock(mQueueItemLock);
1826 mQueueItems.clear();
1827 android_atomic_and(0, &mQueuedFrames);
1828 }
1829
1830 // Once we have hit this state, the shadow queue may no longer
1831 // correctly reflect the incoming BufferQueue's contents, so even if
1832 // updateTexImage starts working, the only safe course of action is
1833 // to continue to ignore updates.
1834 mUpdateTexImageFailed = true;
1835
1836 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001837 }
1838
Pablo Ceballos06312182015-10-07 16:32:12 -07001839 if (queuedBuffer) {
1840 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001841 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1842
Dan Stoza6b9454d2014-11-07 16:00:59 -08001843 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001844
1845 // Remove any stale buffers that have been dropped during
1846 // updateTexImage
1847 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1848 mQueueItems.removeAt(0);
1849 android_atomic_dec(&mQueuedFrames);
1850 }
1851
Dan Stoza6b9454d2014-11-07 16:00:59 -08001852 mQueueItems.removeAt(0);
1853 }
1854
Dan Stozaecc50402015-04-28 14:42:06 -07001855
Andy McFadden1585c4d2013-06-28 13:52:40 -07001856 // Decrement the queued-frames count. Signal another event if we
1857 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001858 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001859 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001860 mFlinger->signalLayerUpdate();
1861 }
1862
1863 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001864 // something happened!
1865 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001866 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001867 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001868
Jamie Gennis351a5132011-09-14 18:23:37 -07001869 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001870 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001871 if (mActiveBuffer == NULL) {
1872 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001873 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001874 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001875
Mathias Agopian4824d402012-06-04 18:16:30 -07001876 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001877 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001878 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001879 // the first time we receive a buffer, we need to trigger a
1880 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001881 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001882 }
1883
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001884 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1885 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1886 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001887 if ((crop != mCurrentCrop) ||
1888 (transform != mCurrentTransform) ||
1889 (scalingMode != mCurrentScalingMode))
1890 {
1891 mCurrentCrop = crop;
1892 mCurrentTransform = transform;
1893 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001894 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001895 }
1896
1897 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001898 uint32_t bufWidth = mActiveBuffer->getWidth();
1899 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001900 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1901 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001902 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001903 }
1904 }
1905
1906 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001907 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001908 recomputeVisibleRegions = true;
1909 }
1910
Dan Stozacac35382016-01-27 12:21:06 -08001911 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1912
1913 // Remove any sync points corresponding to the buffer which was just
1914 // latched
1915 {
1916 Mutex::Autolock lock(mLocalSyncPointMutex);
1917 auto point = mLocalSyncPoints.begin();
1918 while (point != mLocalSyncPoints.end()) {
1919 if (!(*point)->frameIsAvailable() ||
1920 !(*point)->transactionIsApplied()) {
1921 // This sync point must have been added since we started
1922 // latching. Don't drop it yet.
1923 ++point;
1924 continue;
1925 }
1926
1927 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1928 point = mLocalSyncPoints.erase(point);
1929 } else {
1930 ++point;
1931 }
1932 }
1933 }
1934
Mathias Agopian4fec8732012-06-29 14:12:52 -07001935 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001936 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001937
1938 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001939 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001940 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001941 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001942}
1943
Mathias Agopiana67932f2011-04-20 14:20:59 -07001944uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001945{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001946 // TODO: should we do something special if mSecure is set?
1947 if (mProtectedByApp) {
1948 // need a hardware-protected path to external video sink
1949 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001950 }
Riley Andrews03414a12014-07-01 14:22:59 -07001951 if (mPotentialCursor) {
1952 usage |= GraphicBuffer::USAGE_CURSOR;
1953 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001954 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001955 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001956}
1957
Mathias Agopian84300952012-11-21 16:02:13 -08001958void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001959 uint32_t orientation = 0;
1960 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001961 // The transform hint is used to improve performance, but we can
1962 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001963 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001964 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001965 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001966 if (orientation & Transform::ROT_INVALID) {
1967 orientation = 0;
1968 }
1969 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001970 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001971}
1972
Mathias Agopian13127d82013-03-05 17:47:11 -08001973// ----------------------------------------------------------------------------
1974// debugging
1975// ----------------------------------------------------------------------------
1976
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001977void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001978{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001979 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001980
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001981 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001982 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001983 "+ %s %p (%s)\n",
1984 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001985 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001986
Mathias Agopian2ca79392013-04-02 18:30:32 -07001987 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001988 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001989 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001990 sp<Client> client(mClientRef.promote());
1991
Mathias Agopian74d211a2013-04-22 16:55:35 +02001992 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001993 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1994 "isOpaque=%1d, invalidate=%1d, "
Dan Stoza9e56aa02015-11-02 13:00:03 -08001995#ifdef USE_HWC2
1996 "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1997#else
Mathias Agopian13127d82013-03-05 17:47:11 -08001998 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
Dan Stoza9e56aa02015-11-02 13:00:03 -08001999#endif
Mathias Agopian13127d82013-03-05 17:47:11 -08002000 " client=%p\n",
2001 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
2002 s.active.crop.left, s.active.crop.top,
2003 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08002004 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08002005 s.alpha, s.flags,
2006 s.transform[0][0], s.transform[0][1],
2007 s.transform[1][0], s.transform[1][1],
2008 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08002009
2010 sp<const GraphicBuffer> buf0(mActiveBuffer);
2011 uint32_t w0=0, h0=0, s0=0, f0=0;
2012 if (buf0 != 0) {
2013 w0 = buf0->getWidth();
2014 h0 = buf0->getHeight();
2015 s0 = buf0->getStride();
2016 f0 = buf0->format;
2017 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02002018 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08002019 " "
2020 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
2021 " queued-frames=%d, mRefreshPending=%d\n",
2022 mFormat, w0, h0, s0,f0,
2023 mQueuedFrames, mRefreshPending);
2024
Mathias Agopian13127d82013-03-05 17:47:11 -08002025 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02002026 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08002027 }
2028}
2029
Svetoslavd85084b2014-03-20 10:28:31 -07002030void Layer::dumpFrameStats(String8& result) const {
2031 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08002032}
2033
Svetoslavd85084b2014-03-20 10:28:31 -07002034void Layer::clearFrameStats() {
2035 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08002036}
2037
Jamie Gennis6547ff42013-07-16 20:12:42 -07002038void Layer::logFrameStats() {
2039 mFrameTracker.logAndResetStats(mName);
2040}
2041
Svetoslavd85084b2014-03-20 10:28:31 -07002042void Layer::getFrameStats(FrameStats* outStats) const {
2043 mFrameTracker.getStats(outStats);
2044}
2045
Mathias Agopian13127d82013-03-05 17:47:11 -08002046// ---------------------------------------------------------------------------
2047
2048Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
2049 const sp<Layer>& layer)
2050 : mFlinger(flinger), mLayer(layer) {
2051}
2052
2053Layer::LayerCleaner::~LayerCleaner() {
2054 // destroy client resources
2055 mFlinger->onLayerDestroyed(mLayer);
2056}
2057
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002058// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002059}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07002060
2061#if defined(__gl_h_)
2062#error "don't include gl/gl.h in this file"
2063#endif
2064
2065#if defined(__gl2_h_)
2066#error "don't include gl2/gl2.h in this file"
2067#endif