blob: 33af4a5029f5c12a4a693f444db1de14f1506f6d [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),
Mathias Agopiana67932f2011-04-20 14:20:59 -070069 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080070 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070072 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070073 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080074 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080075 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080076 mFiltering(false),
77 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070078 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopian13127d82013-03-05 17:47:11 -080079 mProtectedByApp(false),
80 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070081 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070082 mPotentialCursor(false),
83 mQueueItemLock(),
84 mQueueItemCondition(),
85 mQueueItems(),
Dan Stoza65476f32015-05-14 09:27:25 -070086 mLastFrameNumberReceived(0),
87 mUpdateTexImageFailed(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080088{
Mathias Agopiana67932f2011-04-20 14:20:59 -070089 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070090 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070091 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070092
93 uint32_t layerFlags = 0;
94 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080095 layerFlags |= layer_state_t::eLayerHidden;
96 if (flags & ISurfaceComposerClient::eOpaque)
97 layerFlags |= layer_state_t::eLayerOpaque;
Dan Stoza23116082015-06-18 14:58:39 -070098 if (flags & ISurfaceComposerClient::eSecure)
99 layerFlags |= layer_state_t::eLayerSecure;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700100
101 if (flags & ISurfaceComposerClient::eNonPremultiplied)
102 mPremultipliedAlpha = false;
103
104 mName = name;
105
106 mCurrentState.active.w = w;
107 mCurrentState.active.h = h;
108 mCurrentState.active.crop.makeInvalid();
109 mCurrentState.z = 0;
110 mCurrentState.alpha = 0xFF;
111 mCurrentState.layerStack = 0;
112 mCurrentState.flags = layerFlags;
113 mCurrentState.sequence = 0;
114 mCurrentState.transform.set(0, 0);
115 mCurrentState.requested = mCurrentState.active;
116
117 // drawing state & current state are identical
118 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700119
120 nsecs_t displayPeriod =
121 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
122 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800123}
124
Mathias Agopian3f844832013-08-07 21:24:32 -0700125void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800126 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700127 sp<IGraphicBufferProducer> producer;
128 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700129 BufferQueue::createBufferQueue(&producer, &consumer);
130 mProducer = new MonitoredProducer(producer, mFlinger);
131 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800132 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800133 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700134 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800135
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700136#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
137#warning "disabling triple buffering"
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700138#else
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700139 mProducer->setMaxDequeuedBufferCount(2);
Mathias Agopian303d5382012-02-05 01:49:16 -0800140#endif
Andy McFadden69052052012-09-14 16:10:11 -0700141
Mathias Agopian84300952012-11-21 16:02:13 -0800142 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
143 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700144}
145
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700146Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800147 sp<Client> c(mClientRef.promote());
148 if (c != 0) {
149 c->detachLayer(this);
150 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700151 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700152 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700153}
154
Mathias Agopian13127d82013-03-05 17:47:11 -0800155// ---------------------------------------------------------------------------
156// callbacks
157// ---------------------------------------------------------------------------
158
Dan Stozac7014012014-02-14 15:03:43 -0800159void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800160 HWComposer::HWCLayerInterface* layer) {
161 if (layer) {
162 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700163 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800164 }
165}
166
Dan Stoza6b9454d2014-11-07 16:00:59 -0800167void Layer::onFrameAvailable(const BufferItem& item) {
168 // Add this buffer from our internal queue tracker
169 { // Autolock scope
170 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700171
172 // Reset the frame number tracker when we receive the first buffer after
173 // a frame number reset
174 if (item.mFrameNumber == 1) {
175 mLastFrameNumberReceived = 0;
176 }
177
178 // Ensure that callbacks are handled in order
179 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
180 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
181 ms2ns(500));
182 if (result != NO_ERROR) {
183 ALOGE("[%s] Timed out waiting on callback", mName.string());
184 }
185 }
186
Dan Stoza6b9454d2014-11-07 16:00:59 -0800187 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700188 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700189
190 // Wake up any pending callbacks
191 mLastFrameNumberReceived = item.mFrameNumber;
192 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800193 }
194
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800195 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700196}
197
Dan Stoza6b9454d2014-11-07 16:00:59 -0800198void Layer::onFrameReplaced(const BufferItem& item) {
199 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700200
201 // Ensure that callbacks are handled in order
202 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
203 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
204 ms2ns(500));
205 if (result != NO_ERROR) {
206 ALOGE("[%s] Timed out waiting on callback", mName.string());
207 }
208 }
209
Dan Stoza6b9454d2014-11-07 16:00:59 -0800210 if (mQueueItems.empty()) {
211 ALOGE("Can't replace a frame on an empty queue");
212 return;
213 }
214 mQueueItems.editItemAt(0) = item;
Dan Stozaa4650a52015-05-12 12:56:16 -0700215
216 // Wake up any pending callbacks
217 mLastFrameNumberReceived = item.mFrameNumber;
218 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800219}
220
Jesse Hall399184a2014-03-03 15:42:54 -0800221void Layer::onSidebandStreamChanged() {
222 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
223 // mSidebandStreamChanged was false
224 mFlinger->signalLayerUpdate();
225 }
226}
227
Mathias Agopian67106042013-03-14 19:18:13 -0700228// called with SurfaceFlinger::mStateLock from the drawing thread after
229// the layer has been remove from the current state list (and just before
230// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800231void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800232 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700233}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700234
Mathias Agopian13127d82013-03-05 17:47:11 -0800235// ---------------------------------------------------------------------------
236// set-up
237// ---------------------------------------------------------------------------
238
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700239const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800240 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800241}
242
Mathias Agopianf9d93272009-06-19 17:00:27 -0700243status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800244 PixelFormat format, uint32_t flags)
245{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700246 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700247 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700248
249 // never allow a surface larger than what our underlying GL implementation
250 // can handle.
251 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800252 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700253 return BAD_VALUE;
254 }
255
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700256 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700257
Riley Andrews03414a12014-07-01 14:22:59 -0700258 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700259 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700260 mCurrentOpacity = getOpacityForFormat(format);
261
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800262 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
263 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
264 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700265
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800266 return NO_ERROR;
267}
268
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700269sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800270 Mutex::Autolock _l(mLock);
271
272 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700273 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800274
275 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700276
277 /*
278 * The layer handle is just a BBinder object passed to the client
279 * (remote process) -- we don't keep any reference on our side such that
280 * the dtor is called when the remote side let go of its reference.
281 *
282 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
283 * this layer when the handle is destroyed.
284 */
285
286 class Handle : public BBinder, public LayerCleaner {
287 wp<const Layer> mOwner;
288 public:
289 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
290 : LayerCleaner(flinger, layer), mOwner(layer) {
291 }
292 };
293
294 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800295}
296
Dan Stozab9b08832014-03-13 11:55:57 -0700297sp<IGraphicBufferProducer> Layer::getProducer() const {
298 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700299}
300
Mathias Agopian13127d82013-03-05 17:47:11 -0800301// ---------------------------------------------------------------------------
302// h/w composer set-up
303// ---------------------------------------------------------------------------
304
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800305Rect Layer::getContentCrop() const {
306 // this is the crop rectangle that applies to the buffer
307 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700308 Rect crop;
309 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800310 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700311 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800312 } else if (mActiveBuffer != NULL) {
313 // otherwise we use the whole buffer
314 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700315 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800316 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700317 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700318 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700319 return crop;
320}
321
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700322static Rect reduce(const Rect& win, const Region& exclude) {
323 if (CC_LIKELY(exclude.isEmpty())) {
324 return win;
325 }
326 if (exclude.isRect()) {
327 return win.reduce(exclude.getBounds());
328 }
329 return Region(win).subtract(exclude).getBounds();
330}
331
Mathias Agopian13127d82013-03-05 17:47:11 -0800332Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700333 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700334 return computeBounds(s.activeTransparentRegion);
335}
336
337Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
338 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800339 Rect win(s.active.w, s.active.h);
340 if (!s.active.crop.isEmpty()) {
341 win.intersect(s.active.crop, &win);
342 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700343 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700344 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800345}
346
Mathias Agopian6b442672013-07-09 21:24:52 -0700347FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800348 // the content crop is the area of the content that gets scaled to the
349 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700350 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800351
352 // the active.crop is the area of the window that gets cropped, but not
353 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700354 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800355
356 // apply the projection's clipping to the window crop in
357 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700358 // if there are no window scaling involved, this operation will map to full
359 // pixels in the buffer.
360 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
361 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700362
363 Rect activeCrop(s.active.w, s.active.h);
364 if (!s.active.crop.isEmpty()) {
365 activeCrop = s.active.crop;
366 }
367
368 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800369 activeCrop.intersect(hw->getViewport(), &activeCrop);
370 activeCrop = s.transform.inverse().transform(activeCrop);
371
Michael Lentine28ea2172014-11-19 18:32:37 -0800372 // This needs to be here as transform.transform(Rect) computes the
373 // transformed rect and then takes the bounding box of the result before
374 // returning. This means
375 // transform.inverse().transform(transform.transform(Rect)) != Rect
376 // in which case we need to make sure the final rect is clipped to the
377 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800378 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
379
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700380 // subtract the transparent region and snap to the bounds
381 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
382
Mathias Agopian13127d82013-03-05 17:47:11 -0800383 if (!activeCrop.isEmpty()) {
384 // Transform the window crop to match the buffer coordinate system,
385 // which means using the inverse of the current transform set on the
386 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700387 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700388 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
389 /*
390 * the code below applies the display's inverse transform to the buffer
391 */
392 uint32_t invTransformOrient = hw->getOrientationTransform();
393 // calculate the inverse transform
394 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
395 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
396 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700397 // If the transform has been rotated the axis of flip has been swapped
398 // so we need to swap which flip operations we are performing
399 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
400 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
401 if (is_h_flipped != is_v_flipped) {
402 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
403 NATIVE_WINDOW_TRANSFORM_FLIP_H;
404 }
Michael Lentinef7551402014-08-18 16:35:43 -0700405 }
406 // and apply to the current transform
407 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
408 }
409
Mathias Agopian13127d82013-03-05 17:47:11 -0800410 int winWidth = s.active.w;
411 int winHeight = s.active.h;
412 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700413 // If the activeCrop has been rotate the ends are rotated but not
414 // the space itself so when transforming ends back we can't rely on
415 // a modification of the axes of rotation. To account for this we
416 // need to reorient the inverse rotation in terms of the current
417 // axes of rotation.
418 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
419 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
420 if (is_h_flipped == is_v_flipped) {
421 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
422 NATIVE_WINDOW_TRANSFORM_FLIP_H;
423 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800424 winWidth = s.active.h;
425 winHeight = s.active.w;
426 }
427 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700428 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800429
Mathias Agopian6b442672013-07-09 21:24:52 -0700430 // below, crop is intersected with winCrop expressed in crop's coordinate space
431 float xScale = crop.getWidth() / float(winWidth);
432 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800433
Michael Lentinef7551402014-08-18 16:35:43 -0700434 float insetL = winCrop.left * xScale;
435 float insetT = winCrop.top * yScale;
436 float insetR = (winWidth - winCrop.right ) * xScale;
437 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800438
439 crop.left += insetL;
440 crop.top += insetT;
441 crop.right -= insetR;
442 crop.bottom -= insetB;
443 }
444 return crop;
445}
446
Mathias Agopian4fec8732012-06-29 14:12:52 -0700447void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700448 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700449 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700450{
Mathias Agopian13127d82013-03-05 17:47:11 -0800451 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700452
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700453 // enable this layer
454 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700455
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700456 if (isSecure() && !hw->isSecure()) {
457 layer.setSkip(true);
458 }
459
Mathias Agopian13127d82013-03-05 17:47:11 -0800460 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700461 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800462 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800463 layer.setBlending(mPremultipliedAlpha ?
464 HWC_BLENDING_PREMULT :
465 HWC_BLENDING_COVERAGE);
466 }
467
468 // apply the layer's transform, followed by the display's global transform
469 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700470 Region activeTransparentRegion(s.activeTransparentRegion);
471 if (!s.active.crop.isEmpty()) {
472 Rect activeCrop(s.active.crop);
473 activeCrop = s.transform.transform(activeCrop);
474 activeCrop.intersect(hw->getViewport(), &activeCrop);
475 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800476 // This needs to be here as transform.transform(Rect) computes the
477 // transformed rect and then takes the bounding box of the result before
478 // returning. This means
479 // transform.inverse().transform(transform.transform(Rect)) != Rect
480 // in which case we need to make sure the final rect is clipped to the
481 // display bounds.
482 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700483 // mark regions outside the crop as transparent
484 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
485 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
486 s.active.w, s.active.h));
487 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
488 activeCrop.left, activeCrop.bottom));
489 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
490 s.active.w, activeCrop.bottom));
491 }
492 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800493 frame.intersect(hw->getViewport(), &frame);
494 const Transform& tr(hw->getTransform());
495 layer.setFrame(tr.transform(frame));
496 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800497 layer.setPlaneAlpha(s.alpha);
498
Mathias Agopian29a367b2011-07-12 14:51:45 -0700499 /*
500 * Transformations are applied in this order:
501 * 1) buffer orientation/flip/mirror
502 * 2) state transformation (window manager)
503 * 3) layer orientation (screen orientation)
504 * (NOTE: the matrices are multiplied in reverse order)
505 */
506
507 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700508 Transform transform(tr * s.transform * bufferOrientation);
509
510 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
511 /*
512 * the code below applies the display's inverse transform to the buffer
513 */
514 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700515 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700516 // calculate the inverse transform
517 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
518 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
519 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700520 // If the transform has been rotated the axis of flip has been swapped
521 // so we need to swap which flip operations we are performing
522 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
523 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
524 if (is_h_flipped != is_v_flipped) {
525 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
526 NATIVE_WINDOW_TRANSFORM_FLIP_H;
527 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700528 }
529 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700530 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700531 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700532
533 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800534 const uint32_t orientation = transform.getOrientation();
535 if (orientation & Transform::ROT_INVALID) {
536 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700537 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700538 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800539 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700540 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700541}
542
Mathias Agopian42977342012-08-05 00:40:46 -0700543void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700544 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800545 // we have to set the visible region on every frame because
546 // we currently free it during onLayerDisplayed(), which is called
547 // after HWComposer::commit() -- every frame.
548 // Apply this display's projection's viewport to the visible region
549 // before giving it to the HWC HAL.
550 const Transform& tr = hw->getTransform();
551 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
552 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700553 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700554
Jesse Hall399184a2014-03-03 15:42:54 -0800555 if (mSidebandStream.get()) {
556 layer.setSidebandStream(mSidebandStream);
557 } else {
558 // NOTE: buffer can be NULL if the client never drew into this
559 // layer yet, or if we ran out of memory
560 layer.setBuffer(mActiveBuffer);
561 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700562}
Jesse Halldc5b4852012-06-29 15:21:18 -0700563
Dan Stozac7014012014-02-14 15:03:43 -0800564void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700565 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700566 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700567
568 // TODO: there is a possible optimization here: we only need to set the
569 // acquire fence the first time a new buffer is acquired on EACH display.
570
Riley Andrews03414a12014-07-01 14:22:59 -0700571 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800572 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800573 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700574 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700575 if (fenceFd == -1) {
576 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
577 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700578 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700579 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700580 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700581}
582
Riley Andrews03414a12014-07-01 14:22:59 -0700583Rect Layer::getPosition(
584 const sp<const DisplayDevice>& hw)
585{
586 // this gives us only the "orientation" component of the transform
587 const State& s(getCurrentState());
588
589 // apply the layer's transform, followed by the display's global transform
590 // here we're guaranteed that the layer's transform preserves rects
591 Rect win(s.active.w, s.active.h);
592 if (!s.active.crop.isEmpty()) {
593 win.intersect(s.active.crop, &win);
594 }
595 // subtract the transparent region and snap to the bounds
596 Rect bounds = reduce(win, s.activeTransparentRegion);
597 Rect frame(s.transform.transform(bounds));
598 frame.intersect(hw->getViewport(), &frame);
599 const Transform& tr(hw->getTransform());
600 return Rect(tr.transform(frame));
601}
602
Mathias Agopian13127d82013-03-05 17:47:11 -0800603// ---------------------------------------------------------------------------
604// drawing...
605// ---------------------------------------------------------------------------
606
607void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800608 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800609}
610
Dan Stozac7014012014-02-14 15:03:43 -0800611void Layer::draw(const sp<const DisplayDevice>& hw,
612 bool useIdentityTransform) const {
613 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800614}
615
Dan Stozac7014012014-02-14 15:03:43 -0800616void Layer::draw(const sp<const DisplayDevice>& hw) const {
617 onDraw(hw, Region(hw->bounds()), false);
618}
619
620void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
621 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800622{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800623 ATRACE_CALL();
624
Mathias Agopiana67932f2011-04-20 14:20:59 -0700625 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800626 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700627 // in fact never been drawn into. This happens frequently with
628 // SurfaceView because the WindowManager can't know when the client
629 // has drawn the first time.
630
631 // If there is nothing under us, we paint the screen in black, otherwise
632 // we just skip this update.
633
634 // figure out if there is something below us
635 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700636 const SurfaceFlinger::LayerVector& drawingLayers(
637 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700638 const size_t count = drawingLayers.size();
639 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800640 const sp<Layer>& layer(drawingLayers[i]);
641 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700642 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700643 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700644 }
645 // if not everything below us is covered, we plug the holes!
646 Region holes(clip.subtract(under));
647 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700648 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700649 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800650 return;
651 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700652
Andy McFadden97eba892012-12-11 15:21:45 -0800653 // Bind the current buffer to the GL texture, and wait for it to be
654 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800655 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
656 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800657 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700658 // Go ahead and draw the buffer anyway; no matter what we do the screen
659 // is probably going to have something visibly wrong.
660 }
661
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700662 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
663
Mathias Agopian875d8e12013-06-07 15:35:48 -0700664 RenderEngine& engine(mFlinger->getRenderEngine());
665
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700666 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700667 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700668 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700669
670 // Query the texture matrix given our current filtering mode.
671 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800672 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
673 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700674
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700675 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
676
677 /*
678 * the code below applies the display's inverse transform to the texture transform
679 */
680
681 // create a 4x4 transform matrix from the display transform flags
682 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
683 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
684 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
685
686 mat4 tr;
687 uint32_t transform = hw->getOrientationTransform();
688 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
689 tr = tr * rot90;
690 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
691 tr = tr * flipH;
692 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
693 tr = tr * flipV;
694
695 // calculate the inverse
696 tr = inverse(tr);
697
698 // and finally apply it to the original texture matrix
699 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
700 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
701 }
702
Jamie Genniscbb1a952012-05-08 17:05:52 -0700703 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700704 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
705 mTexture.setFiltering(useFiltering);
706 mTexture.setMatrix(textureMatrix);
707
708 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700709 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700710 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700711 }
Dan Stozac7014012014-02-14 15:03:43 -0800712 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700713 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800714}
715
Mathias Agopian13127d82013-03-05 17:47:11 -0800716
Dan Stozac7014012014-02-14 15:03:43 -0800717void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
718 const Region& /* clip */, float red, float green, float blue,
719 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800720{
Mathias Agopian19733a32013-08-28 18:13:56 -0700721 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800722 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700723 engine.setupFillWithColor(red, green, blue, alpha);
724 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800725}
726
727void Layer::clearWithOpenGL(
728 const sp<const DisplayDevice>& hw, const Region& clip) const {
729 clearWithOpenGL(hw, clip, 0,0,0,0);
730}
731
Dan Stozac7014012014-02-14 15:03:43 -0800732void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
733 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700734 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800735
Dan Stozac7014012014-02-14 15:03:43 -0800736 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800737
Mathias Agopian13127d82013-03-05 17:47:11 -0800738 /*
739 * NOTE: the way we compute the texture coordinates here produces
740 * different results than when we take the HWC path -- in the later case
741 * the "source crop" is rounded to texel boundaries.
742 * This can produce significantly different results when the texture
743 * is scaled by a large amount.
744 *
745 * The GL code below is more logical (imho), and the difference with
746 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700747 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800748 * GL composition when a buffer scaling is applied (maybe with some
749 * minimal value)? Or, we could make GL behave like HWC -- but this feel
750 * like more of a hack.
751 */
752 const Rect win(computeBounds());
753
Mathias Agopian3f844832013-08-07 21:24:32 -0700754 float left = float(win.left) / float(s.active.w);
755 float top = float(win.top) / float(s.active.h);
756 float right = float(win.right) / float(s.active.w);
757 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800758
Mathias Agopian875d8e12013-06-07 15:35:48 -0700759 // TODO: we probably want to generate the texture coords with the mesh
760 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700761 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
762 texCoords[0] = vec2(left, 1.0f - top);
763 texCoords[1] = vec2(left, 1.0f - bottom);
764 texCoords[2] = vec2(right, 1.0f - bottom);
765 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800766
Mathias Agopian875d8e12013-06-07 15:35:48 -0700767 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800768 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700769 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700770 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800771}
772
Ruben Brunk1681d952014-06-27 15:51:55 -0700773uint32_t Layer::getProducerStickyTransform() const {
774 int producerStickyTransform = 0;
775 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
776 if (ret != OK) {
777 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
778 strerror(-ret), ret);
779 return 0;
780 }
781 return static_cast<uint32_t>(producerStickyTransform);
782}
783
Mathias Agopian13127d82013-03-05 17:47:11 -0800784void Layer::setFiltering(bool filtering) {
785 mFiltering = filtering;
786}
787
788bool Layer::getFiltering() const {
789 return mFiltering;
790}
791
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800792// As documented in libhardware header, formats in the range
793// 0x100 - 0x1FF are specific to the HAL implementation, and
794// are known to have no alpha channel
795// TODO: move definition for device-specific range into
796// hardware.h, instead of using hard-coded values here.
797#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
798
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700799bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700800 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
801 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800802 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700803 switch (format) {
804 case HAL_PIXEL_FORMAT_RGBA_8888:
805 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700806 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700807 }
808 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700809 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800810}
811
Mathias Agopian13127d82013-03-05 17:47:11 -0800812// ----------------------------------------------------------------------------
813// local state
814// ----------------------------------------------------------------------------
815
Dan Stozac7014012014-02-14 15:03:43 -0800816void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
817 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800818{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700819 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800820 const Transform tr(useIdentityTransform ?
821 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800822 const uint32_t hw_h = hw->getHeight();
823 Rect win(s.active.w, s.active.h);
824 if (!s.active.crop.isEmpty()) {
825 win.intersect(s.active.crop, &win);
826 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700827 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700828 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700829
Mathias Agopianff2ed702013-09-01 21:36:12 -0700830 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
831 position[0] = tr.transform(win.left, win.top);
832 position[1] = tr.transform(win.left, win.bottom);
833 position[2] = tr.transform(win.right, win.bottom);
834 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700835 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700836 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800837 }
838}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800839
Andy McFadden4125a4f2014-01-29 17:17:11 -0800840bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700841{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700842 // if we don't have a buffer yet, we're translucent regardless of the
843 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700844 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700845 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700846 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700847
848 // if the layer has the opaque flag, then we're always opaque,
849 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800850 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700851}
852
Dan Stoza23116082015-06-18 14:58:39 -0700853bool Layer::isSecure() const
854{
855 const Layer::State& s(mDrawingState);
856 return (s.flags & layer_state_t::eLayerSecure);
857}
858
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800859bool Layer::isProtected() const
860{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700861 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800862 return (activeBuffer != 0) &&
863 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
864}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700865
Mathias Agopian13127d82013-03-05 17:47:11 -0800866bool Layer::isFixedSize() const {
867 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
868}
869
870bool Layer::isCropped() const {
871 return !mCurrentCrop.isEmpty();
872}
873
874bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
875 return mNeedsFiltering || hw->needsFiltering();
876}
877
878void Layer::setVisibleRegion(const Region& visibleRegion) {
879 // always called from main thread
880 this->visibleRegion = visibleRegion;
881}
882
883void Layer::setCoveredRegion(const Region& coveredRegion) {
884 // always called from main thread
885 this->coveredRegion = coveredRegion;
886}
887
888void Layer::setVisibleNonTransparentRegion(const Region&
889 setVisibleNonTransparentRegion) {
890 // always called from main thread
891 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
892}
893
894// ----------------------------------------------------------------------------
895// transaction
896// ----------------------------------------------------------------------------
897
898uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800899 ATRACE_CALL();
900
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700901 const Layer::State& s(getDrawingState());
902 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800903
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700904 const bool sizeChanged = (c.requested.w != s.requested.w) ||
905 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700906
907 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700908 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000909 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700910 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700911 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
912 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
913 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
914 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700915 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
916 c.active.w, c.active.h,
917 c.active.crop.left,
918 c.active.crop.top,
919 c.active.crop.right,
920 c.active.crop.bottom,
921 c.active.crop.getWidth(),
922 c.active.crop.getHeight(),
923 c.requested.w, c.requested.h,
924 c.requested.crop.left,
925 c.requested.crop.top,
926 c.requested.crop.right,
927 c.requested.crop.bottom,
928 c.requested.crop.getWidth(),
929 c.requested.crop.getHeight(),
930 s.active.w, s.active.h,
931 s.active.crop.left,
932 s.active.crop.top,
933 s.active.crop.right,
934 s.active.crop.bottom,
935 s.active.crop.getWidth(),
936 s.active.crop.getHeight(),
937 s.requested.w, s.requested.h,
938 s.requested.crop.left,
939 s.requested.crop.top,
940 s.requested.crop.right,
941 s.requested.crop.bottom,
942 s.requested.crop.getWidth(),
943 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800944
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700945 // record the new size, form this point on, when the client request
946 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800947 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700948 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800949 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700950
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700951 if (!isFixedSize()) {
952
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700953 const bool resizePending = (c.requested.w != c.active.w) ||
954 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700955
Dan Stoza9e9b0442015-04-22 14:59:08 -0700956 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800957 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700958 // if we have a pending resize, unless we are in fixed-size mode.
959 // the drawing state will be updated only once we receive a buffer
960 // with the correct size.
961 //
962 // in particular, we want to make sure the clip (which is part
963 // of the geometry state) is latched together with the size but is
964 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -0700965 //
966 // If a sideband stream is attached, however, we want to skip this
967 // optimization so that transactions aren't missed when a buffer
968 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700969
970 flags |= eDontUpdateGeometryState;
971 }
972 }
973
Mathias Agopian13127d82013-03-05 17:47:11 -0800974 // always set active to requested, unless we're asked not to
975 // this is used by Layer, which special cases resizes.
976 if (flags & eDontUpdateGeometryState) {
977 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700978 Layer::State& editCurrentState(getCurrentState());
979 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800980 }
981
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700982 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800983 // invalidate and recompute the visible regions if needed
984 flags |= Layer::eVisibleRegion;
985 }
986
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700987 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800988 // invalidate and recompute the visible regions if needed
989 flags |= eVisibleRegion;
990 this->contentDirty = true;
991
992 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700993 const uint8_t type = c.transform.getType();
994 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800995 (type >= Transform::SCALE));
996 }
997
998 // Commit the transaction
999 commitTransaction();
1000 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001001}
1002
Mathias Agopian13127d82013-03-05 17:47:11 -08001003void Layer::commitTransaction() {
1004 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001005}
1006
Mathias Agopian13127d82013-03-05 17:47:11 -08001007uint32_t Layer::getTransactionFlags(uint32_t flags) {
1008 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1009}
1010
1011uint32_t Layer::setTransactionFlags(uint32_t flags) {
1012 return android_atomic_or(flags, &mTransactionFlags);
1013}
1014
1015bool Layer::setPosition(float x, float y) {
1016 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1017 return false;
1018 mCurrentState.sequence++;
1019 mCurrentState.transform.set(x, y);
1020 setTransactionFlags(eTransactionNeeded);
1021 return true;
1022}
1023bool Layer::setLayer(uint32_t z) {
1024 if (mCurrentState.z == z)
1025 return false;
1026 mCurrentState.sequence++;
1027 mCurrentState.z = z;
1028 setTransactionFlags(eTransactionNeeded);
1029 return true;
1030}
1031bool Layer::setSize(uint32_t w, uint32_t h) {
1032 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1033 return false;
1034 mCurrentState.requested.w = w;
1035 mCurrentState.requested.h = h;
1036 setTransactionFlags(eTransactionNeeded);
1037 return true;
1038}
1039bool Layer::setAlpha(uint8_t alpha) {
1040 if (mCurrentState.alpha == alpha)
1041 return false;
1042 mCurrentState.sequence++;
1043 mCurrentState.alpha = alpha;
1044 setTransactionFlags(eTransactionNeeded);
1045 return true;
1046}
1047bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1048 mCurrentState.sequence++;
1049 mCurrentState.transform.set(
1050 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1051 setTransactionFlags(eTransactionNeeded);
1052 return true;
1053}
1054bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001055 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001056 setTransactionFlags(eTransactionNeeded);
1057 return true;
1058}
1059bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1060 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1061 if (mCurrentState.flags == newFlags)
1062 return false;
1063 mCurrentState.sequence++;
1064 mCurrentState.flags = newFlags;
1065 setTransactionFlags(eTransactionNeeded);
1066 return true;
1067}
1068bool Layer::setCrop(const Rect& crop) {
1069 if (mCurrentState.requested.crop == crop)
1070 return false;
1071 mCurrentState.sequence++;
1072 mCurrentState.requested.crop = crop;
1073 setTransactionFlags(eTransactionNeeded);
1074 return true;
1075}
1076
1077bool Layer::setLayerStack(uint32_t layerStack) {
1078 if (mCurrentState.layerStack == layerStack)
1079 return false;
1080 mCurrentState.sequence++;
1081 mCurrentState.layerStack = layerStack;
1082 setTransactionFlags(eTransactionNeeded);
1083 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001084}
1085
Dan Stozaee44edd2015-03-23 15:50:23 -07001086void Layer::useSurfaceDamage() {
1087 if (mFlinger->mForceFullDamage) {
1088 surfaceDamageRegion = Region::INVALID_REGION;
1089 } else {
1090 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1091 }
1092}
1093
1094void Layer::useEmptyDamage() {
1095 surfaceDamageRegion.clear();
1096}
1097
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001098// ----------------------------------------------------------------------------
1099// pageflip handling...
1100// ----------------------------------------------------------------------------
1101
Dan Stoza6b9454d2014-11-07 16:00:59 -08001102bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Dan Stozad87defa2015-07-29 16:15:50 -07001103 if (mSidebandStreamChanged) {
1104 return true;
1105 }
1106
Dan Stoza6b9454d2014-11-07 16:00:59 -08001107 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001108 if (mQueueItems.empty()) {
1109 return false;
1110 }
1111 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001112 nsecs_t expectedPresent =
1113 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001114
1115 // Ignore timestamps more than a second in the future
1116 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1117 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1118 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1119 expectedPresent);
1120
1121 bool isDue = timestamp < expectedPresent;
1122 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001123}
1124
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001125bool Layer::onPreComposition() {
1126 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001127 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001128}
1129
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001130void Layer::onPostComposition() {
1131 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001132 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001133 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1134
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001135 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001136 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001137 mFrameTracker.setFrameReadyFence(frameReadyFence);
1138 } else {
1139 // There was no fence for this frame, so assume that it was ready
1140 // to be presented at the desired present time.
1141 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1142 }
1143
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001144 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001145 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001146 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001147 mFrameTracker.setActualPresentFence(presentFence);
1148 } else {
1149 // The HWC doesn't support present fences, so use the refresh
1150 // timestamp instead.
1151 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1152 mFrameTracker.setActualPresentTime(presentTime);
1153 }
1154
1155 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001156 mFrameLatencyNeeded = false;
1157 }
1158}
1159
Mathias Agopianda27af92012-09-13 18:17:13 -07001160bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001161 const Layer::State& s(mDrawingState);
1162 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001163 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001164}
1165
Mathias Agopian4fec8732012-06-29 14:12:52 -07001166Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001167{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001168 ATRACE_CALL();
1169
Jesse Hall399184a2014-03-03 15:42:54 -08001170 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1171 // mSidebandStreamChanged was true
1172 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001173 if (mSidebandStream != NULL) {
1174 setTransactionFlags(eTransactionNeeded);
1175 mFlinger->setTransactionFlags(eTraversalNeeded);
1176 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001177 recomputeVisibleRegions = true;
1178
1179 const State& s(getDrawingState());
1180 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001181 }
1182
Mathias Agopian4fec8732012-06-29 14:12:52 -07001183 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001184 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001185
1186 // if we've already called updateTexImage() without going through
1187 // a composition step, we have to skip this layer at this point
1188 // because we cannot call updateTeximage() without a corresponding
1189 // compositionComplete() call.
1190 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001191 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001192 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001193 }
1194
Jamie Gennis351a5132011-09-14 18:23:37 -07001195 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001196 const State& s(getDrawingState());
1197 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001198 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001199
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001200 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001201 Layer::State& front;
1202 Layer::State& current;
1203 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001204 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001205 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001206 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001207 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001208 recomputeVisibleRegions(recomputeVisibleRegions),
1209 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001210 }
1211
1212 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001213 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001214 if (buf == NULL) {
1215 return false;
1216 }
1217
1218 uint32_t bufWidth = buf->getWidth();
1219 uint32_t bufHeight = buf->getHeight();
1220
1221 // check that we received a buffer of the right size
1222 // (Take the buffer's orientation into account)
1223 if (item.mTransform & Transform::ROT_90) {
1224 swap(bufWidth, bufHeight);
1225 }
1226
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001227 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1228 if (front.active != front.requested) {
1229
1230 if (isFixedSize ||
1231 (bufWidth == front.requested.w &&
1232 bufHeight == front.requested.h))
1233 {
1234 // Here we pretend the transaction happened by updating the
1235 // current and drawing states. Drawing state is only accessed
1236 // in this thread, no need to have it locked
1237 front.active = front.requested;
1238
1239 // We also need to update the current state so that
1240 // we don't end-up overwriting the drawing state with
1241 // this stale current state during the next transaction
1242 //
1243 // NOTE: We don't need to hold the transaction lock here
1244 // because State::active is only accessed from this thread.
1245 current.active = front.active;
1246
1247 // recompute visible region
1248 recomputeVisibleRegions = true;
1249 }
1250
1251 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001252 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001253 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1254 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001255 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001256 front.active.w, front.active.h,
1257 front.active.crop.left,
1258 front.active.crop.top,
1259 front.active.crop.right,
1260 front.active.crop.bottom,
1261 front.active.crop.getWidth(),
1262 front.active.crop.getHeight(),
1263 front.requested.w, front.requested.h,
1264 front.requested.crop.left,
1265 front.requested.crop.top,
1266 front.requested.crop.right,
1267 front.requested.crop.bottom,
1268 front.requested.crop.getWidth(),
1269 front.requested.crop.getHeight());
1270 }
1271
Ruben Brunk1681d952014-06-27 15:51:55 -07001272 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001273 if (front.active.w != bufWidth ||
1274 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001275 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001276 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1277 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001278 return true;
1279 }
1280 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001281
1282 // if the transparent region has changed (this test is
1283 // conservative, but that's fine, worst case we're doing
1284 // a bit of extra work), we latch the new one and we
1285 // trigger a visible-region recompute.
1286 if (!front.activeTransparentRegion.isTriviallyEqual(
1287 front.requestedTransparentRegion)) {
1288 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001289
1290 // We also need to update the current state so that
1291 // we don't end-up overwriting the drawing state with
1292 // this stale current state during the next transaction
1293 //
1294 // NOTE: We don't need to hold the transaction lock here
1295 // because State::active is only accessed from this thread.
1296 current.activeTransparentRegion = front.activeTransparentRegion;
1297
1298 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001299 recomputeVisibleRegions = true;
1300 }
1301
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001302 return false;
1303 }
1304 };
1305
Ruben Brunk1681d952014-06-27 15:51:55 -07001306 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1307 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001308
Dan Stozaa4650a52015-05-12 12:56:16 -07001309 uint64_t maxFrameNumber = 0;
1310 {
1311 Mutex::Autolock lock(mQueueItemLock);
1312 maxFrameNumber = mLastFrameNumberReceived;
1313 }
1314
Andy McFadden41d67d72014-04-25 16:58:34 -07001315 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Dan Stozaa4650a52015-05-12 12:56:16 -07001316 mFlinger->mPrimaryDispSync, maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001317 if (updateResult == BufferQueue::PRESENT_LATER) {
1318 // Producer doesn't want buffer to be displayed yet. Signal a
1319 // layer update so we check again at the next opportunity.
1320 mFlinger->signalLayerUpdate();
1321 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001322 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1323 // If the buffer has been rejected, remove it from the shadow queue
1324 // and return early
1325 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001326 mQueueItems.removeAt(0);
Dan Stozaecc50402015-04-28 14:42:06 -07001327 android_atomic_dec(&mQueuedFrames);
1328 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001329 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1330 // This can occur if something goes wrong when trying to create the
1331 // EGLImage for this buffer. If this happens, the buffer has already
1332 // been released, so we need to clean up the queue and bug out
1333 // early.
1334 {
1335 Mutex::Autolock lock(mQueueItemLock);
1336 mQueueItems.clear();
1337 android_atomic_and(0, &mQueuedFrames);
1338 }
1339
1340 // Once we have hit this state, the shadow queue may no longer
1341 // correctly reflect the incoming BufferQueue's contents, so even if
1342 // updateTexImage starts working, the only safe course of action is
1343 // to continue to ignore updates.
1344 mUpdateTexImageFailed = true;
1345
1346 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001347 }
1348
Dan Stoza6b9454d2014-11-07 16:00:59 -08001349 { // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001350 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1351
Dan Stoza6b9454d2014-11-07 16:00:59 -08001352 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001353
1354 // Remove any stale buffers that have been dropped during
1355 // updateTexImage
1356 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1357 mQueueItems.removeAt(0);
1358 android_atomic_dec(&mQueuedFrames);
1359 }
1360
Dan Stoza6b9454d2014-11-07 16:00:59 -08001361 mQueueItems.removeAt(0);
1362 }
1363
Dan Stozaecc50402015-04-28 14:42:06 -07001364
Andy McFadden1585c4d2013-06-28 13:52:40 -07001365 // Decrement the queued-frames count. Signal another event if we
1366 // have more frames pending.
1367 if (android_atomic_dec(&mQueuedFrames) > 1) {
1368 mFlinger->signalLayerUpdate();
1369 }
1370
1371 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001372 // something happened!
1373 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001374 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001375 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001376
Jamie Gennis351a5132011-09-14 18:23:37 -07001377 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001378 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001379 if (mActiveBuffer == NULL) {
1380 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001381 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001382 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001383
Mathias Agopian4824d402012-06-04 18:16:30 -07001384 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001385 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001386 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001387 // the first time we receive a buffer, we need to trigger a
1388 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001389 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001390 }
1391
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001392 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1393 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1394 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001395 if ((crop != mCurrentCrop) ||
1396 (transform != mCurrentTransform) ||
1397 (scalingMode != mCurrentScalingMode))
1398 {
1399 mCurrentCrop = crop;
1400 mCurrentTransform = transform;
1401 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001402 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001403 }
1404
1405 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001406 uint32_t bufWidth = mActiveBuffer->getWidth();
1407 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001408 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1409 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001410 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001411 }
1412 }
1413
1414 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001415 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001416 recomputeVisibleRegions = true;
1417 }
1418
Mathias Agopian4fec8732012-06-29 14:12:52 -07001419 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001420 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001421
1422 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001423 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001424 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001425 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001426}
1427
Mathias Agopiana67932f2011-04-20 14:20:59 -07001428uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001429{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001430 // TODO: should we do something special if mSecure is set?
1431 if (mProtectedByApp) {
1432 // need a hardware-protected path to external video sink
1433 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001434 }
Riley Andrews03414a12014-07-01 14:22:59 -07001435 if (mPotentialCursor) {
1436 usage |= GraphicBuffer::USAGE_CURSOR;
1437 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001438 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001439 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001440}
1441
Mathias Agopian84300952012-11-21 16:02:13 -08001442void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001443 uint32_t orientation = 0;
1444 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001445 // The transform hint is used to improve performance, but we can
1446 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001447 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001448 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001449 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001450 if (orientation & Transform::ROT_INVALID) {
1451 orientation = 0;
1452 }
1453 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001454 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001455}
1456
Mathias Agopian13127d82013-03-05 17:47:11 -08001457// ----------------------------------------------------------------------------
1458// debugging
1459// ----------------------------------------------------------------------------
1460
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001461void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001462{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001463 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001464
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001465 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001466 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001467 "+ %s %p (%s)\n",
1468 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001469 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001470
Mathias Agopian2ca79392013-04-02 18:30:32 -07001471 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001472 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001473 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001474 sp<Client> client(mClientRef.promote());
1475
Mathias Agopian74d211a2013-04-22 16:55:35 +02001476 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001477 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1478 "isOpaque=%1d, invalidate=%1d, "
1479 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1480 " client=%p\n",
1481 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1482 s.active.crop.left, s.active.crop.top,
1483 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001484 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001485 s.alpha, s.flags,
1486 s.transform[0][0], s.transform[0][1],
1487 s.transform[1][0], s.transform[1][1],
1488 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001489
1490 sp<const GraphicBuffer> buf0(mActiveBuffer);
1491 uint32_t w0=0, h0=0, s0=0, f0=0;
1492 if (buf0 != 0) {
1493 w0 = buf0->getWidth();
1494 h0 = buf0->getHeight();
1495 s0 = buf0->getStride();
1496 f0 = buf0->format;
1497 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001498 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001499 " "
1500 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1501 " queued-frames=%d, mRefreshPending=%d\n",
1502 mFormat, w0, h0, s0,f0,
1503 mQueuedFrames, mRefreshPending);
1504
Mathias Agopian13127d82013-03-05 17:47:11 -08001505 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001506 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001507 }
1508}
1509
Svetoslavd85084b2014-03-20 10:28:31 -07001510void Layer::dumpFrameStats(String8& result) const {
1511 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001512}
1513
Svetoslavd85084b2014-03-20 10:28:31 -07001514void Layer::clearFrameStats() {
1515 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001516}
1517
Jamie Gennis6547ff42013-07-16 20:12:42 -07001518void Layer::logFrameStats() {
1519 mFrameTracker.logAndResetStats(mName);
1520}
1521
Svetoslavd85084b2014-03-20 10:28:31 -07001522void Layer::getFrameStats(FrameStats* outStats) const {
1523 mFrameTracker.getStats(outStats);
1524}
1525
Mathias Agopian13127d82013-03-05 17:47:11 -08001526// ---------------------------------------------------------------------------
1527
1528Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1529 const sp<Layer>& layer)
1530 : mFlinger(flinger), mLayer(layer) {
1531}
1532
1533Layer::LayerCleaner::~LayerCleaner() {
1534 // destroy client resources
1535 mFlinger->onLayerDestroyed(mLayer);
1536}
1537
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001538// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001539}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001540
1541#if defined(__gl_h_)
1542#error "don't include gl/gl.h in this file"
1543#endif
1544
1545#if defined(__gl2_h_)
1546#error "don't include gl2/gl2.h in this file"
1547#endif