blob: 6574898154a92e5305bc254f7b53d1f284a3e2d6 [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
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080019#include <stdlib.h>
20#include <stdint.h>
21#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080022#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080023
Mathias Agopiana67932f2011-04-20 14:20:59 -070024#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070025#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070026#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080027
28#include <utils/Errors.h>
29#include <utils/Log.h>
Jesse Hall399184a2014-03-03 15:42:54 -080030#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080031#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080032#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080033
Mathias Agopian3330b202009-10-05 17:07:12 -070034#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080035#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080036
Dan Stoza6b9454d2014-11-07 16:00:59 -080037#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080038#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039
40#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020041#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070042#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070044#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046
Mathias Agopian1b031492012-06-20 17:51:20 -070047#include "DisplayHardware/HWComposer.h"
48
Mathias Agopian875d8e12013-06-07 15:35:48 -070049#include "RenderEngine/RenderEngine.h"
50
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051#define DEBUG_RESIZE 0
52
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053namespace android {
54
55// ---------------------------------------------------------------------------
56
Mathias Agopian13127d82013-03-05 17:47:11 -080057int32_t Layer::sSequence = 1;
58
Mathias Agopian4d9b8222013-03-12 17:11:48 -070059Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
60 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080061 : contentDirty(false),
62 sequence(uint32_t(android_atomic_inc(&sSequence))),
63 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070064 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080065 mPremultipliedAlpha(true),
66 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mTransactionFlags(0),
Dan Stoza7dde5992015-05-22 09:51:44 -070069 mPendingStateMutex(),
70 mPendingStates(),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080072 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070073 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070074 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070075 mCurrentOpacity(true),
Dan Stozacac35382016-01-27 12:21:06 -080076 mCurrentFrameNumber(0),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080077 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080078 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080079 mFiltering(false),
80 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070081 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080082 mProtectedByApp(false),
83 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070084 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070085 mPotentialCursor(false),
86 mQueueItemLock(),
87 mQueueItemCondition(),
88 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070089 mLastFrameNumberReceived(0),
Pablo Ceballos04839ab2015-11-13 13:39:23 -080090 mUpdateTexImageFailed(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080091 mAutoRefresh(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080092{
Mathias Agopiana67932f2011-04-20 14:20:59 -070093 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070094 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070095 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070096
97 uint32_t layerFlags = 0;
98 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080099 layerFlags |= layer_state_t::eLayerHidden;
100 if (flags & ISurfaceComposerClient::eOpaque)
101 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700102 if (flags & ISurfaceComposerClient::eSecure)
103 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700104
105 if (flags & ISurfaceComposerClient::eNonPremultiplied)
106 mPremultipliedAlpha = false;
107
108 mName = name;
109
110 mCurrentState.active.w = w;
111 mCurrentState.active.h = h;
112 mCurrentState.active.crop.makeInvalid();
113 mCurrentState.z = 0;
114 mCurrentState.alpha = 0xFF;
115 mCurrentState.layerStack = 0;
116 mCurrentState.flags = layerFlags;
117 mCurrentState.sequence = 0;
118 mCurrentState.transform.set(0, 0);
119 mCurrentState.requested = mCurrentState.active;
120
121 // drawing state & current state are identical
122 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700123
124 nsecs_t displayPeriod =
125 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
126 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800127}
128
Mathias Agopian3f844832013-08-07 21:24:32 -0700129void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800130 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700131 sp<IGraphicBufferProducer> producer;
132 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700133 BufferQueue::createBufferQueue(&producer, &consumer);
134 mProducer = new MonitoredProducer(producer, mFlinger);
135 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800136 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800137 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700138 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800139
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700140#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
141#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700142#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700143 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800144#endif
Andy McFadden69052052012-09-14 16:10:11 -0700145
Mathias Agopian84300952012-11-21 16:02:13 -0800146 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
147 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700148}
149
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700150Layer::~Layer() {
Dan Stozacac35382016-01-27 12:21:06 -0800151 for (auto& point : mRemoteSyncPoints) {
152 point->setTransactionApplied();
153 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700154 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700155 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700156}
157
Mathias Agopian13127d82013-03-05 17:47:11 -0800158// ---------------------------------------------------------------------------
159// callbacks
160// ---------------------------------------------------------------------------
161
Dan Stozac7014012014-02-14 15:03:43 -0800162void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800163 HWComposer::HWCLayerInterface* layer) {
164 if (layer) {
165 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700166 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800167 }
168}
169
Dan Stoza6b9454d2014-11-07 16:00:59 -0800170void Layer::onFrameAvailable(const BufferItem& item) {
171 // Add this buffer from our internal queue tracker
172 { // Autolock scope
173 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700174
175 // Reset the frame number tracker when we receive the first buffer after
176 // a frame number reset
177 if (item.mFrameNumber == 1) {
178 mLastFrameNumberReceived = 0;
179 }
180
181 // Ensure that callbacks are handled in order
182 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
183 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
184 ms2ns(500));
185 if (result != NO_ERROR) {
186 ALOGE("[%s] Timed out waiting on callback", mName.string());
187 }
188 }
189
Dan Stoza6b9454d2014-11-07 16:00:59 -0800190 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700191 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700192
193 // Wake up any pending callbacks
194 mLastFrameNumberReceived = item.mFrameNumber;
195 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800196 }
197
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800198 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700199}
200
Dan Stoza6b9454d2014-11-07 16:00:59 -0800201void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700202 { // Autolock scope
203 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700204
Dan Stoza7dde5992015-05-22 09:51:44 -0700205 // 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 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700212 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700213
214 if (mQueueItems.empty()) {
215 ALOGE("Can't replace a frame on an empty queue");
216 return;
217 }
218 mQueueItems.editItemAt(0) = item;
219
220 // Wake up any pending callbacks
221 mLastFrameNumberReceived = item.mFrameNumber;
222 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700223 }
Dan Stoza6b9454d2014-11-07 16:00:59 -0800224}
225
Jesse Hall399184a2014-03-03 15:42:54 -0800226void Layer::onSidebandStreamChanged() {
227 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
228 // mSidebandStreamChanged was false
229 mFlinger->signalLayerUpdate();
230 }
231}
232
Mathias Agopian67106042013-03-14 19:18:13 -0700233// called with SurfaceFlinger::mStateLock from the drawing thread after
234// the layer has been remove from the current state list (and just before
235// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800236void Layer::onRemoved() {
Pablo Ceballose338df12015-12-03 11:44:46 -0800237 sp<Client> c(mClientRef.promote());
238 if (c != 0) {
239 c->detachLayer(this);
240 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800241 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700242}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700243
Mathias Agopian13127d82013-03-05 17:47:11 -0800244// ---------------------------------------------------------------------------
245// set-up
246// ---------------------------------------------------------------------------
247
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700248const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800249 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800250}
251
Mathias Agopianf9d93272009-06-19 17:00:27 -0700252status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800253 PixelFormat format, uint32_t flags)
254{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700255 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700256 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700257
258 // never allow a surface larger than what our underlying GL implementation
259 // can handle.
260 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800261 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700262 return BAD_VALUE;
263 }
264
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700265 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700266
Riley Andrews03414a12014-07-01 14:22:59 -0700267 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700268 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700269 mCurrentOpacity = getOpacityForFormat(format);
270
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800271 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
272 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
273 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700274
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800275 return NO_ERROR;
276}
277
Dan Stoza7dde5992015-05-22 09:51:44 -0700278/*
279 * The layer handle is just a BBinder object passed to the client
280 * (remote process) -- we don't keep any reference on our side such that
281 * the dtor is called when the remote side let go of its reference.
282 *
283 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
284 * this layer when the handle is destroyed.
285 */
286class Layer::Handle : public BBinder, public LayerCleaner {
287 public:
288 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
289 : LayerCleaner(flinger, layer), owner(layer) {}
290
291 wp<Layer> owner;
292};
293
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700294sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800295 Mutex::Autolock _l(mLock);
296
297 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700298 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800299
300 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700301
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700302 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800303}
304
Dan Stozab9b08832014-03-13 11:55:57 -0700305sp<IGraphicBufferProducer> Layer::getProducer() const {
306 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700307}
308
Mathias Agopian13127d82013-03-05 17:47:11 -0800309// ---------------------------------------------------------------------------
310// h/w composer set-up
311// ---------------------------------------------------------------------------
312
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800313Rect Layer::getContentCrop() const {
314 // this is the crop rectangle that applies to the buffer
315 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700316 Rect crop;
317 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800318 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700319 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800320 } else if (mActiveBuffer != NULL) {
321 // otherwise we use the whole buffer
322 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700323 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800324 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700325 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700326 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700327 return crop;
328}
329
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700330static Rect reduce(const Rect& win, const Region& exclude) {
331 if (CC_LIKELY(exclude.isEmpty())) {
332 return win;
333 }
334 if (exclude.isRect()) {
335 return win.reduce(exclude.getBounds());
336 }
337 return Region(win).subtract(exclude).getBounds();
338}
339
Mathias Agopian13127d82013-03-05 17:47:11 -0800340Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700341 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700342 return computeBounds(s.activeTransparentRegion);
343}
344
345Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
346 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800347 Rect win(s.active.w, s.active.h);
348 if (!s.active.crop.isEmpty()) {
349 win.intersect(s.active.crop, &win);
350 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700351 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700352 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800353}
354
Mathias Agopian6b442672013-07-09 21:24:52 -0700355FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800356 // the content crop is the area of the content that gets scaled to the
357 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700358 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800359
360 // the active.crop is the area of the window that gets cropped, but not
361 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700362 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800363
364 // apply the projection's clipping to the window crop in
365 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700366 // if there are no window scaling involved, this operation will map to full
367 // pixels in the buffer.
368 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
369 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700370
371 Rect activeCrop(s.active.w, s.active.h);
372 if (!s.active.crop.isEmpty()) {
373 activeCrop = s.active.crop;
374 }
375
376 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800377 activeCrop.intersect(hw->getViewport(), &activeCrop);
378 activeCrop = s.transform.inverse().transform(activeCrop);
379
Michael Lentine28ea2172014-11-19 18:32:37 -0800380 // This needs to be here as transform.transform(Rect) computes the
381 // transformed rect and then takes the bounding box of the result before
382 // returning. This means
383 // transform.inverse().transform(transform.transform(Rect)) != Rect
384 // in which case we need to make sure the final rect is clipped to the
385 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800386 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
387
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700388 // subtract the transparent region and snap to the bounds
389 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
390
Mathias Agopian13127d82013-03-05 17:47:11 -0800391 if (!activeCrop.isEmpty()) {
392 // Transform the window crop to match the buffer coordinate system,
393 // which means using the inverse of the current transform set on the
394 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700395 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700396 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
397 /*
398 * the code below applies the display's inverse transform to the buffer
399 */
400 uint32_t invTransformOrient = hw->getOrientationTransform();
401 // calculate the inverse transform
402 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
403 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
404 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700405 // If the transform has been rotated the axis of flip has been swapped
406 // so we need to swap which flip operations we are performing
407 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
408 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
409 if (is_h_flipped != is_v_flipped) {
410 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
411 NATIVE_WINDOW_TRANSFORM_FLIP_H;
412 }
Michael Lentinef7551402014-08-18 16:35:43 -0700413 }
414 // and apply to the current transform
415 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
416 }
417
Mathias Agopian13127d82013-03-05 17:47:11 -0800418 int winWidth = s.active.w;
419 int winHeight = s.active.h;
420 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700421 // If the activeCrop has been rotate the ends are rotated but not
422 // the space itself so when transforming ends back we can't rely on
423 // a modification of the axes of rotation. To account for this we
424 // need to reorient the inverse rotation in terms of the current
425 // axes of rotation.
426 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
427 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
428 if (is_h_flipped == is_v_flipped) {
429 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
430 NATIVE_WINDOW_TRANSFORM_FLIP_H;
431 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800432 winWidth = s.active.h;
433 winHeight = s.active.w;
434 }
435 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700436 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800437
Mathias Agopian6b442672013-07-09 21:24:52 -0700438 // below, crop is intersected with winCrop expressed in crop's coordinate space
439 float xScale = crop.getWidth() / float(winWidth);
440 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800441
Michael Lentinef7551402014-08-18 16:35:43 -0700442 float insetL = winCrop.left * xScale;
443 float insetT = winCrop.top * yScale;
444 float insetR = (winWidth - winCrop.right ) * xScale;
445 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800446
447 crop.left += insetL;
448 crop.top += insetT;
449 crop.right -= insetR;
450 crop.bottom -= insetB;
451 }
452 return crop;
453}
454
Mathias Agopian4fec8732012-06-29 14:12:52 -0700455void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700456 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700457 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700458{
Mathias Agopian13127d82013-03-05 17:47:11 -0800459 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700460
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700461 // enable this layer
462 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700463
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700464 if (isSecure() && !hw->isSecure()) {
465 layer.setSkip(true);
466 }
467
Mathias Agopian13127d82013-03-05 17:47:11 -0800468 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700469 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800470 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800471 layer.setBlending(mPremultipliedAlpha ?
472 HWC_BLENDING_PREMULT :
473 HWC_BLENDING_COVERAGE);
474 }
475
476 // apply the layer's transform, followed by the display's global transform
477 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700478 Region activeTransparentRegion(s.activeTransparentRegion);
479 if (!s.active.crop.isEmpty()) {
480 Rect activeCrop(s.active.crop);
481 activeCrop = s.transform.transform(activeCrop);
482 activeCrop.intersect(hw->getViewport(), &activeCrop);
483 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800484 // This needs to be here as transform.transform(Rect) computes the
485 // transformed rect and then takes the bounding box of the result before
486 // returning. This means
487 // transform.inverse().transform(transform.transform(Rect)) != Rect
488 // in which case we need to make sure the final rect is clipped to the
489 // display bounds.
490 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700491 // mark regions outside the crop as transparent
492 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
493 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
494 s.active.w, s.active.h));
495 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
496 activeCrop.left, activeCrop.bottom));
497 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
498 s.active.w, activeCrop.bottom));
499 }
500 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800501 frame.intersect(hw->getViewport(), &frame);
502 const Transform& tr(hw->getTransform());
503 layer.setFrame(tr.transform(frame));
504 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800505 layer.setPlaneAlpha(s.alpha);
506
Mathias Agopian29a367b2011-07-12 14:51:45 -0700507 /*
508 * Transformations are applied in this order:
509 * 1) buffer orientation/flip/mirror
510 * 2) state transformation (window manager)
511 * 3) layer orientation (screen orientation)
512 * (NOTE: the matrices are multiplied in reverse order)
513 */
514
515 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700516 Transform transform(tr * s.transform * bufferOrientation);
517
518 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
519 /*
520 * the code below applies the display's inverse transform to the buffer
521 */
522 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700523 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700524 // calculate the inverse transform
525 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
526 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
527 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700528 // If the transform has been rotated the axis of flip has been swapped
529 // so we need to swap which flip operations we are performing
530 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
531 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
532 if (is_h_flipped != is_v_flipped) {
533 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
534 NATIVE_WINDOW_TRANSFORM_FLIP_H;
535 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700536 }
537 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700538 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700539 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700540
541 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800542 const uint32_t orientation = transform.getOrientation();
543 if (orientation & Transform::ROT_INVALID) {
544 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700545 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700546 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800547 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700548 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700549}
550
Mathias Agopian42977342012-08-05 00:40:46 -0700551void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700552 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800553 // we have to set the visible region on every frame because
554 // we currently free it during onLayerDisplayed(), which is called
555 // after HWComposer::commit() -- every frame.
556 // Apply this display's projection's viewport to the visible region
557 // before giving it to the HWC HAL.
558 const Transform& tr = hw->getTransform();
559 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
560 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700561 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700562
Jesse Hall399184a2014-03-03 15:42:54 -0800563 if (mSidebandStream.get()) {
564 layer.setSidebandStream(mSidebandStream);
565 } else {
566 // NOTE: buffer can be NULL if the client never drew into this
567 // layer yet, or if we ran out of memory
568 layer.setBuffer(mActiveBuffer);
569 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700570}
Jesse Halldc5b4852012-06-29 15:21:18 -0700571
Dan Stozac7014012014-02-14 15:03:43 -0800572void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700573 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700574 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700575
576 // TODO: there is a possible optimization here: we only need to set the
577 // acquire fence the first time a new buffer is acquired on EACH display.
578
Riley Andrews03414a12014-07-01 14:22:59 -0700579 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800580 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800581 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700582 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700583 if (fenceFd == -1) {
584 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
585 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700586 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700587 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700588 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700589}
590
Riley Andrews03414a12014-07-01 14:22:59 -0700591Rect Layer::getPosition(
592 const sp<const DisplayDevice>& hw)
593{
594 // this gives us only the "orientation" component of the transform
595 const State& s(getCurrentState());
596
597 // apply the layer's transform, followed by the display's global transform
598 // here we're guaranteed that the layer's transform preserves rects
599 Rect win(s.active.w, s.active.h);
600 if (!s.active.crop.isEmpty()) {
601 win.intersect(s.active.crop, &win);
602 }
603 // subtract the transparent region and snap to the bounds
604 Rect bounds = reduce(win, s.activeTransparentRegion);
605 Rect frame(s.transform.transform(bounds));
606 frame.intersect(hw->getViewport(), &frame);
607 const Transform& tr(hw->getTransform());
608 return Rect(tr.transform(frame));
609}
610
Mathias Agopian13127d82013-03-05 17:47:11 -0800611// ---------------------------------------------------------------------------
612// drawing...
613// ---------------------------------------------------------------------------
614
615void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800616 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800617}
618
Dan Stozac7014012014-02-14 15:03:43 -0800619void Layer::draw(const sp<const DisplayDevice>& hw,
620 bool useIdentityTransform) const {
621 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800622}
623
Dan Stozac7014012014-02-14 15:03:43 -0800624void Layer::draw(const sp<const DisplayDevice>& hw) const {
625 onDraw(hw, Region(hw->bounds()), false);
626}
627
628void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
629 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800630{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800631 ATRACE_CALL();
632
Mathias Agopiana67932f2011-04-20 14:20:59 -0700633 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800634 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700635 // in fact never been drawn into. This happens frequently with
636 // SurfaceView because the WindowManager can't know when the client
637 // has drawn the first time.
638
639 // If there is nothing under us, we paint the screen in black, otherwise
640 // we just skip this update.
641
642 // figure out if there is something below us
643 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700644 const SurfaceFlinger::LayerVector& drawingLayers(
645 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700646 const size_t count = drawingLayers.size();
647 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800648 const sp<Layer>& layer(drawingLayers[i]);
649 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700650 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700651 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700652 }
653 // if not everything below us is covered, we plug the holes!
654 Region holes(clip.subtract(under));
655 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700656 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700657 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800658 return;
659 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700660
Andy McFadden97eba892012-12-11 15:21:45 -0800661 // Bind the current buffer to the GL texture, and wait for it to be
662 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800663 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
664 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800665 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700666 // Go ahead and draw the buffer anyway; no matter what we do the screen
667 // is probably going to have something visibly wrong.
668 }
669
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700670 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
671
Mathias Agopian875d8e12013-06-07 15:35:48 -0700672 RenderEngine& engine(mFlinger->getRenderEngine());
673
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700674 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700675 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700676 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700677
678 // Query the texture matrix given our current filtering mode.
679 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800680 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
681 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700682
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700683 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
684
685 /*
686 * the code below applies the display's inverse transform to the texture transform
687 */
688
689 // create a 4x4 transform matrix from the display transform flags
690 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
691 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
692 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
693
694 mat4 tr;
695 uint32_t transform = hw->getOrientationTransform();
696 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
697 tr = tr * rot90;
698 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
699 tr = tr * flipH;
700 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
701 tr = tr * flipV;
702
703 // calculate the inverse
704 tr = inverse(tr);
705
706 // and finally apply it to the original texture matrix
707 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
708 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
709 }
710
Jamie Genniscbb1a952012-05-08 17:05:52 -0700711 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700712 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
713 mTexture.setFiltering(useFiltering);
714 mTexture.setMatrix(textureMatrix);
715
716 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700717 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700718 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700719 }
Dan Stozac7014012014-02-14 15:03:43 -0800720 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700721 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800722}
723
Mathias Agopian13127d82013-03-05 17:47:11 -0800724
Dan Stozac7014012014-02-14 15:03:43 -0800725void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
726 const Region& /* clip */, float red, float green, float blue,
727 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800728{
Mathias Agopian19733a32013-08-28 18:13:56 -0700729 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800730 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700731 engine.setupFillWithColor(red, green, blue, alpha);
732 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800733}
734
735void Layer::clearWithOpenGL(
736 const sp<const DisplayDevice>& hw, const Region& clip) const {
737 clearWithOpenGL(hw, clip, 0,0,0,0);
738}
739
Dan Stozac7014012014-02-14 15:03:43 -0800740void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
741 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700742 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800743
Dan Stozac7014012014-02-14 15:03:43 -0800744 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800745
Mathias Agopian13127d82013-03-05 17:47:11 -0800746 /*
747 * NOTE: the way we compute the texture coordinates here produces
748 * different results than when we take the HWC path -- in the later case
749 * the "source crop" is rounded to texel boundaries.
750 * This can produce significantly different results when the texture
751 * is scaled by a large amount.
752 *
753 * The GL code below is more logical (imho), and the difference with
754 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700755 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800756 * GL composition when a buffer scaling is applied (maybe with some
757 * minimal value)? Or, we could make GL behave like HWC -- but this feel
758 * like more of a hack.
759 */
760 const Rect win(computeBounds());
761
Mathias Agopian3f844832013-08-07 21:24:32 -0700762 float left = float(win.left) / float(s.active.w);
763 float top = float(win.top) / float(s.active.h);
764 float right = float(win.right) / float(s.active.w);
765 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800766
Mathias Agopian875d8e12013-06-07 15:35:48 -0700767 // TODO: we probably want to generate the texture coords with the mesh
768 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700769 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
770 texCoords[0] = vec2(left, 1.0f - top);
771 texCoords[1] = vec2(left, 1.0f - bottom);
772 texCoords[2] = vec2(right, 1.0f - bottom);
773 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800774
Mathias Agopian875d8e12013-06-07 15:35:48 -0700775 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800776 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700777 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700778 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800779}
780
Ruben Brunk1681d952014-06-27 15:51:55 -0700781uint32_t Layer::getProducerStickyTransform() const {
782 int producerStickyTransform = 0;
783 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
784 if (ret != OK) {
785 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
786 strerror(-ret), ret);
787 return 0;
788 }
789 return static_cast<uint32_t>(producerStickyTransform);
790}
791
Dan Stozacac35382016-01-27 12:21:06 -0800792uint64_t Layer::getHeadFrameNumber() const {
793 Mutex::Autolock lock(mQueueItemLock);
794 if (!mQueueItems.empty()) {
795 return mQueueItems[0].mFrameNumber;
796 } else {
797 return mCurrentFrameNumber;
798 }
799}
800
801bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
802 if (point->getFrameNumber() <= mCurrentFrameNumber) {
803 // Don't bother with a SyncPoint, since we've already latched the
804 // relevant frame
805 return false;
Dan Stoza7dde5992015-05-22 09:51:44 -0700806 }
807
Dan Stozacac35382016-01-27 12:21:06 -0800808 Mutex::Autolock lock(mLocalSyncPointMutex);
809 mLocalSyncPoints.push_back(point);
810 return true;
Dan Stoza7dde5992015-05-22 09:51:44 -0700811}
812
Mathias Agopian13127d82013-03-05 17:47:11 -0800813void Layer::setFiltering(bool filtering) {
814 mFiltering = filtering;
815}
816
817bool Layer::getFiltering() const {
818 return mFiltering;
819}
820
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800821// As documented in libhardware header, formats in the range
822// 0x100 - 0x1FF are specific to the HAL implementation, and
823// are known to have no alpha channel
824// TODO: move definition for device-specific range into
825// hardware.h, instead of using hard-coded values here.
826#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
827
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700828bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700829 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
830 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800831 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700832 switch (format) {
833 case HAL_PIXEL_FORMAT_RGBA_8888:
834 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700835 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700836 }
837 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700838 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800839}
840
Mathias Agopian13127d82013-03-05 17:47:11 -0800841// ----------------------------------------------------------------------------
842// local state
843// ----------------------------------------------------------------------------
844
Dan Stozac7014012014-02-14 15:03:43 -0800845void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
846 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800847{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700848 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800849 const Transform tr(useIdentityTransform ?
850 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800851 const uint32_t hw_h = hw->getHeight();
852 Rect win(s.active.w, s.active.h);
853 if (!s.active.crop.isEmpty()) {
854 win.intersect(s.active.crop, &win);
855 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700856 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700857 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700858
Mathias Agopianff2ed702013-09-01 21:36:12 -0700859 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
860 position[0] = tr.transform(win.left, win.top);
861 position[1] = tr.transform(win.left, win.bottom);
862 position[2] = tr.transform(win.right, win.bottom);
863 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700864 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700865 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800866 }
867}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800868
Andy McFadden4125a4f2014-01-29 17:17:11 -0800869bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700870{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700871 // if we don't have a buffer yet, we're translucent regardless of the
872 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700873 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700874 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700875 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700876
877 // if the layer has the opaque flag, then we're always opaque,
878 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800879 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700880}
881
Dan Stoza23116082015-06-18 14:58:39 -0700882bool Layer::isSecure() const
883{
884 const Layer::State& s(mDrawingState);
885 return (s.flags & layer_state_t::eLayerSecure);
886}
887
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800888bool Layer::isProtected() const
889{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700890 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800891 return (activeBuffer != 0) &&
892 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
893}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700894
Mathias Agopian13127d82013-03-05 17:47:11 -0800895bool Layer::isFixedSize() const {
896 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
897}
898
899bool Layer::isCropped() const {
900 return !mCurrentCrop.isEmpty();
901}
902
903bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
904 return mNeedsFiltering || hw->needsFiltering();
905}
906
907void Layer::setVisibleRegion(const Region& visibleRegion) {
908 // always called from main thread
909 this->visibleRegion = visibleRegion;
910}
911
912void Layer::setCoveredRegion(const Region& coveredRegion) {
913 // always called from main thread
914 this->coveredRegion = coveredRegion;
915}
916
917void Layer::setVisibleNonTransparentRegion(const Region&
918 setVisibleNonTransparentRegion) {
919 // always called from main thread
920 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
921}
922
923// ----------------------------------------------------------------------------
924// transaction
925// ----------------------------------------------------------------------------
926
Dan Stoza7dde5992015-05-22 09:51:44 -0700927void Layer::pushPendingState() {
928 if (!mCurrentState.modified) {
929 return;
930 }
931
Dan Stoza7dde5992015-05-22 09:51:44 -0700932 // If this transaction is waiting on the receipt of a frame, generate a sync
933 // point and send it to the remote layer.
934 if (mCurrentState.handle != nullptr) {
935 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
936 sp<Layer> handleLayer = handle->owner.promote();
937 if (handleLayer == nullptr) {
938 ALOGE("[%s] Unable to promote Layer handle", mName.string());
939 // If we can't promote the layer we are intended to wait on,
940 // then it is expired or otherwise invalid. Allow this transaction
941 // to be applied as per normal (no synchronization).
942 mCurrentState.handle = nullptr;
Pablo Ceballos3bddd5b2015-11-19 14:39:14 -0800943 } else {
944 auto syncPoint = std::make_shared<SyncPoint>(
945 mCurrentState.frameNumber);
Dan Stozacac35382016-01-27 12:21:06 -0800946 if (handleLayer->addSyncPoint(syncPoint)) {
947 mRemoteSyncPoints.push_back(std::move(syncPoint));
948 } else {
949 // We already missed the frame we're supposed to synchronize
950 // on, so go ahead and apply the state update
951 mCurrentState.handle = nullptr;
952 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700953 }
954
Dan Stoza7dde5992015-05-22 09:51:44 -0700955 // Wake us up to check if the frame has been received
956 setTransactionFlags(eTransactionNeeded);
957 }
958 mPendingStates.push_back(mCurrentState);
959}
960
961void Layer::popPendingState() {
962 auto oldFlags = mCurrentState.flags;
963 mCurrentState = mPendingStates[0];
Dan Stozacac35382016-01-27 12:21:06 -0800964 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
Dan Stoza7dde5992015-05-22 09:51:44 -0700965 (mCurrentState.flags & mCurrentState.mask);
966
967 mPendingStates.removeAt(0);
968}
969
970bool Layer::applyPendingStates() {
Dan Stoza7dde5992015-05-22 09:51:44 -0700971 bool stateUpdateAvailable = false;
972 while (!mPendingStates.empty()) {
973 if (mPendingStates[0].handle != nullptr) {
974 if (mRemoteSyncPoints.empty()) {
975 // If we don't have a sync point for this, apply it anyway. It
976 // will be visually wrong, but it should keep us from getting
977 // into too much trouble.
978 ALOGE("[%s] No local sync point found", mName.string());
979 popPendingState();
980 stateUpdateAvailable = true;
981 continue;
982 }
983
Dan Stozacac35382016-01-27 12:21:06 -0800984 if (mRemoteSyncPoints.front()->getFrameNumber() !=
985 mPendingStates[0].frameNumber) {
986 ALOGE("[%s] Unexpected sync point frame number found",
987 mName.string());
988
989 // Signal our end of the sync point and then dispose of it
990 mRemoteSyncPoints.front()->setTransactionApplied();
991 mRemoteSyncPoints.pop_front();
992 continue;
993 }
994
Dan Stoza7dde5992015-05-22 09:51:44 -0700995 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
996 // Apply the state update
997 popPendingState();
998 stateUpdateAvailable = true;
999
1000 // Signal our end of the sync point and then dispose of it
1001 mRemoteSyncPoints.front()->setTransactionApplied();
1002 mRemoteSyncPoints.pop_front();
1003 }
1004 break;
1005 } else {
1006 popPendingState();
1007 stateUpdateAvailable = true;
1008 }
1009 }
1010
1011 // If we still have pending updates, wake SurfaceFlinger back up and point
1012 // it at this layer so we can process them
1013 if (!mPendingStates.empty()) {
1014 setTransactionFlags(eTransactionNeeded);
1015 mFlinger->setTransactionFlags(eTraversalNeeded);
1016 }
1017
1018 mCurrentState.modified = false;
1019 return stateUpdateAvailable;
1020}
1021
1022void Layer::notifyAvailableFrames() {
Dan Stozacac35382016-01-27 12:21:06 -08001023 auto headFrameNumber = getHeadFrameNumber();
1024 Mutex::Autolock lock(mLocalSyncPointMutex);
1025 for (auto& point : mLocalSyncPoints) {
1026 if (headFrameNumber >= point->getFrameNumber()) {
1027 point->setFrameAvailable();
1028 }
Dan Stoza7dde5992015-05-22 09:51:44 -07001029 }
1030}
1031
Mathias Agopian13127d82013-03-05 17:47:11 -08001032uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001033 ATRACE_CALL();
1034
Dan Stoza7dde5992015-05-22 09:51:44 -07001035 pushPendingState();
1036 if (!applyPendingStates()) {
1037 return 0;
1038 }
1039
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001040 const Layer::State& s(getDrawingState());
1041 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001042
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001043 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1044 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001045
1046 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001047 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001048 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001049 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001050 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1051 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1052 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1053 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001054 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1055 c.active.w, c.active.h,
1056 c.active.crop.left,
1057 c.active.crop.top,
1058 c.active.crop.right,
1059 c.active.crop.bottom,
1060 c.active.crop.getWidth(),
1061 c.active.crop.getHeight(),
1062 c.requested.w, c.requested.h,
1063 c.requested.crop.left,
1064 c.requested.crop.top,
1065 c.requested.crop.right,
1066 c.requested.crop.bottom,
1067 c.requested.crop.getWidth(),
1068 c.requested.crop.getHeight(),
1069 s.active.w, s.active.h,
1070 s.active.crop.left,
1071 s.active.crop.top,
1072 s.active.crop.right,
1073 s.active.crop.bottom,
1074 s.active.crop.getWidth(),
1075 s.active.crop.getHeight(),
1076 s.requested.w, s.requested.h,
1077 s.requested.crop.left,
1078 s.requested.crop.top,
1079 s.requested.crop.right,
1080 s.requested.crop.bottom,
1081 s.requested.crop.getWidth(),
1082 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001083
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001084 // record the new size, form this point on, when the client request
1085 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001086 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001087 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001088 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001089
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001090 if (!isFixedSize()) {
1091
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001092 const bool resizePending = (c.requested.w != c.active.w) ||
1093 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001094
Dan Stoza9e9b0442015-04-22 14:59:08 -07001095 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001096 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001097 // if we have a pending resize, unless we are in fixed-size mode.
1098 // the drawing state will be updated only once we receive a buffer
1099 // with the correct size.
1100 //
1101 // in particular, we want to make sure the clip (which is part
1102 // of the geometry state) is latched together with the size but is
1103 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001104 //
1105 // If a sideband stream is attached, however, we want to skip this
1106 // optimization so that transactions aren't missed when a buffer
1107 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001108
1109 flags |= eDontUpdateGeometryState;
1110 }
1111 }
1112
Mathias Agopian13127d82013-03-05 17:47:11 -08001113 // always set active to requested, unless we're asked not to
1114 // this is used by Layer, which special cases resizes.
1115 if (flags & eDontUpdateGeometryState) {
1116 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001117 Layer::State& editCurrentState(getCurrentState());
1118 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001119 }
1120
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001121 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001122 // invalidate and recompute the visible regions if needed
1123 flags |= Layer::eVisibleRegion;
1124 }
1125
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001126 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001127 // invalidate and recompute the visible regions if needed
1128 flags |= eVisibleRegion;
1129 this->contentDirty = true;
1130
1131 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001132 const uint8_t type = c.transform.getType();
1133 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001134 (type >= Transform::SCALE));
1135 }
1136
1137 // Commit the transaction
1138 commitTransaction();
1139 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001140}
1141
Mathias Agopian13127d82013-03-05 17:47:11 -08001142void Layer::commitTransaction() {
1143 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001144}
1145
Mathias Agopian13127d82013-03-05 17:47:11 -08001146uint32_t Layer::getTransactionFlags(uint32_t flags) {
1147 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1148}
1149
1150uint32_t Layer::setTransactionFlags(uint32_t flags) {
1151 return android_atomic_or(flags, &mTransactionFlags);
1152}
1153
1154bool Layer::setPosition(float x, float y) {
1155 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1156 return false;
1157 mCurrentState.sequence++;
1158 mCurrentState.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001159 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001160 setTransactionFlags(eTransactionNeeded);
1161 return true;
1162}
1163bool Layer::setLayer(uint32_t z) {
1164 if (mCurrentState.z == z)
1165 return false;
1166 mCurrentState.sequence++;
1167 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001168 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001169 setTransactionFlags(eTransactionNeeded);
1170 return true;
1171}
1172bool Layer::setSize(uint32_t w, uint32_t h) {
1173 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1174 return false;
1175 mCurrentState.requested.w = w;
1176 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001177 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001178 setTransactionFlags(eTransactionNeeded);
1179 return true;
1180}
1181bool Layer::setAlpha(uint8_t alpha) {
1182 if (mCurrentState.alpha == alpha)
1183 return false;
1184 mCurrentState.sequence++;
1185 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001186 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001187 setTransactionFlags(eTransactionNeeded);
1188 return true;
1189}
1190bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1191 mCurrentState.sequence++;
1192 mCurrentState.transform.set(
1193 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001194 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001195 setTransactionFlags(eTransactionNeeded);
1196 return true;
1197}
1198bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001199 mCurrentState.requestedTransparentRegion = transparent;
Dan Stoza7dde5992015-05-22 09:51:44 -07001200 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001201 setTransactionFlags(eTransactionNeeded);
1202 return true;
1203}
1204bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1205 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1206 if (mCurrentState.flags == newFlags)
1207 return false;
1208 mCurrentState.sequence++;
1209 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001210 mCurrentState.mask = mask;
1211 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001212 setTransactionFlags(eTransactionNeeded);
1213 return true;
1214}
1215bool Layer::setCrop(const Rect& crop) {
1216 if (mCurrentState.requested.crop == crop)
1217 return false;
1218 mCurrentState.sequence++;
1219 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001220 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001221 setTransactionFlags(eTransactionNeeded);
1222 return true;
1223}
1224
1225bool Layer::setLayerStack(uint32_t layerStack) {
1226 if (mCurrentState.layerStack == layerStack)
1227 return false;
1228 mCurrentState.sequence++;
1229 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001230 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001231 setTransactionFlags(eTransactionNeeded);
1232 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001233}
1234
Dan Stoza7dde5992015-05-22 09:51:44 -07001235void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1236 uint64_t frameNumber) {
1237 mCurrentState.handle = handle;
1238 mCurrentState.frameNumber = frameNumber;
1239 // We don't set eTransactionNeeded, because just receiving a deferral
1240 // request without any other state updates shouldn't actually induce a delay
1241 mCurrentState.modified = true;
1242 pushPendingState();
1243 mCurrentState.modified = false;
1244}
1245
Dan Stozaee44edd2015-03-23 15:50:23 -07001246void Layer::useSurfaceDamage() {
1247 if (mFlinger->mForceFullDamage) {
1248 surfaceDamageRegion = Region::INVALID_REGION;
1249 } else {
1250 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1251 }
1252}
1253
1254void Layer::useEmptyDamage() {
1255 surfaceDamageRegion.clear();
1256}
1257
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001258// ----------------------------------------------------------------------------
1259// pageflip handling...
1260// ----------------------------------------------------------------------------
1261
Dan Stoza6b9454d2014-11-07 16:00:59 -08001262bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001263 if (mSidebandStreamChanged || mAutoRefresh) {
Dan Stozad87defa2015-07-29 16:15:50 -07001264 return true;
1265 }
1266
Dan Stoza6b9454d2014-11-07 16:00:59 -08001267 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001268 if (mQueueItems.empty()) {
1269 return false;
1270 }
1271 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001272 nsecs_t expectedPresent =
1273 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001274
1275 // Ignore timestamps more than a second in the future
1276 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1277 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1278 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1279 expectedPresent);
1280
1281 bool isDue = timestamp < expectedPresent;
1282 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001283}
1284
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001285bool Layer::onPreComposition() {
1286 mRefreshPending = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001287 return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001288}
1289
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001290void Layer::onPostComposition() {
1291 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001292 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001293 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1294
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001295 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001296 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001297 mFrameTracker.setFrameReadyFence(frameReadyFence);
1298 } else {
1299 // There was no fence for this frame, so assume that it was ready
1300 // to be presented at the desired present time.
1301 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1302 }
1303
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001304 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001305 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001306 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001307 mFrameTracker.setActualPresentFence(presentFence);
1308 } else {
1309 // The HWC doesn't support present fences, so use the refresh
1310 // timestamp instead.
1311 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1312 mFrameTracker.setActualPresentTime(presentTime);
1313 }
1314
1315 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001316 mFrameLatencyNeeded = false;
1317 }
1318}
1319
Mathias Agopianda27af92012-09-13 18:17:13 -07001320bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001321 const Layer::State& s(mDrawingState);
1322 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001323 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001324}
1325
Mathias Agopian4fec8732012-06-29 14:12:52 -07001326Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001327{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001328 ATRACE_CALL();
1329
Jesse Hall399184a2014-03-03 15:42:54 -08001330 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1331 // mSidebandStreamChanged was true
1332 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001333 if (mSidebandStream != NULL) {
1334 setTransactionFlags(eTransactionNeeded);
1335 mFlinger->setTransactionFlags(eTraversalNeeded);
1336 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001337 recomputeVisibleRegions = true;
1338
1339 const State& s(getDrawingState());
1340 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001341 }
1342
Mathias Agopian4fec8732012-06-29 14:12:52 -07001343 Region outDirtyRegion;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001344 if (mQueuedFrames > 0 || mAutoRefresh) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001345
1346 // if we've already called updateTexImage() without going through
1347 // a composition step, we have to skip this layer at this point
1348 // because we cannot call updateTeximage() without a corresponding
1349 // compositionComplete() call.
1350 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001351 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001352 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001353 }
1354
Jamie Gennis351a5132011-09-14 18:23:37 -07001355 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001356 const State& s(getDrawingState());
1357 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001358 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001359
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001360 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001361 Layer::State& front;
1362 Layer::State& current;
1363 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001364 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001365 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001366 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001367 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001368 recomputeVisibleRegions(recomputeVisibleRegions),
1369 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001370 }
1371
1372 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001373 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001374 if (buf == NULL) {
1375 return false;
1376 }
1377
1378 uint32_t bufWidth = buf->getWidth();
1379 uint32_t bufHeight = buf->getHeight();
1380
1381 // check that we received a buffer of the right size
1382 // (Take the buffer's orientation into account)
1383 if (item.mTransform & Transform::ROT_90) {
1384 swap(bufWidth, bufHeight);
1385 }
1386
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001387 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1388 if (front.active != front.requested) {
1389
1390 if (isFixedSize ||
1391 (bufWidth == front.requested.w &&
1392 bufHeight == front.requested.h))
1393 {
1394 // Here we pretend the transaction happened by updating the
1395 // current and drawing states. Drawing state is only accessed
1396 // in this thread, no need to have it locked
1397 front.active = front.requested;
1398
1399 // We also need to update the current state so that
1400 // we don't end-up overwriting the drawing state with
1401 // this stale current state during the next transaction
1402 //
1403 // NOTE: We don't need to hold the transaction lock here
1404 // because State::active is only accessed from this thread.
1405 current.active = front.active;
1406
1407 // recompute visible region
1408 recomputeVisibleRegions = true;
1409 }
1410
1411 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001412 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001413 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1414 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001415 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001416 front.active.w, front.active.h,
1417 front.active.crop.left,
1418 front.active.crop.top,
1419 front.active.crop.right,
1420 front.active.crop.bottom,
1421 front.active.crop.getWidth(),
1422 front.active.crop.getHeight(),
1423 front.requested.w, front.requested.h,
1424 front.requested.crop.left,
1425 front.requested.crop.top,
1426 front.requested.crop.right,
1427 front.requested.crop.bottom,
1428 front.requested.crop.getWidth(),
1429 front.requested.crop.getHeight());
1430 }
1431
Ruben Brunk1681d952014-06-27 15:51:55 -07001432 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001433 if (front.active.w != bufWidth ||
1434 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001435 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001436 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1437 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001438 return true;
1439 }
1440 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001441
1442 // if the transparent region has changed (this test is
1443 // conservative, but that's fine, worst case we're doing
1444 // a bit of extra work), we latch the new one and we
1445 // trigger a visible-region recompute.
1446 if (!front.activeTransparentRegion.isTriviallyEqual(
1447 front.requestedTransparentRegion)) {
1448 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001449
1450 // We also need to update the current state so that
1451 // we don't end-up overwriting the drawing state with
1452 // this stale current state during the next transaction
1453 //
1454 // NOTE: We don't need to hold the transaction lock here
1455 // because State::active is only accessed from this thread.
1456 current.activeTransparentRegion = front.activeTransparentRegion;
1457
1458 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001459 recomputeVisibleRegions = true;
1460 }
1461
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001462 return false;
1463 }
1464 };
1465
Ruben Brunk1681d952014-06-27 15:51:55 -07001466 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1467 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001468
Dan Stozacac35382016-01-27 12:21:06 -08001469
1470 // Check all of our local sync points to ensure that all transactions
1471 // which need to have been applied prior to the frame which is about to
1472 // be latched have signaled
1473
1474 auto headFrameNumber = getHeadFrameNumber();
1475 bool matchingFramesFound = false;
1476 bool allTransactionsApplied = true;
Dan Stozaa4650a52015-05-12 12:56:16 -07001477 {
Dan Stozacac35382016-01-27 12:21:06 -08001478 Mutex::Autolock lock(mLocalSyncPointMutex);
1479 for (auto& point : mLocalSyncPoints) {
1480 if (point->getFrameNumber() > headFrameNumber) {
1481 break;
1482 }
1483
1484 matchingFramesFound = true;
1485
1486 if (!point->frameIsAvailable()) {
1487 // We haven't notified the remote layer that the frame for
1488 // this point is available yet. Notify it now, and then
1489 // abort this attempt to latch.
1490 point->setFrameAvailable();
1491 allTransactionsApplied = false;
1492 break;
1493 }
1494
1495 allTransactionsApplied &= point->transactionIsApplied();
Dan Stoza7dde5992015-05-22 09:51:44 -07001496 }
1497 }
1498
Dan Stozacac35382016-01-27 12:21:06 -08001499 if (matchingFramesFound && !allTransactionsApplied) {
1500 mFlinger->signalLayerUpdate();
1501 return outDirtyRegion;
Dan Stozaa4650a52015-05-12 12:56:16 -07001502 }
1503
Pablo Ceballos06312182015-10-07 16:32:12 -07001504 // This boolean is used to make sure that SurfaceFlinger's shadow copy
1505 // of the buffer queue isn't modified when the buffer queue is returning
1506 // BufferItem's that weren't actually queued. This can happen in single
1507 // buffer mode.
1508 bool queuedBuffer = false;
Andy McFadden41d67d72014-04-25 16:58:34 -07001509 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001510 mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
Dan Stozacac35382016-01-27 12:21:06 -08001511 mLastFrameNumberReceived);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001512 if (updateResult == BufferQueue::PRESENT_LATER) {
1513 // Producer doesn't want buffer to be displayed yet. Signal a
1514 // layer update so we check again at the next opportunity.
1515 mFlinger->signalLayerUpdate();
1516 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001517 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1518 // If the buffer has been rejected, remove it from the shadow queue
1519 // and return early
Pablo Ceballos06312182015-10-07 16:32:12 -07001520 if (queuedBuffer) {
1521 Mutex::Autolock lock(mQueueItemLock);
1522 mQueueItems.removeAt(0);
1523 android_atomic_dec(&mQueuedFrames);
1524 }
Dan Stozaecc50402015-04-28 14:42:06 -07001525 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001526 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1527 // This can occur if something goes wrong when trying to create the
1528 // EGLImage for this buffer. If this happens, the buffer has already
1529 // been released, so we need to clean up the queue and bug out
1530 // early.
Pablo Ceballos06312182015-10-07 16:32:12 -07001531 if (queuedBuffer) {
Dan Stoza65476f32015-05-14 09:27:25 -07001532 Mutex::Autolock lock(mQueueItemLock);
1533 mQueueItems.clear();
1534 android_atomic_and(0, &mQueuedFrames);
1535 }
1536
1537 // Once we have hit this state, the shadow queue may no longer
1538 // correctly reflect the incoming BufferQueue's contents, so even if
1539 // updateTexImage starts working, the only safe course of action is
1540 // to continue to ignore updates.
1541 mUpdateTexImageFailed = true;
1542
1543 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001544 }
1545
Pablo Ceballos06312182015-10-07 16:32:12 -07001546 if (queuedBuffer) {
1547 // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001548 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1549
Dan Stoza6b9454d2014-11-07 16:00:59 -08001550 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001551
1552 // Remove any stale buffers that have been dropped during
1553 // updateTexImage
1554 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1555 mQueueItems.removeAt(0);
1556 android_atomic_dec(&mQueuedFrames);
1557 }
1558
Dan Stoza6b9454d2014-11-07 16:00:59 -08001559 mQueueItems.removeAt(0);
1560 }
1561
Dan Stozaecc50402015-04-28 14:42:06 -07001562
Andy McFadden1585c4d2013-06-28 13:52:40 -07001563 // Decrement the queued-frames count. Signal another event if we
1564 // have more frames pending.
Pablo Ceballos06312182015-10-07 16:32:12 -07001565 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001566 || mAutoRefresh) {
Andy McFadden1585c4d2013-06-28 13:52:40 -07001567 mFlinger->signalLayerUpdate();
1568 }
1569
1570 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001571 // something happened!
1572 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001573 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001574 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001575
Jamie Gennis351a5132011-09-14 18:23:37 -07001576 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001577 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001578 if (mActiveBuffer == NULL) {
1579 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001580 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001581 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001582
Mathias Agopian4824d402012-06-04 18:16:30 -07001583 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001584 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001585 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001586 // the first time we receive a buffer, we need to trigger a
1587 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001588 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001589 }
1590
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001591 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1592 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1593 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001594 if ((crop != mCurrentCrop) ||
1595 (transform != mCurrentTransform) ||
1596 (scalingMode != mCurrentScalingMode))
1597 {
1598 mCurrentCrop = crop;
1599 mCurrentTransform = transform;
1600 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001601 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001602 }
1603
1604 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001605 uint32_t bufWidth = mActiveBuffer->getWidth();
1606 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001607 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1608 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001609 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001610 }
1611 }
1612
1613 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001614 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001615 recomputeVisibleRegions = true;
1616 }
1617
Dan Stozacac35382016-01-27 12:21:06 -08001618 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1619
1620 // Remove any sync points corresponding to the buffer which was just
1621 // latched
1622 {
1623 Mutex::Autolock lock(mLocalSyncPointMutex);
1624 auto point = mLocalSyncPoints.begin();
1625 while (point != mLocalSyncPoints.end()) {
1626 if (!(*point)->frameIsAvailable() ||
1627 !(*point)->transactionIsApplied()) {
1628 // This sync point must have been added since we started
1629 // latching. Don't drop it yet.
1630 ++point;
1631 continue;
1632 }
1633
1634 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
1635 point = mLocalSyncPoints.erase(point);
1636 } else {
1637 ++point;
1638 }
1639 }
1640 }
1641
Mathias Agopian4fec8732012-06-29 14:12:52 -07001642 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001643 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001644
1645 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001646 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001647 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001648 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001649}
1650
Mathias Agopiana67932f2011-04-20 14:20:59 -07001651uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001652{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001653 // TODO: should we do something special if mSecure is set?
1654 if (mProtectedByApp) {
1655 // need a hardware-protected path to external video sink
1656 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001657 }
Riley Andrews03414a12014-07-01 14:22:59 -07001658 if (mPotentialCursor) {
1659 usage |= GraphicBuffer::USAGE_CURSOR;
1660 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001661 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001662 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001663}
1664
Mathias Agopian84300952012-11-21 16:02:13 -08001665void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001666 uint32_t orientation = 0;
1667 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001668 // The transform hint is used to improve performance, but we can
1669 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001670 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001671 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001672 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001673 if (orientation & Transform::ROT_INVALID) {
1674 orientation = 0;
1675 }
1676 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001677 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001678}
1679
Mathias Agopian13127d82013-03-05 17:47:11 -08001680// ----------------------------------------------------------------------------
1681// debugging
1682// ----------------------------------------------------------------------------
1683
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001684void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001685{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001686 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001687
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001688 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001689 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001690 "+ %s %p (%s)\n",
1691 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001692 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001693
Mathias Agopian2ca79392013-04-02 18:30:32 -07001694 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001695 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001696 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001697 sp<Client> client(mClientRef.promote());
1698
Mathias Agopian74d211a2013-04-22 16:55:35 +02001699 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001700 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1701 "isOpaque=%1d, invalidate=%1d, "
1702 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1703 " client=%p\n",
1704 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1705 s.active.crop.left, s.active.crop.top,
1706 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001707 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001708 s.alpha, s.flags,
1709 s.transform[0][0], s.transform[0][1],
1710 s.transform[1][0], s.transform[1][1],
1711 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001712
1713 sp<const GraphicBuffer> buf0(mActiveBuffer);
1714 uint32_t w0=0, h0=0, s0=0, f0=0;
1715 if (buf0 != 0) {
1716 w0 = buf0->getWidth();
1717 h0 = buf0->getHeight();
1718 s0 = buf0->getStride();
1719 f0 = buf0->format;
1720 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001721 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001722 " "
1723 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1724 " queued-frames=%d, mRefreshPending=%d\n",
1725 mFormat, w0, h0, s0,f0,
1726 mQueuedFrames, mRefreshPending);
1727
Mathias Agopian13127d82013-03-05 17:47:11 -08001728 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001729 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001730 }
1731}
1732
Svetoslavd85084b2014-03-20 10:28:31 -07001733void Layer::dumpFrameStats(String8& result) const {
1734 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001735}
1736
Svetoslavd85084b2014-03-20 10:28:31 -07001737void Layer::clearFrameStats() {
1738 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001739}
1740
Jamie Gennis6547ff42013-07-16 20:12:42 -07001741void Layer::logFrameStats() {
1742 mFrameTracker.logAndResetStats(mName);
1743}
1744
Svetoslavd85084b2014-03-20 10:28:31 -07001745void Layer::getFrameStats(FrameStats* outStats) const {
1746 mFrameTracker.getStats(outStats);
1747}
1748
Mathias Agopian13127d82013-03-05 17:47:11 -08001749// ---------------------------------------------------------------------------
1750
1751Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1752 const sp<Layer>& layer)
1753 : mFlinger(flinger), mLayer(layer) {
1754}
1755
1756Layer::LayerCleaner::~LayerCleaner() {
1757 // destroy client resources
1758 mFlinger->onLayerDestroyed(mLayer);
1759}
1760
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001761// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001762}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001763
1764#if defined(__gl_h_)
1765#error "don't include gl/gl.h in this file"
1766#endif
1767
1768#if defined(__gl2_h_)
1769#error "don't include gl2/gl2.h in this file"
1770#endif