blob: a7b167fbc32e585d9b54f50974633789dae5c396 [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),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080076 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080077 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080078 mFiltering(false),
79 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070080 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080081 mProtectedByApp(false),
82 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070083 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070084 mPotentialCursor(false),
85 mQueueItemLock(),
86 mQueueItemCondition(),
87 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070088 mLastFrameNumberReceived(0),
89 mUpdateTexImageFailed(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080090{
Mathias Agopiana67932f2011-04-20 14:20:59 -070091 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070092 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070093 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070094
95 uint32_t layerFlags = 0;
96 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080097 layerFlags |= layer_state_t::eLayerHidden;
98 if (flags & ISurfaceComposerClient::eOpaque)
99 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -0700100 if (flags & ISurfaceComposerClient::eSecure)
101 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700102
103 if (flags & ISurfaceComposerClient::eNonPremultiplied)
104 mPremultipliedAlpha = false;
105
106 mName = name;
107
108 mCurrentState.active.w = w;
109 mCurrentState.active.h = h;
110 mCurrentState.active.crop.makeInvalid();
111 mCurrentState.z = 0;
112 mCurrentState.alpha = 0xFF;
113 mCurrentState.layerStack = 0;
114 mCurrentState.flags = layerFlags;
115 mCurrentState.sequence = 0;
116 mCurrentState.transform.set(0, 0);
117 mCurrentState.requested = mCurrentState.active;
118
119 // drawing state & current state are identical
120 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700121
122 nsecs_t displayPeriod =
123 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
124 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800125}
126
Mathias Agopian3f844832013-08-07 21:24:32 -0700127void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800128 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700129 sp<IGraphicBufferProducer> producer;
130 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700131 BufferQueue::createBufferQueue(&producer, &consumer);
132 mProducer = new MonitoredProducer(producer, mFlinger);
133 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800134 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800135 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700136 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800137
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700138#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
139#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700140#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700141 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800142#endif
Andy McFadden69052052012-09-14 16:10:11 -0700143
Mathias Agopian84300952012-11-21 16:02:13 -0800144 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
145 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700146}
147
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700148Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800149 sp<Client> c(mClientRef.promote());
150 if (c != 0) {
151 c->detachLayer(this);
152 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700153 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700154 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700155}
156
Mathias Agopian13127d82013-03-05 17:47:11 -0800157// ---------------------------------------------------------------------------
158// callbacks
159// ---------------------------------------------------------------------------
160
Dan Stozac7014012014-02-14 15:03:43 -0800161void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800162 HWComposer::HWCLayerInterface* layer) {
163 if (layer) {
164 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700165 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800166 }
167}
168
Dan Stoza7dde5992015-05-22 09:51:44 -0700169void Layer::markSyncPointsAvailable(const BufferItem& item) {
170 auto pointIter = mLocalSyncPoints.begin();
171 while (pointIter != mLocalSyncPoints.end()) {
172 if ((*pointIter)->getFrameNumber() == item.mFrameNumber) {
173 auto syncPoint = *pointIter;
174 pointIter = mLocalSyncPoints.erase(pointIter);
175 Mutex::Autolock lock(mAvailableFrameMutex);
176 mAvailableFrames.push_back(std::move(syncPoint));
177 } else {
178 ++pointIter;
179 }
180 }
181}
182
Dan Stoza6b9454d2014-11-07 16:00:59 -0800183void Layer::onFrameAvailable(const BufferItem& item) {
184 // Add this buffer from our internal queue tracker
185 { // Autolock scope
186 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700187
188 // Reset the frame number tracker when we receive the first buffer after
189 // a frame number reset
190 if (item.mFrameNumber == 1) {
191 mLastFrameNumberReceived = 0;
192 }
193
194 // Ensure that callbacks are handled in order
195 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
196 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
197 ms2ns(500));
198 if (result != NO_ERROR) {
199 ALOGE("[%s] Timed out waiting on callback", mName.string());
200 }
201 }
202
Dan Stoza6b9454d2014-11-07 16:00:59 -0800203 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700204 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700205
206 // Wake up any pending callbacks
207 mLastFrameNumberReceived = item.mFrameNumber;
208 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800209 }
210
Dan Stoza7dde5992015-05-22 09:51:44 -0700211 markSyncPointsAvailable(item);
212
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800213 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700214}
215
Dan Stoza6b9454d2014-11-07 16:00:59 -0800216void Layer::onFrameReplaced(const BufferItem& item) {
Dan Stoza7dde5992015-05-22 09:51:44 -0700217 { // Autolock scope
218 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700219
Dan Stoza7dde5992015-05-22 09:51:44 -0700220 // Ensure that callbacks are handled in order
221 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
222 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
223 ms2ns(500));
224 if (result != NO_ERROR) {
225 ALOGE("[%s] Timed out waiting on callback", mName.string());
226 }
Dan Stozaa4650a52015-05-12 12:56:16 -0700227 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700228
229 if (mQueueItems.empty()) {
230 ALOGE("Can't replace a frame on an empty queue");
231 return;
232 }
233 mQueueItems.editItemAt(0) = item;
234
235 // Wake up any pending callbacks
236 mLastFrameNumberReceived = item.mFrameNumber;
237 mQueueItemCondition.broadcast();
Dan Stozaa4650a52015-05-12 12:56:16 -0700238 }
239
Dan Stoza7dde5992015-05-22 09:51:44 -0700240 markSyncPointsAvailable(item);
Dan Stoza6b9454d2014-11-07 16:00:59 -0800241}
242
Jesse Hall399184a2014-03-03 15:42:54 -0800243void Layer::onSidebandStreamChanged() {
244 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
245 // mSidebandStreamChanged was false
246 mFlinger->signalLayerUpdate();
247 }
248}
249
Mathias Agopian67106042013-03-14 19:18:13 -0700250// called with SurfaceFlinger::mStateLock from the drawing thread after
251// the layer has been remove from the current state list (and just before
252// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800253void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800254 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700255}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700256
Mathias Agopian13127d82013-03-05 17:47:11 -0800257// ---------------------------------------------------------------------------
258// set-up
259// ---------------------------------------------------------------------------
260
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700261const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800262 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800263}
264
Mathias Agopianf9d93272009-06-19 17:00:27 -0700265status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800266 PixelFormat format, uint32_t flags)
267{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700268 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700269 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700270
271 // never allow a surface larger than what our underlying GL implementation
272 // can handle.
273 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800274 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700275 return BAD_VALUE;
276 }
277
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700278 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700279
Riley Andrews03414a12014-07-01 14:22:59 -0700280 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700281 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700282 mCurrentOpacity = getOpacityForFormat(format);
283
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800284 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
285 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
286 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700287
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800288 return NO_ERROR;
289}
290
Dan Stoza7dde5992015-05-22 09:51:44 -0700291/*
292 * The layer handle is just a BBinder object passed to the client
293 * (remote process) -- we don't keep any reference on our side such that
294 * the dtor is called when the remote side let go of its reference.
295 *
296 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
297 * this layer when the handle is destroyed.
298 */
299class Layer::Handle : public BBinder, public LayerCleaner {
300 public:
301 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
302 : LayerCleaner(flinger, layer), owner(layer) {}
303
304 wp<Layer> owner;
305};
306
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700307sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800308 Mutex::Autolock _l(mLock);
309
310 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700311 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800312
313 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700314
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700315 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800316}
317
Dan Stozab9b08832014-03-13 11:55:57 -0700318sp<IGraphicBufferProducer> Layer::getProducer() const {
319 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700320}
321
Mathias Agopian13127d82013-03-05 17:47:11 -0800322// ---------------------------------------------------------------------------
323// h/w composer set-up
324// ---------------------------------------------------------------------------
325
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800326Rect Layer::getContentCrop() const {
327 // this is the crop rectangle that applies to the buffer
328 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700329 Rect crop;
330 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800331 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700332 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800333 } else if (mActiveBuffer != NULL) {
334 // otherwise we use the whole buffer
335 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700336 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800337 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700338 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700339 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700340 return crop;
341}
342
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700343static Rect reduce(const Rect& win, const Region& exclude) {
344 if (CC_LIKELY(exclude.isEmpty())) {
345 return win;
346 }
347 if (exclude.isRect()) {
348 return win.reduce(exclude.getBounds());
349 }
350 return Region(win).subtract(exclude).getBounds();
351}
352
Mathias Agopian13127d82013-03-05 17:47:11 -0800353Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700354 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700355 return computeBounds(s.activeTransparentRegion);
356}
357
358Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
359 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800360 Rect win(s.active.w, s.active.h);
361 if (!s.active.crop.isEmpty()) {
362 win.intersect(s.active.crop, &win);
363 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700364 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700365 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800366}
367
Mathias Agopian6b442672013-07-09 21:24:52 -0700368FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800369 // the content crop is the area of the content that gets scaled to the
370 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700371 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800372
373 // the active.crop is the area of the window that gets cropped, but not
374 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700375 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800376
377 // apply the projection's clipping to the window crop in
378 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700379 // if there are no window scaling involved, this operation will map to full
380 // pixels in the buffer.
381 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
382 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700383
384 Rect activeCrop(s.active.w, s.active.h);
385 if (!s.active.crop.isEmpty()) {
386 activeCrop = s.active.crop;
387 }
388
389 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800390 activeCrop.intersect(hw->getViewport(), &activeCrop);
391 activeCrop = s.transform.inverse().transform(activeCrop);
392
Michael Lentine28ea2172014-11-19 18:32:37 -0800393 // This needs to be here as transform.transform(Rect) computes the
394 // transformed rect and then takes the bounding box of the result before
395 // returning. This means
396 // transform.inverse().transform(transform.transform(Rect)) != Rect
397 // in which case we need to make sure the final rect is clipped to the
398 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800399 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
400
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700401 // subtract the transparent region and snap to the bounds
402 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
403
Mathias Agopian13127d82013-03-05 17:47:11 -0800404 if (!activeCrop.isEmpty()) {
405 // Transform the window crop to match the buffer coordinate system,
406 // which means using the inverse of the current transform set on the
407 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700408 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700409 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
410 /*
411 * the code below applies the display's inverse transform to the buffer
412 */
413 uint32_t invTransformOrient = hw->getOrientationTransform();
414 // calculate the inverse transform
415 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
416 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
417 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700418 // If the transform has been rotated the axis of flip has been swapped
419 // so we need to swap which flip operations we are performing
420 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
421 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
422 if (is_h_flipped != is_v_flipped) {
423 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
424 NATIVE_WINDOW_TRANSFORM_FLIP_H;
425 }
Michael Lentinef7551402014-08-18 16:35:43 -0700426 }
427 // and apply to the current transform
428 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
429 }
430
Mathias Agopian13127d82013-03-05 17:47:11 -0800431 int winWidth = s.active.w;
432 int winHeight = s.active.h;
433 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700434 // If the activeCrop has been rotate the ends are rotated but not
435 // the space itself so when transforming ends back we can't rely on
436 // a modification of the axes of rotation. To account for this we
437 // need to reorient the inverse rotation in terms of the current
438 // axes of rotation.
439 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
440 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
441 if (is_h_flipped == is_v_flipped) {
442 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
443 NATIVE_WINDOW_TRANSFORM_FLIP_H;
444 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800445 winWidth = s.active.h;
446 winHeight = s.active.w;
447 }
448 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700449 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800450
Mathias Agopian6b442672013-07-09 21:24:52 -0700451 // below, crop is intersected with winCrop expressed in crop's coordinate space
452 float xScale = crop.getWidth() / float(winWidth);
453 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800454
Michael Lentinef7551402014-08-18 16:35:43 -0700455 float insetL = winCrop.left * xScale;
456 float insetT = winCrop.top * yScale;
457 float insetR = (winWidth - winCrop.right ) * xScale;
458 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800459
460 crop.left += insetL;
461 crop.top += insetT;
462 crop.right -= insetR;
463 crop.bottom -= insetB;
464 }
465 return crop;
466}
467
Mathias Agopian4fec8732012-06-29 14:12:52 -0700468void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700469 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700470 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700471{
Mathias Agopian13127d82013-03-05 17:47:11 -0800472 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700473
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700474 // enable this layer
475 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700476
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700477 if (isSecure() && !hw->isSecure()) {
478 layer.setSkip(true);
479 }
480
Mathias Agopian13127d82013-03-05 17:47:11 -0800481 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700482 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800483 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800484 layer.setBlending(mPremultipliedAlpha ?
485 HWC_BLENDING_PREMULT :
486 HWC_BLENDING_COVERAGE);
487 }
488
489 // apply the layer's transform, followed by the display's global transform
490 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700491 Region activeTransparentRegion(s.activeTransparentRegion);
492 if (!s.active.crop.isEmpty()) {
493 Rect activeCrop(s.active.crop);
494 activeCrop = s.transform.transform(activeCrop);
495 activeCrop.intersect(hw->getViewport(), &activeCrop);
496 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800497 // This needs to be here as transform.transform(Rect) computes the
498 // transformed rect and then takes the bounding box of the result before
499 // returning. This means
500 // transform.inverse().transform(transform.transform(Rect)) != Rect
501 // in which case we need to make sure the final rect is clipped to the
502 // display bounds.
503 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700504 // mark regions outside the crop as transparent
505 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
506 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
507 s.active.w, s.active.h));
508 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
509 activeCrop.left, activeCrop.bottom));
510 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
511 s.active.w, activeCrop.bottom));
512 }
513 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800514 frame.intersect(hw->getViewport(), &frame);
515 const Transform& tr(hw->getTransform());
516 layer.setFrame(tr.transform(frame));
517 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800518 layer.setPlaneAlpha(s.alpha);
519
Mathias Agopian29a367b2011-07-12 14:51:45 -0700520 /*
521 * Transformations are applied in this order:
522 * 1) buffer orientation/flip/mirror
523 * 2) state transformation (window manager)
524 * 3) layer orientation (screen orientation)
525 * (NOTE: the matrices are multiplied in reverse order)
526 */
527
528 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700529 Transform transform(tr * s.transform * bufferOrientation);
530
531 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
532 /*
533 * the code below applies the display's inverse transform to the buffer
534 */
535 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700536 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700537 // calculate the inverse transform
538 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
539 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
540 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700541 // If the transform has been rotated the axis of flip has been swapped
542 // so we need to swap which flip operations we are performing
543 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
544 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
545 if (is_h_flipped != is_v_flipped) {
546 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
547 NATIVE_WINDOW_TRANSFORM_FLIP_H;
548 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700549 }
550 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700551 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700552 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700553
554 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800555 const uint32_t orientation = transform.getOrientation();
556 if (orientation & Transform::ROT_INVALID) {
557 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700558 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700559 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800560 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700561 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700562}
563
Mathias Agopian42977342012-08-05 00:40:46 -0700564void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700565 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800566 // we have to set the visible region on every frame because
567 // we currently free it during onLayerDisplayed(), which is called
568 // after HWComposer::commit() -- every frame.
569 // Apply this display's projection's viewport to the visible region
570 // before giving it to the HWC HAL.
571 const Transform& tr = hw->getTransform();
572 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
573 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700574 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700575
Jesse Hall399184a2014-03-03 15:42:54 -0800576 if (mSidebandStream.get()) {
577 layer.setSidebandStream(mSidebandStream);
578 } else {
579 // NOTE: buffer can be NULL if the client never drew into this
580 // layer yet, or if we ran out of memory
581 layer.setBuffer(mActiveBuffer);
582 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700583}
Jesse Halldc5b4852012-06-29 15:21:18 -0700584
Dan Stozac7014012014-02-14 15:03:43 -0800585void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700586 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700587 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700588
589 // TODO: there is a possible optimization here: we only need to set the
590 // acquire fence the first time a new buffer is acquired on EACH display.
591
Riley Andrews03414a12014-07-01 14:22:59 -0700592 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800593 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800594 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700595 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700596 if (fenceFd == -1) {
597 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
598 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700599 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700600 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700601 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700602}
603
Riley Andrews03414a12014-07-01 14:22:59 -0700604Rect Layer::getPosition(
605 const sp<const DisplayDevice>& hw)
606{
607 // this gives us only the "orientation" component of the transform
608 const State& s(getCurrentState());
609
610 // apply the layer's transform, followed by the display's global transform
611 // here we're guaranteed that the layer's transform preserves rects
612 Rect win(s.active.w, s.active.h);
613 if (!s.active.crop.isEmpty()) {
614 win.intersect(s.active.crop, &win);
615 }
616 // subtract the transparent region and snap to the bounds
617 Rect bounds = reduce(win, s.activeTransparentRegion);
618 Rect frame(s.transform.transform(bounds));
619 frame.intersect(hw->getViewport(), &frame);
620 const Transform& tr(hw->getTransform());
621 return Rect(tr.transform(frame));
622}
623
Mathias Agopian13127d82013-03-05 17:47:11 -0800624// ---------------------------------------------------------------------------
625// drawing...
626// ---------------------------------------------------------------------------
627
628void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800629 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800630}
631
Dan Stozac7014012014-02-14 15:03:43 -0800632void Layer::draw(const sp<const DisplayDevice>& hw,
633 bool useIdentityTransform) const {
634 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800635}
636
Dan Stozac7014012014-02-14 15:03:43 -0800637void Layer::draw(const sp<const DisplayDevice>& hw) const {
638 onDraw(hw, Region(hw->bounds()), false);
639}
640
641void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
642 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800643{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800644 ATRACE_CALL();
645
Mathias Agopiana67932f2011-04-20 14:20:59 -0700646 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800647 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700648 // in fact never been drawn into. This happens frequently with
649 // SurfaceView because the WindowManager can't know when the client
650 // has drawn the first time.
651
652 // If there is nothing under us, we paint the screen in black, otherwise
653 // we just skip this update.
654
655 // figure out if there is something below us
656 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700657 const SurfaceFlinger::LayerVector& drawingLayers(
658 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700659 const size_t count = drawingLayers.size();
660 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800661 const sp<Layer>& layer(drawingLayers[i]);
662 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700663 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700664 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700665 }
666 // if not everything below us is covered, we plug the holes!
667 Region holes(clip.subtract(under));
668 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700669 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700670 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800671 return;
672 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700673
Andy McFadden97eba892012-12-11 15:21:45 -0800674 // Bind the current buffer to the GL texture, and wait for it to be
675 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800676 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
677 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800678 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700679 // Go ahead and draw the buffer anyway; no matter what we do the screen
680 // is probably going to have something visibly wrong.
681 }
682
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700683 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
684
Mathias Agopian875d8e12013-06-07 15:35:48 -0700685 RenderEngine& engine(mFlinger->getRenderEngine());
686
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700687 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700688 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700689 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700690
691 // Query the texture matrix given our current filtering mode.
692 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800693 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
694 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700695
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700696 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
697
698 /*
699 * the code below applies the display's inverse transform to the texture transform
700 */
701
702 // create a 4x4 transform matrix from the display transform flags
703 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
704 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
705 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
706
707 mat4 tr;
708 uint32_t transform = hw->getOrientationTransform();
709 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
710 tr = tr * rot90;
711 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
712 tr = tr * flipH;
713 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
714 tr = tr * flipV;
715
716 // calculate the inverse
717 tr = inverse(tr);
718
719 // and finally apply it to the original texture matrix
720 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
721 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
722 }
723
Jamie Genniscbb1a952012-05-08 17:05:52 -0700724 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700725 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
726 mTexture.setFiltering(useFiltering);
727 mTexture.setMatrix(textureMatrix);
728
729 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700730 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700731 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700732 }
Dan Stozac7014012014-02-14 15:03:43 -0800733 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700734 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800735}
736
Mathias Agopian13127d82013-03-05 17:47:11 -0800737
Dan Stozac7014012014-02-14 15:03:43 -0800738void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
739 const Region& /* clip */, float red, float green, float blue,
740 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800741{
Mathias Agopian19733a32013-08-28 18:13:56 -0700742 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800743 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700744 engine.setupFillWithColor(red, green, blue, alpha);
745 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800746}
747
748void Layer::clearWithOpenGL(
749 const sp<const DisplayDevice>& hw, const Region& clip) const {
750 clearWithOpenGL(hw, clip, 0,0,0,0);
751}
752
Dan Stozac7014012014-02-14 15:03:43 -0800753void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
754 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700755 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800756
Dan Stozac7014012014-02-14 15:03:43 -0800757 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800758
Mathias Agopian13127d82013-03-05 17:47:11 -0800759 /*
760 * NOTE: the way we compute the texture coordinates here produces
761 * different results than when we take the HWC path -- in the later case
762 * the "source crop" is rounded to texel boundaries.
763 * This can produce significantly different results when the texture
764 * is scaled by a large amount.
765 *
766 * The GL code below is more logical (imho), and the difference with
767 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700768 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800769 * GL composition when a buffer scaling is applied (maybe with some
770 * minimal value)? Or, we could make GL behave like HWC -- but this feel
771 * like more of a hack.
772 */
773 const Rect win(computeBounds());
774
Mathias Agopian3f844832013-08-07 21:24:32 -0700775 float left = float(win.left) / float(s.active.w);
776 float top = float(win.top) / float(s.active.h);
777 float right = float(win.right) / float(s.active.w);
778 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800779
Mathias Agopian875d8e12013-06-07 15:35:48 -0700780 // TODO: we probably want to generate the texture coords with the mesh
781 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700782 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
783 texCoords[0] = vec2(left, 1.0f - top);
784 texCoords[1] = vec2(left, 1.0f - bottom);
785 texCoords[2] = vec2(right, 1.0f - bottom);
786 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800787
Mathias Agopian875d8e12013-06-07 15:35:48 -0700788 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800789 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700790 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700791 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800792}
793
Ruben Brunk1681d952014-06-27 15:51:55 -0700794uint32_t Layer::getProducerStickyTransform() const {
795 int producerStickyTransform = 0;
796 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
797 if (ret != OK) {
798 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
799 strerror(-ret), ret);
800 return 0;
801 }
802 return static_cast<uint32_t>(producerStickyTransform);
803}
804
Dan Stoza7dde5992015-05-22 09:51:44 -0700805void Layer::addSyncPoint(std::shared_ptr<SyncPoint> point) {
806 uint64_t headFrameNumber = 0;
807 {
808 Mutex::Autolock lock(mQueueItemLock);
809 if (!mQueueItems.empty()) {
810 headFrameNumber = mQueueItems[0].mFrameNumber;
811 } else {
812 headFrameNumber = mLastFrameNumberReceived;
813 }
814 }
815
816 if (point->getFrameNumber() <= headFrameNumber) {
817 point->setFrameAvailable();
818 } else {
819 mLocalSyncPoints.push_back(std::move(point));
820 }
821}
822
Mathias Agopian13127d82013-03-05 17:47:11 -0800823void Layer::setFiltering(bool filtering) {
824 mFiltering = filtering;
825}
826
827bool Layer::getFiltering() const {
828 return mFiltering;
829}
830
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800831// As documented in libhardware header, formats in the range
832// 0x100 - 0x1FF are specific to the HAL implementation, and
833// are known to have no alpha channel
834// TODO: move definition for device-specific range into
835// hardware.h, instead of using hard-coded values here.
836#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
837
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700838bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700839 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
840 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800841 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700842 switch (format) {
843 case HAL_PIXEL_FORMAT_RGBA_8888:
844 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700845 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700846 }
847 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700848 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800849}
850
Mathias Agopian13127d82013-03-05 17:47:11 -0800851// ----------------------------------------------------------------------------
852// local state
853// ----------------------------------------------------------------------------
854
Dan Stozac7014012014-02-14 15:03:43 -0800855void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
856 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800857{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700858 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800859 const Transform tr(useIdentityTransform ?
860 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800861 const uint32_t hw_h = hw->getHeight();
862 Rect win(s.active.w, s.active.h);
863 if (!s.active.crop.isEmpty()) {
864 win.intersect(s.active.crop, &win);
865 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700866 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700867 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700868
Mathias Agopianff2ed702013-09-01 21:36:12 -0700869 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
870 position[0] = tr.transform(win.left, win.top);
871 position[1] = tr.transform(win.left, win.bottom);
872 position[2] = tr.transform(win.right, win.bottom);
873 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700874 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700875 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800876 }
877}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800878
Andy McFadden4125a4f2014-01-29 17:17:11 -0800879bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700880{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700881 // if we don't have a buffer yet, we're translucent regardless of the
882 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700883 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700884 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700885 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700886
887 // if the layer has the opaque flag, then we're always opaque,
888 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800889 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700890}
891
Dan Stoza23116082015-06-18 14:58:39 -0700892bool Layer::isSecure() const
893{
894 const Layer::State& s(mDrawingState);
895 return (s.flags & layer_state_t::eLayerSecure);
896}
897
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800898bool Layer::isProtected() const
899{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700900 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800901 return (activeBuffer != 0) &&
902 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
903}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700904
Mathias Agopian13127d82013-03-05 17:47:11 -0800905bool Layer::isFixedSize() const {
906 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
907}
908
909bool Layer::isCropped() const {
910 return !mCurrentCrop.isEmpty();
911}
912
913bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
914 return mNeedsFiltering || hw->needsFiltering();
915}
916
917void Layer::setVisibleRegion(const Region& visibleRegion) {
918 // always called from main thread
919 this->visibleRegion = visibleRegion;
920}
921
922void Layer::setCoveredRegion(const Region& coveredRegion) {
923 // always called from main thread
924 this->coveredRegion = coveredRegion;
925}
926
927void Layer::setVisibleNonTransparentRegion(const Region&
928 setVisibleNonTransparentRegion) {
929 // always called from main thread
930 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
931}
932
933// ----------------------------------------------------------------------------
934// transaction
935// ----------------------------------------------------------------------------
936
Dan Stoza7dde5992015-05-22 09:51:44 -0700937void Layer::pushPendingState() {
938 if (!mCurrentState.modified) {
939 return;
940 }
941
942 Mutex::Autolock lock(mPendingStateMutex);
943
944 // If this transaction is waiting on the receipt of a frame, generate a sync
945 // point and send it to the remote layer.
946 if (mCurrentState.handle != nullptr) {
947 sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
948 sp<Layer> handleLayer = handle->owner.promote();
949 if (handleLayer == nullptr) {
950 ALOGE("[%s] Unable to promote Layer handle", mName.string());
951 // If we can't promote the layer we are intended to wait on,
952 // then it is expired or otherwise invalid. Allow this transaction
953 // to be applied as per normal (no synchronization).
954 mCurrentState.handle = nullptr;
955 }
956
957 auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber);
958 handleLayer->addSyncPoint(syncPoint);
959 mRemoteSyncPoints.push_back(std::move(syncPoint));
960
961 // Wake us up to check if the frame has been received
962 setTransactionFlags(eTransactionNeeded);
963 }
964 mPendingStates.push_back(mCurrentState);
965}
966
967void Layer::popPendingState() {
968 auto oldFlags = mCurrentState.flags;
969 mCurrentState = mPendingStates[0];
970 mCurrentState.flags = (oldFlags & ~mCurrentState.mask) |
971 (mCurrentState.flags & mCurrentState.mask);
972
973 mPendingStates.removeAt(0);
974}
975
976bool Layer::applyPendingStates() {
977 Mutex::Autolock lock(mPendingStateMutex);
978
979 bool stateUpdateAvailable = false;
980 while (!mPendingStates.empty()) {
981 if (mPendingStates[0].handle != nullptr) {
982 if (mRemoteSyncPoints.empty()) {
983 // If we don't have a sync point for this, apply it anyway. It
984 // will be visually wrong, but it should keep us from getting
985 // into too much trouble.
986 ALOGE("[%s] No local sync point found", mName.string());
987 popPendingState();
988 stateUpdateAvailable = true;
989 continue;
990 }
991
992 if (mRemoteSyncPoints.front()->frameIsAvailable()) {
993 // Apply the state update
994 popPendingState();
995 stateUpdateAvailable = true;
996
997 // Signal our end of the sync point and then dispose of it
998 mRemoteSyncPoints.front()->setTransactionApplied();
999 mRemoteSyncPoints.pop_front();
1000 }
1001 break;
1002 } else {
1003 popPendingState();
1004 stateUpdateAvailable = true;
1005 }
1006 }
1007
1008 // If we still have pending updates, wake SurfaceFlinger back up and point
1009 // it at this layer so we can process them
1010 if (!mPendingStates.empty()) {
1011 setTransactionFlags(eTransactionNeeded);
1012 mFlinger->setTransactionFlags(eTraversalNeeded);
1013 }
1014
1015 mCurrentState.modified = false;
1016 return stateUpdateAvailable;
1017}
1018
1019void Layer::notifyAvailableFrames() {
1020 Mutex::Autolock lock(mAvailableFrameMutex);
1021 for (auto frame : mAvailableFrames) {
1022 frame->setFrameAvailable();
1023 }
1024}
1025
Mathias Agopian13127d82013-03-05 17:47:11 -08001026uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001027 ATRACE_CALL();
1028
Dan Stoza7dde5992015-05-22 09:51:44 -07001029 pushPendingState();
1030 if (!applyPendingStates()) {
1031 return 0;
1032 }
1033
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001034 const Layer::State& s(getDrawingState());
1035 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001036
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001037 const bool sizeChanged = (c.requested.w != s.requested.w) ||
1038 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -07001039
1040 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001041 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +00001042 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001043 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -07001044 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1045 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
1046 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1047 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001048 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
1049 c.active.w, c.active.h,
1050 c.active.crop.left,
1051 c.active.crop.top,
1052 c.active.crop.right,
1053 c.active.crop.bottom,
1054 c.active.crop.getWidth(),
1055 c.active.crop.getHeight(),
1056 c.requested.w, c.requested.h,
1057 c.requested.crop.left,
1058 c.requested.crop.top,
1059 c.requested.crop.right,
1060 c.requested.crop.bottom,
1061 c.requested.crop.getWidth(),
1062 c.requested.crop.getHeight(),
1063 s.active.w, s.active.h,
1064 s.active.crop.left,
1065 s.active.crop.top,
1066 s.active.crop.right,
1067 s.active.crop.bottom,
1068 s.active.crop.getWidth(),
1069 s.active.crop.getHeight(),
1070 s.requested.w, s.requested.h,
1071 s.requested.crop.left,
1072 s.requested.crop.top,
1073 s.requested.crop.right,
1074 s.requested.crop.bottom,
1075 s.requested.crop.getWidth(),
1076 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001077
Jamie Gennis2a0d5b62011-09-26 16:54:44 -07001078 // record the new size, form this point on, when the client request
1079 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001080 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001081 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001082 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -07001083
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001084 if (!isFixedSize()) {
1085
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001086 const bool resizePending = (c.requested.w != c.active.w) ||
1087 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001088
Dan Stoza9e9b0442015-04-22 14:59:08 -07001089 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001090 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001091 // if we have a pending resize, unless we are in fixed-size mode.
1092 // the drawing state will be updated only once we receive a buffer
1093 // with the correct size.
1094 //
1095 // in particular, we want to make sure the clip (which is part
1096 // of the geometry state) is latched together with the size but is
1097 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -07001098 //
1099 // If a sideband stream is attached, however, we want to skip this
1100 // optimization so that transactions aren't missed when a buffer
1101 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -07001102
1103 flags |= eDontUpdateGeometryState;
1104 }
1105 }
1106
Mathias Agopian13127d82013-03-05 17:47:11 -08001107 // always set active to requested, unless we're asked not to
1108 // this is used by Layer, which special cases resizes.
1109 if (flags & eDontUpdateGeometryState) {
1110 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001111 Layer::State& editCurrentState(getCurrentState());
1112 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -08001113 }
1114
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001115 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001116 // invalidate and recompute the visible regions if needed
1117 flags |= Layer::eVisibleRegion;
1118 }
1119
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001120 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -08001121 // invalidate and recompute the visible regions if needed
1122 flags |= eVisibleRegion;
1123 this->contentDirty = true;
1124
1125 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001126 const uint8_t type = c.transform.getType();
1127 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -08001128 (type >= Transform::SCALE));
1129 }
1130
1131 // Commit the transaction
1132 commitTransaction();
1133 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001134}
1135
Mathias Agopian13127d82013-03-05 17:47:11 -08001136void Layer::commitTransaction() {
1137 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001138}
1139
Mathias Agopian13127d82013-03-05 17:47:11 -08001140uint32_t Layer::getTransactionFlags(uint32_t flags) {
1141 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1142}
1143
1144uint32_t Layer::setTransactionFlags(uint32_t flags) {
1145 return android_atomic_or(flags, &mTransactionFlags);
1146}
1147
1148bool Layer::setPosition(float x, float y) {
1149 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1150 return false;
1151 mCurrentState.sequence++;
1152 mCurrentState.transform.set(x, y);
Dan Stoza7dde5992015-05-22 09:51:44 -07001153 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001154 setTransactionFlags(eTransactionNeeded);
1155 return true;
1156}
1157bool Layer::setLayer(uint32_t z) {
1158 if (mCurrentState.z == z)
1159 return false;
1160 mCurrentState.sequence++;
1161 mCurrentState.z = z;
Dan Stoza7dde5992015-05-22 09:51:44 -07001162 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001163 setTransactionFlags(eTransactionNeeded);
1164 return true;
1165}
1166bool Layer::setSize(uint32_t w, uint32_t h) {
1167 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1168 return false;
1169 mCurrentState.requested.w = w;
1170 mCurrentState.requested.h = h;
Dan Stoza7dde5992015-05-22 09:51:44 -07001171 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001172 setTransactionFlags(eTransactionNeeded);
1173 return true;
1174}
1175bool Layer::setAlpha(uint8_t alpha) {
1176 if (mCurrentState.alpha == alpha)
1177 return false;
1178 mCurrentState.sequence++;
1179 mCurrentState.alpha = alpha;
Dan Stoza7dde5992015-05-22 09:51:44 -07001180 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001181 setTransactionFlags(eTransactionNeeded);
1182 return true;
1183}
1184bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1185 mCurrentState.sequence++;
1186 mCurrentState.transform.set(
1187 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
Dan Stoza7dde5992015-05-22 09:51:44 -07001188 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001189 setTransactionFlags(eTransactionNeeded);
1190 return true;
1191}
1192bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001193 mCurrentState.requestedTransparentRegion = transparent;
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::setFlags(uint8_t flags, uint8_t mask) {
1199 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1200 if (mCurrentState.flags == newFlags)
1201 return false;
1202 mCurrentState.sequence++;
1203 mCurrentState.flags = newFlags;
Dan Stoza7dde5992015-05-22 09:51:44 -07001204 mCurrentState.mask = mask;
1205 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001206 setTransactionFlags(eTransactionNeeded);
1207 return true;
1208}
1209bool Layer::setCrop(const Rect& crop) {
1210 if (mCurrentState.requested.crop == crop)
1211 return false;
1212 mCurrentState.sequence++;
1213 mCurrentState.requested.crop = crop;
Dan Stoza7dde5992015-05-22 09:51:44 -07001214 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001215 setTransactionFlags(eTransactionNeeded);
1216 return true;
1217}
1218
1219bool Layer::setLayerStack(uint32_t layerStack) {
1220 if (mCurrentState.layerStack == layerStack)
1221 return false;
1222 mCurrentState.sequence++;
1223 mCurrentState.layerStack = layerStack;
Dan Stoza7dde5992015-05-22 09:51:44 -07001224 mCurrentState.modified = true;
Mathias Agopian13127d82013-03-05 17:47:11 -08001225 setTransactionFlags(eTransactionNeeded);
1226 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001227}
1228
Dan Stoza7dde5992015-05-22 09:51:44 -07001229void Layer::deferTransactionUntil(const sp<IBinder>& handle,
1230 uint64_t frameNumber) {
1231 mCurrentState.handle = handle;
1232 mCurrentState.frameNumber = frameNumber;
1233 // We don't set eTransactionNeeded, because just receiving a deferral
1234 // request without any other state updates shouldn't actually induce a delay
1235 mCurrentState.modified = true;
1236 pushPendingState();
1237 mCurrentState.modified = false;
1238}
1239
Dan Stozaee44edd2015-03-23 15:50:23 -07001240void Layer::useSurfaceDamage() {
1241 if (mFlinger->mForceFullDamage) {
1242 surfaceDamageRegion = Region::INVALID_REGION;
1243 } else {
1244 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1245 }
1246}
1247
1248void Layer::useEmptyDamage() {
1249 surfaceDamageRegion.clear();
1250}
1251
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001252// ----------------------------------------------------------------------------
1253// pageflip handling...
1254// ----------------------------------------------------------------------------
1255
Dan Stoza6b9454d2014-11-07 16:00:59 -08001256bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Dan Stozad87defa2015-07-29 16:15:50 -07001257 if (mSidebandStreamChanged) {
1258 return true;
1259 }
1260
Dan Stoza6b9454d2014-11-07 16:00:59 -08001261 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001262 if (mQueueItems.empty()) {
1263 return false;
1264 }
1265 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001266 nsecs_t expectedPresent =
1267 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001268
1269 // Ignore timestamps more than a second in the future
1270 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1271 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1272 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1273 expectedPresent);
1274
1275 bool isDue = timestamp < expectedPresent;
1276 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001277}
1278
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001279bool Layer::onPreComposition() {
1280 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001281 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001282}
1283
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001284void Layer::onPostComposition() {
1285 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001286 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001287 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1288
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001289 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001290 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001291 mFrameTracker.setFrameReadyFence(frameReadyFence);
1292 } else {
1293 // There was no fence for this frame, so assume that it was ready
1294 // to be presented at the desired present time.
1295 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1296 }
1297
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001298 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001299 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001300 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001301 mFrameTracker.setActualPresentFence(presentFence);
1302 } else {
1303 // The HWC doesn't support present fences, so use the refresh
1304 // timestamp instead.
1305 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1306 mFrameTracker.setActualPresentTime(presentTime);
1307 }
1308
1309 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001310 mFrameLatencyNeeded = false;
1311 }
1312}
1313
Mathias Agopianda27af92012-09-13 18:17:13 -07001314bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001315 const Layer::State& s(mDrawingState);
1316 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001317 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001318}
1319
Mathias Agopian4fec8732012-06-29 14:12:52 -07001320Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001321{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001322 ATRACE_CALL();
1323
Jesse Hall399184a2014-03-03 15:42:54 -08001324 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1325 // mSidebandStreamChanged was true
1326 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001327 if (mSidebandStream != NULL) {
1328 setTransactionFlags(eTransactionNeeded);
1329 mFlinger->setTransactionFlags(eTraversalNeeded);
1330 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001331 recomputeVisibleRegions = true;
1332
1333 const State& s(getDrawingState());
1334 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001335 }
1336
Mathias Agopian4fec8732012-06-29 14:12:52 -07001337 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001338 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001339
1340 // if we've already called updateTexImage() without going through
1341 // a composition step, we have to skip this layer at this point
1342 // because we cannot call updateTeximage() without a corresponding
1343 // compositionComplete() call.
1344 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001345 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001346 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001347 }
1348
Jamie Gennis351a5132011-09-14 18:23:37 -07001349 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001350 const State& s(getDrawingState());
1351 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001352 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001353
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001354 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001355 Layer::State& front;
1356 Layer::State& current;
1357 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001358 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001359 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001360 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001361 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001362 recomputeVisibleRegions(recomputeVisibleRegions),
1363 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001364 }
1365
1366 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001367 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001368 if (buf == NULL) {
1369 return false;
1370 }
1371
1372 uint32_t bufWidth = buf->getWidth();
1373 uint32_t bufHeight = buf->getHeight();
1374
1375 // check that we received a buffer of the right size
1376 // (Take the buffer's orientation into account)
1377 if (item.mTransform & Transform::ROT_90) {
1378 swap(bufWidth, bufHeight);
1379 }
1380
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001381 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1382 if (front.active != front.requested) {
1383
1384 if (isFixedSize ||
1385 (bufWidth == front.requested.w &&
1386 bufHeight == front.requested.h))
1387 {
1388 // Here we pretend the transaction happened by updating the
1389 // current and drawing states. Drawing state is only accessed
1390 // in this thread, no need to have it locked
1391 front.active = front.requested;
1392
1393 // We also need to update the current state so that
1394 // we don't end-up overwriting the drawing state with
1395 // this stale current state during the next transaction
1396 //
1397 // NOTE: We don't need to hold the transaction lock here
1398 // because State::active is only accessed from this thread.
1399 current.active = front.active;
1400
1401 // recompute visible region
1402 recomputeVisibleRegions = true;
1403 }
1404
1405 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001406 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001407 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1408 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001409 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001410 front.active.w, front.active.h,
1411 front.active.crop.left,
1412 front.active.crop.top,
1413 front.active.crop.right,
1414 front.active.crop.bottom,
1415 front.active.crop.getWidth(),
1416 front.active.crop.getHeight(),
1417 front.requested.w, front.requested.h,
1418 front.requested.crop.left,
1419 front.requested.crop.top,
1420 front.requested.crop.right,
1421 front.requested.crop.bottom,
1422 front.requested.crop.getWidth(),
1423 front.requested.crop.getHeight());
1424 }
1425
Ruben Brunk1681d952014-06-27 15:51:55 -07001426 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001427 if (front.active.w != bufWidth ||
1428 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001429 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001430 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1431 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001432 return true;
1433 }
1434 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001435
1436 // if the transparent region has changed (this test is
1437 // conservative, but that's fine, worst case we're doing
1438 // a bit of extra work), we latch the new one and we
1439 // trigger a visible-region recompute.
1440 if (!front.activeTransparentRegion.isTriviallyEqual(
1441 front.requestedTransparentRegion)) {
1442 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001443
1444 // We also need to update the current state so that
1445 // we don't end-up overwriting the drawing state with
1446 // this stale current state during the next transaction
1447 //
1448 // NOTE: We don't need to hold the transaction lock here
1449 // because State::active is only accessed from this thread.
1450 current.activeTransparentRegion = front.activeTransparentRegion;
1451
1452 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001453 recomputeVisibleRegions = true;
1454 }
1455
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001456 return false;
1457 }
1458 };
1459
Ruben Brunk1681d952014-06-27 15:51:55 -07001460 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1461 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001462
Dan Stozaa4650a52015-05-12 12:56:16 -07001463 uint64_t maxFrameNumber = 0;
Dan Stoza7dde5992015-05-22 09:51:44 -07001464 uint64_t headFrameNumber = 0;
Dan Stozaa4650a52015-05-12 12:56:16 -07001465 {
1466 Mutex::Autolock lock(mQueueItemLock);
1467 maxFrameNumber = mLastFrameNumberReceived;
Dan Stoza7dde5992015-05-22 09:51:44 -07001468 if (!mQueueItems.empty()) {
1469 headFrameNumber = mQueueItems[0].mFrameNumber;
1470 }
1471 }
1472
1473 bool availableFramesEmpty = true;
1474 {
1475 Mutex::Autolock lock(mAvailableFrameMutex);
1476 availableFramesEmpty = mAvailableFrames.empty();
1477 }
1478 if (!availableFramesEmpty) {
1479 Mutex::Autolock lock(mAvailableFrameMutex);
1480 bool matchingFramesFound = false;
1481 bool allTransactionsApplied = true;
1482 for (auto& frame : mAvailableFrames) {
1483 if (headFrameNumber != frame->getFrameNumber()) {
1484 break;
1485 }
1486 matchingFramesFound = true;
1487 allTransactionsApplied &= frame->transactionIsApplied();
1488 }
1489 if (matchingFramesFound && !allTransactionsApplied) {
1490 mFlinger->signalLayerUpdate();
1491 return outDirtyRegion;
1492 }
Dan Stozaa4650a52015-05-12 12:56:16 -07001493 }
1494
Andy McFadden41d67d72014-04-25 16:58:34 -07001495 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Dan Stozaa4650a52015-05-12 12:56:16 -07001496 mFlinger->mPrimaryDispSync, maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001497 if (updateResult == BufferQueue::PRESENT_LATER) {
1498 // Producer doesn't want buffer to be displayed yet. Signal a
1499 // layer update so we check again at the next opportunity.
1500 mFlinger->signalLayerUpdate();
1501 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001502 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1503 // If the buffer has been rejected, remove it from the shadow queue
1504 // and return early
1505 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001506 mQueueItems.removeAt(0);
Dan Stozaecc50402015-04-28 14:42:06 -07001507 android_atomic_dec(&mQueuedFrames);
1508 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001509 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1510 // This can occur if something goes wrong when trying to create the
1511 // EGLImage for this buffer. If this happens, the buffer has already
1512 // been released, so we need to clean up the queue and bug out
1513 // early.
1514 {
1515 Mutex::Autolock lock(mQueueItemLock);
1516 mQueueItems.clear();
1517 android_atomic_and(0, &mQueuedFrames);
1518 }
1519
1520 // Once we have hit this state, the shadow queue may no longer
1521 // correctly reflect the incoming BufferQueue's contents, so even if
1522 // updateTexImage starts working, the only safe course of action is
1523 // to continue to ignore updates.
1524 mUpdateTexImageFailed = true;
1525
1526 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001527 }
1528
Dan Stoza6b9454d2014-11-07 16:00:59 -08001529 { // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001530 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1531
Dan Stoza6b9454d2014-11-07 16:00:59 -08001532 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001533
1534 // Remove any stale buffers that have been dropped during
1535 // updateTexImage
1536 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1537 mQueueItems.removeAt(0);
1538 android_atomic_dec(&mQueuedFrames);
1539 }
1540
Dan Stoza6b9454d2014-11-07 16:00:59 -08001541 mQueueItems.removeAt(0);
1542 }
1543
Dan Stozaecc50402015-04-28 14:42:06 -07001544
Andy McFadden1585c4d2013-06-28 13:52:40 -07001545 // Decrement the queued-frames count. Signal another event if we
1546 // have more frames pending.
1547 if (android_atomic_dec(&mQueuedFrames) > 1) {
1548 mFlinger->signalLayerUpdate();
1549 }
1550
Dan Stoza7dde5992015-05-22 09:51:44 -07001551 if (!availableFramesEmpty) {
1552 Mutex::Autolock lock(mAvailableFrameMutex);
1553 auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1554 while (!mAvailableFrames.empty() &&
1555 frameNumber == mAvailableFrames.front()->getFrameNumber()) {
1556 mAvailableFrames.pop_front();
1557 }
1558 }
1559
Andy McFadden1585c4d2013-06-28 13:52:40 -07001560 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001561 // something happened!
1562 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001563 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001564 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001565
Jamie Gennis351a5132011-09-14 18:23:37 -07001566 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001567 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001568 if (mActiveBuffer == NULL) {
1569 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001570 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001571 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001572
Mathias Agopian4824d402012-06-04 18:16:30 -07001573 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001574 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001575 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001576 // the first time we receive a buffer, we need to trigger a
1577 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001578 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001579 }
1580
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001581 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1582 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1583 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001584 if ((crop != mCurrentCrop) ||
1585 (transform != mCurrentTransform) ||
1586 (scalingMode != mCurrentScalingMode))
1587 {
1588 mCurrentCrop = crop;
1589 mCurrentTransform = transform;
1590 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001591 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001592 }
1593
1594 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001595 uint32_t bufWidth = mActiveBuffer->getWidth();
1596 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001597 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1598 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001599 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001600 }
1601 }
1602
1603 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001604 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001605 recomputeVisibleRegions = true;
1606 }
1607
Mathias Agopian4fec8732012-06-29 14:12:52 -07001608 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001609 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001610
1611 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001612 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001613 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001614 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001615}
1616
Mathias Agopiana67932f2011-04-20 14:20:59 -07001617uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001618{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001619 // TODO: should we do something special if mSecure is set?
1620 if (mProtectedByApp) {
1621 // need a hardware-protected path to external video sink
1622 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001623 }
Riley Andrews03414a12014-07-01 14:22:59 -07001624 if (mPotentialCursor) {
1625 usage |= GraphicBuffer::USAGE_CURSOR;
1626 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001627 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001628 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001629}
1630
Mathias Agopian84300952012-11-21 16:02:13 -08001631void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001632 uint32_t orientation = 0;
1633 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001634 // The transform hint is used to improve performance, but we can
1635 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001636 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001637 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001638 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001639 if (orientation & Transform::ROT_INVALID) {
1640 orientation = 0;
1641 }
1642 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001643 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001644}
1645
Mathias Agopian13127d82013-03-05 17:47:11 -08001646// ----------------------------------------------------------------------------
1647// debugging
1648// ----------------------------------------------------------------------------
1649
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001650void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001651{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001652 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001653
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001654 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001655 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001656 "+ %s %p (%s)\n",
1657 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001658 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001659
Mathias Agopian2ca79392013-04-02 18:30:32 -07001660 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001661 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001662 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001663 sp<Client> client(mClientRef.promote());
1664
Mathias Agopian74d211a2013-04-22 16:55:35 +02001665 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001666 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1667 "isOpaque=%1d, invalidate=%1d, "
1668 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1669 " client=%p\n",
1670 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1671 s.active.crop.left, s.active.crop.top,
1672 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001673 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001674 s.alpha, s.flags,
1675 s.transform[0][0], s.transform[0][1],
1676 s.transform[1][0], s.transform[1][1],
1677 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001678
1679 sp<const GraphicBuffer> buf0(mActiveBuffer);
1680 uint32_t w0=0, h0=0, s0=0, f0=0;
1681 if (buf0 != 0) {
1682 w0 = buf0->getWidth();
1683 h0 = buf0->getHeight();
1684 s0 = buf0->getStride();
1685 f0 = buf0->format;
1686 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001687 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001688 " "
1689 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1690 " queued-frames=%d, mRefreshPending=%d\n",
1691 mFormat, w0, h0, s0,f0,
1692 mQueuedFrames, mRefreshPending);
1693
Mathias Agopian13127d82013-03-05 17:47:11 -08001694 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001695 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001696 }
1697}
1698
Svetoslavd85084b2014-03-20 10:28:31 -07001699void Layer::dumpFrameStats(String8& result) const {
1700 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001701}
1702
Svetoslavd85084b2014-03-20 10:28:31 -07001703void Layer::clearFrameStats() {
1704 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001705}
1706
Jamie Gennis6547ff42013-07-16 20:12:42 -07001707void Layer::logFrameStats() {
1708 mFrameTracker.logAndResetStats(mName);
1709}
1710
Svetoslavd85084b2014-03-20 10:28:31 -07001711void Layer::getFrameStats(FrameStats* outStats) const {
1712 mFrameTracker.getStats(outStats);
1713}
1714
Mathias Agopian13127d82013-03-05 17:47:11 -08001715// ---------------------------------------------------------------------------
1716
1717Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1718 const sp<Layer>& layer)
1719 : mFlinger(flinger), mLayer(layer) {
1720}
1721
1722Layer::LayerCleaner::~LayerCleaner() {
1723 // destroy client resources
1724 mFlinger->onLayerDestroyed(mLayer);
1725}
1726
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001727// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001728}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001729
1730#if defined(__gl_h_)
1731#error "don't include gl/gl.h in this file"
1732#endif
1733
1734#if defined(__gl2_h_)
1735#error "don't include gl2/gl2.h in this file"
1736#endif