blob: 2b733e905fe115e623cb8641be58af0c57261c0a [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 Agopianb7e930d2010-06-01 15:12:58 -070079 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080080 mProtectedByApp(false),
81 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070082 mClientRef(client),
Dan Stozaa4650a52015-05-12 12:56:16 -070083 mPotentialCursor(false),
84 mQueueItemLock(),
85 mQueueItemCondition(),
86 mQueueItems(),
87 mLastFrameNumberReceived(0)
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;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070098
99 if (flags & ISurfaceComposerClient::eNonPremultiplied)
100 mPremultipliedAlpha = false;
101
102 mName = name;
103
104 mCurrentState.active.w = w;
105 mCurrentState.active.h = h;
106 mCurrentState.active.crop.makeInvalid();
107 mCurrentState.z = 0;
108 mCurrentState.alpha = 0xFF;
109 mCurrentState.layerStack = 0;
110 mCurrentState.flags = layerFlags;
111 mCurrentState.sequence = 0;
112 mCurrentState.transform.set(0, 0);
113 mCurrentState.requested = mCurrentState.active;
114
115 // drawing state & current state are identical
116 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700117
118 nsecs_t displayPeriod =
119 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
120 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800121}
122
Mathias Agopian3f844832013-08-07 21:24:32 -0700123void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800124 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700125 sp<IGraphicBufferProducer> producer;
126 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700127 BufferQueue::createBufferQueue(&producer, &consumer);
128 mProducer = new MonitoredProducer(producer, mFlinger);
129 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800130 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800131 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700132 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800133
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700134#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
135#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800136 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700137#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800138 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800139#endif
Andy McFadden69052052012-09-14 16:10:11 -0700140
Mathias Agopian84300952012-11-21 16:02:13 -0800141 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
142 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700143}
144
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700145Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800146 sp<Client> c(mClientRef.promote());
147 if (c != 0) {
148 c->detachLayer(this);
149 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700150 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700151 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700152}
153
Mathias Agopian13127d82013-03-05 17:47:11 -0800154// ---------------------------------------------------------------------------
155// callbacks
156// ---------------------------------------------------------------------------
157
Dan Stozac7014012014-02-14 15:03:43 -0800158void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800159 HWComposer::HWCLayerInterface* layer) {
160 if (layer) {
161 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700162 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800163 }
164}
165
Dan Stoza6b9454d2014-11-07 16:00:59 -0800166void Layer::onFrameAvailable(const BufferItem& item) {
167 // Add this buffer from our internal queue tracker
168 { // Autolock scope
169 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700170
171 // Reset the frame number tracker when we receive the first buffer after
172 // a frame number reset
173 if (item.mFrameNumber == 1) {
174 mLastFrameNumberReceived = 0;
175 }
176
177 // Ensure that callbacks are handled in order
178 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
179 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
180 ms2ns(500));
181 if (result != NO_ERROR) {
182 ALOGE("[%s] Timed out waiting on callback", mName.string());
183 }
184 }
185
Dan Stoza6b9454d2014-11-07 16:00:59 -0800186 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700187 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700188
189 // Wake up any pending callbacks
190 mLastFrameNumberReceived = item.mFrameNumber;
191 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800192 }
193
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800194 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700195}
196
Dan Stoza6b9454d2014-11-07 16:00:59 -0800197void Layer::onFrameReplaced(const BufferItem& item) {
198 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700199
200 // Ensure that callbacks are handled in order
201 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
202 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
203 ms2ns(500));
204 if (result != NO_ERROR) {
205 ALOGE("[%s] Timed out waiting on callback", mName.string());
206 }
207 }
208
Dan Stoza6b9454d2014-11-07 16:00:59 -0800209 if (mQueueItems.empty()) {
210 ALOGE("Can't replace a frame on an empty queue");
211 return;
212 }
213 mQueueItems.editItemAt(0) = item;
Dan Stozaa4650a52015-05-12 12:56:16 -0700214
215 // Wake up any pending callbacks
216 mLastFrameNumberReceived = item.mFrameNumber;
217 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800218}
219
Jesse Hall399184a2014-03-03 15:42:54 -0800220void Layer::onSidebandStreamChanged() {
221 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
222 // mSidebandStreamChanged was false
223 mFlinger->signalLayerUpdate();
224 }
225}
226
Mathias Agopian67106042013-03-14 19:18:13 -0700227// called with SurfaceFlinger::mStateLock from the drawing thread after
228// the layer has been remove from the current state list (and just before
229// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800230void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800231 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700232}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700233
Mathias Agopian13127d82013-03-05 17:47:11 -0800234// ---------------------------------------------------------------------------
235// set-up
236// ---------------------------------------------------------------------------
237
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700238const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800239 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800240}
241
Mathias Agopianf9d93272009-06-19 17:00:27 -0700242status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800243 PixelFormat format, uint32_t flags)
244{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700245 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700246 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700247
248 // never allow a surface larger than what our underlying GL implementation
249 // can handle.
250 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800251 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700252 return BAD_VALUE;
253 }
254
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700255 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700256
Riley Andrews03414a12014-07-01 14:22:59 -0700257 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700258 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
259 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);
553
Dan Stozaee44edd2015-03-23 15:50:23 -0700554 // Pass full-surface damage down untouched
555 if (surfaceDamageRegion.isRect() &&
556 surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
557 layer.setSurfaceDamage(surfaceDamageRegion);
558 } else {
559 Region surfaceDamage =
560 tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
561 layer.setSurfaceDamage(surfaceDamage);
562 }
563
Jesse Hall399184a2014-03-03 15:42:54 -0800564 if (mSidebandStream.get()) {
565 layer.setSidebandStream(mSidebandStream);
566 } else {
567 // NOTE: buffer can be NULL if the client never drew into this
568 // layer yet, or if we ran out of memory
569 layer.setBuffer(mActiveBuffer);
570 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700571}
Jesse Halldc5b4852012-06-29 15:21:18 -0700572
Dan Stozac7014012014-02-14 15:03:43 -0800573void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700574 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700575 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700576
577 // TODO: there is a possible optimization here: we only need to set the
578 // acquire fence the first time a new buffer is acquired on EACH display.
579
Riley Andrews03414a12014-07-01 14:22:59 -0700580 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800581 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800582 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700583 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700584 if (fenceFd == -1) {
585 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
586 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700587 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700588 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700589 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700590}
591
Riley Andrews03414a12014-07-01 14:22:59 -0700592Rect Layer::getPosition(
593 const sp<const DisplayDevice>& hw)
594{
595 // this gives us only the "orientation" component of the transform
596 const State& s(getCurrentState());
597
598 // apply the layer's transform, followed by the display's global transform
599 // here we're guaranteed that the layer's transform preserves rects
600 Rect win(s.active.w, s.active.h);
601 if (!s.active.crop.isEmpty()) {
602 win.intersect(s.active.crop, &win);
603 }
604 // subtract the transparent region and snap to the bounds
605 Rect bounds = reduce(win, s.activeTransparentRegion);
606 Rect frame(s.transform.transform(bounds));
607 frame.intersect(hw->getViewport(), &frame);
608 const Transform& tr(hw->getTransform());
609 return Rect(tr.transform(frame));
610}
611
Mathias Agopian13127d82013-03-05 17:47:11 -0800612// ---------------------------------------------------------------------------
613// drawing...
614// ---------------------------------------------------------------------------
615
616void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800617 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800618}
619
Dan Stozac7014012014-02-14 15:03:43 -0800620void Layer::draw(const sp<const DisplayDevice>& hw,
621 bool useIdentityTransform) const {
622 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800623}
624
Dan Stozac7014012014-02-14 15:03:43 -0800625void Layer::draw(const sp<const DisplayDevice>& hw) const {
626 onDraw(hw, Region(hw->bounds()), false);
627}
628
629void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
630 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800631{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800632 ATRACE_CALL();
633
Mathias Agopiana67932f2011-04-20 14:20:59 -0700634 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800635 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700636 // in fact never been drawn into. This happens frequently with
637 // SurfaceView because the WindowManager can't know when the client
638 // has drawn the first time.
639
640 // If there is nothing under us, we paint the screen in black, otherwise
641 // we just skip this update.
642
643 // figure out if there is something below us
644 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700645 const SurfaceFlinger::LayerVector& drawingLayers(
646 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700647 const size_t count = drawingLayers.size();
648 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800649 const sp<Layer>& layer(drawingLayers[i]);
650 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700651 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700652 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700653 }
654 // if not everything below us is covered, we plug the holes!
655 Region holes(clip.subtract(under));
656 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700657 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700658 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800659 return;
660 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700661
Andy McFadden97eba892012-12-11 15:21:45 -0800662 // Bind the current buffer to the GL texture, and wait for it to be
663 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800664 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
665 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800666 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700667 // Go ahead and draw the buffer anyway; no matter what we do the screen
668 // is probably going to have something visibly wrong.
669 }
670
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700671 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
672
Mathias Agopian875d8e12013-06-07 15:35:48 -0700673 RenderEngine& engine(mFlinger->getRenderEngine());
674
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700675 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700676 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700677 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700678
679 // Query the texture matrix given our current filtering mode.
680 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800681 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
682 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700683
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700684 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
685
686 /*
687 * the code below applies the display's inverse transform to the texture transform
688 */
689
690 // create a 4x4 transform matrix from the display transform flags
691 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
692 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
693 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
694
695 mat4 tr;
696 uint32_t transform = hw->getOrientationTransform();
697 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
698 tr = tr * rot90;
699 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
700 tr = tr * flipH;
701 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
702 tr = tr * flipV;
703
704 // calculate the inverse
705 tr = inverse(tr);
706
707 // and finally apply it to the original texture matrix
708 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
709 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
710 }
711
Jamie Genniscbb1a952012-05-08 17:05:52 -0700712 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700713 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
714 mTexture.setFiltering(useFiltering);
715 mTexture.setMatrix(textureMatrix);
716
717 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700718 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700719 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700720 }
Dan Stozac7014012014-02-14 15:03:43 -0800721 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700722 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800723}
724
Mathias Agopian13127d82013-03-05 17:47:11 -0800725
Dan Stozac7014012014-02-14 15:03:43 -0800726void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
727 const Region& /* clip */, float red, float green, float blue,
728 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800729{
Mathias Agopian19733a32013-08-28 18:13:56 -0700730 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800731 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700732 engine.setupFillWithColor(red, green, blue, alpha);
733 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800734}
735
736void Layer::clearWithOpenGL(
737 const sp<const DisplayDevice>& hw, const Region& clip) const {
738 clearWithOpenGL(hw, clip, 0,0,0,0);
739}
740
Dan Stozac7014012014-02-14 15:03:43 -0800741void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
742 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700743 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800744
Dan Stozac7014012014-02-14 15:03:43 -0800745 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800746
Mathias Agopian13127d82013-03-05 17:47:11 -0800747 /*
748 * NOTE: the way we compute the texture coordinates here produces
749 * different results than when we take the HWC path -- in the later case
750 * the "source crop" is rounded to texel boundaries.
751 * This can produce significantly different results when the texture
752 * is scaled by a large amount.
753 *
754 * The GL code below is more logical (imho), and the difference with
755 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700756 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800757 * GL composition when a buffer scaling is applied (maybe with some
758 * minimal value)? Or, we could make GL behave like HWC -- but this feel
759 * like more of a hack.
760 */
761 const Rect win(computeBounds());
762
Mathias Agopian3f844832013-08-07 21:24:32 -0700763 float left = float(win.left) / float(s.active.w);
764 float top = float(win.top) / float(s.active.h);
765 float right = float(win.right) / float(s.active.w);
766 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800767
Mathias Agopian875d8e12013-06-07 15:35:48 -0700768 // TODO: we probably want to generate the texture coords with the mesh
769 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700770 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
771 texCoords[0] = vec2(left, 1.0f - top);
772 texCoords[1] = vec2(left, 1.0f - bottom);
773 texCoords[2] = vec2(right, 1.0f - bottom);
774 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800775
Mathias Agopian875d8e12013-06-07 15:35:48 -0700776 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800777 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700778 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700779 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800780}
781
Ruben Brunk1681d952014-06-27 15:51:55 -0700782uint32_t Layer::getProducerStickyTransform() const {
783 int producerStickyTransform = 0;
784 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
785 if (ret != OK) {
786 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
787 strerror(-ret), ret);
788 return 0;
789 }
790 return static_cast<uint32_t>(producerStickyTransform);
791}
792
Mathias Agopian13127d82013-03-05 17:47:11 -0800793void Layer::setFiltering(bool filtering) {
794 mFiltering = filtering;
795}
796
797bool Layer::getFiltering() const {
798 return mFiltering;
799}
800
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800801// As documented in libhardware header, formats in the range
802// 0x100 - 0x1FF are specific to the HAL implementation, and
803// are known to have no alpha channel
804// TODO: move definition for device-specific range into
805// hardware.h, instead of using hard-coded values here.
806#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
807
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700808bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700809 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
810 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800811 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700812 switch (format) {
813 case HAL_PIXEL_FORMAT_RGBA_8888:
814 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700815 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700816 }
817 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700818 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800819}
820
Mathias Agopian13127d82013-03-05 17:47:11 -0800821// ----------------------------------------------------------------------------
822// local state
823// ----------------------------------------------------------------------------
824
Dan Stozac7014012014-02-14 15:03:43 -0800825void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
826 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800827{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700828 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800829 const Transform tr(useIdentityTransform ?
830 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800831 const uint32_t hw_h = hw->getHeight();
832 Rect win(s.active.w, s.active.h);
833 if (!s.active.crop.isEmpty()) {
834 win.intersect(s.active.crop, &win);
835 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700836 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700837 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700838
Mathias Agopianff2ed702013-09-01 21:36:12 -0700839 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
840 position[0] = tr.transform(win.left, win.top);
841 position[1] = tr.transform(win.left, win.bottom);
842 position[2] = tr.transform(win.right, win.bottom);
843 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700844 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700845 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800846 }
847}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800848
Andy McFadden4125a4f2014-01-29 17:17:11 -0800849bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700850{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700851 // if we don't have a buffer yet, we're translucent regardless of the
852 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700853 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700854 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700855 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700856
857 // if the layer has the opaque flag, then we're always opaque,
858 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800859 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700860}
861
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800862bool Layer::isProtected() const
863{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700864 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800865 return (activeBuffer != 0) &&
866 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
867}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700868
Mathias Agopian13127d82013-03-05 17:47:11 -0800869bool Layer::isFixedSize() const {
870 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
871}
872
873bool Layer::isCropped() const {
874 return !mCurrentCrop.isEmpty();
875}
876
877bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
878 return mNeedsFiltering || hw->needsFiltering();
879}
880
881void Layer::setVisibleRegion(const Region& visibleRegion) {
882 // always called from main thread
883 this->visibleRegion = visibleRegion;
884}
885
886void Layer::setCoveredRegion(const Region& coveredRegion) {
887 // always called from main thread
888 this->coveredRegion = coveredRegion;
889}
890
891void Layer::setVisibleNonTransparentRegion(const Region&
892 setVisibleNonTransparentRegion) {
893 // always called from main thread
894 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
895}
896
897// ----------------------------------------------------------------------------
898// transaction
899// ----------------------------------------------------------------------------
900
901uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800902 ATRACE_CALL();
903
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700904 const Layer::State& s(getDrawingState());
905 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800906
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700907 const bool sizeChanged = (c.requested.w != s.requested.w) ||
908 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700909
910 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700911 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000912 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700913 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700914 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
915 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
916 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
917 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700918 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
919 c.active.w, c.active.h,
920 c.active.crop.left,
921 c.active.crop.top,
922 c.active.crop.right,
923 c.active.crop.bottom,
924 c.active.crop.getWidth(),
925 c.active.crop.getHeight(),
926 c.requested.w, c.requested.h,
927 c.requested.crop.left,
928 c.requested.crop.top,
929 c.requested.crop.right,
930 c.requested.crop.bottom,
931 c.requested.crop.getWidth(),
932 c.requested.crop.getHeight(),
933 s.active.w, s.active.h,
934 s.active.crop.left,
935 s.active.crop.top,
936 s.active.crop.right,
937 s.active.crop.bottom,
938 s.active.crop.getWidth(),
939 s.active.crop.getHeight(),
940 s.requested.w, s.requested.h,
941 s.requested.crop.left,
942 s.requested.crop.top,
943 s.requested.crop.right,
944 s.requested.crop.bottom,
945 s.requested.crop.getWidth(),
946 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800947
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700948 // record the new size, form this point on, when the client request
949 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800950 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700951 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800952 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700953
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700954 if (!isFixedSize()) {
955
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700956 const bool resizePending = (c.requested.w != c.active.w) ||
957 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700958
Dan Stoza9e9b0442015-04-22 14:59:08 -0700959 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800960 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700961 // if we have a pending resize, unless we are in fixed-size mode.
962 // the drawing state will be updated only once we receive a buffer
963 // with the correct size.
964 //
965 // in particular, we want to make sure the clip (which is part
966 // of the geometry state) is latched together with the size but is
967 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -0700968 //
969 // If a sideband stream is attached, however, we want to skip this
970 // optimization so that transactions aren't missed when a buffer
971 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700972
973 flags |= eDontUpdateGeometryState;
974 }
975 }
976
Mathias Agopian13127d82013-03-05 17:47:11 -0800977 // always set active to requested, unless we're asked not to
978 // this is used by Layer, which special cases resizes.
979 if (flags & eDontUpdateGeometryState) {
980 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700981 Layer::State& editCurrentState(getCurrentState());
982 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800983 }
984
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700985 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800986 // invalidate and recompute the visible regions if needed
987 flags |= Layer::eVisibleRegion;
988 }
989
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700990 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800991 // invalidate and recompute the visible regions if needed
992 flags |= eVisibleRegion;
993 this->contentDirty = true;
994
995 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700996 const uint8_t type = c.transform.getType();
997 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800998 (type >= Transform::SCALE));
999 }
1000
1001 // Commit the transaction
1002 commitTransaction();
1003 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001004}
1005
Mathias Agopian13127d82013-03-05 17:47:11 -08001006void Layer::commitTransaction() {
1007 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001008}
1009
Mathias Agopian13127d82013-03-05 17:47:11 -08001010uint32_t Layer::getTransactionFlags(uint32_t flags) {
1011 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1012}
1013
1014uint32_t Layer::setTransactionFlags(uint32_t flags) {
1015 return android_atomic_or(flags, &mTransactionFlags);
1016}
1017
1018bool Layer::setPosition(float x, float y) {
1019 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1020 return false;
1021 mCurrentState.sequence++;
1022 mCurrentState.transform.set(x, y);
1023 setTransactionFlags(eTransactionNeeded);
1024 return true;
1025}
1026bool Layer::setLayer(uint32_t z) {
1027 if (mCurrentState.z == z)
1028 return false;
1029 mCurrentState.sequence++;
1030 mCurrentState.z = z;
1031 setTransactionFlags(eTransactionNeeded);
1032 return true;
1033}
1034bool Layer::setSize(uint32_t w, uint32_t h) {
1035 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1036 return false;
1037 mCurrentState.requested.w = w;
1038 mCurrentState.requested.h = h;
1039 setTransactionFlags(eTransactionNeeded);
1040 return true;
1041}
1042bool Layer::setAlpha(uint8_t alpha) {
1043 if (mCurrentState.alpha == alpha)
1044 return false;
1045 mCurrentState.sequence++;
1046 mCurrentState.alpha = alpha;
1047 setTransactionFlags(eTransactionNeeded);
1048 return true;
1049}
1050bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1051 mCurrentState.sequence++;
1052 mCurrentState.transform.set(
1053 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1054 setTransactionFlags(eTransactionNeeded);
1055 return true;
1056}
1057bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001058 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001059 setTransactionFlags(eTransactionNeeded);
1060 return true;
1061}
1062bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1063 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1064 if (mCurrentState.flags == newFlags)
1065 return false;
1066 mCurrentState.sequence++;
1067 mCurrentState.flags = newFlags;
1068 setTransactionFlags(eTransactionNeeded);
1069 return true;
1070}
1071bool Layer::setCrop(const Rect& crop) {
1072 if (mCurrentState.requested.crop == crop)
1073 return false;
1074 mCurrentState.sequence++;
1075 mCurrentState.requested.crop = crop;
1076 setTransactionFlags(eTransactionNeeded);
1077 return true;
1078}
1079
1080bool Layer::setLayerStack(uint32_t layerStack) {
1081 if (mCurrentState.layerStack == layerStack)
1082 return false;
1083 mCurrentState.sequence++;
1084 mCurrentState.layerStack = layerStack;
1085 setTransactionFlags(eTransactionNeeded);
1086 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001087}
1088
Dan Stozaee44edd2015-03-23 15:50:23 -07001089void Layer::useSurfaceDamage() {
1090 if (mFlinger->mForceFullDamage) {
1091 surfaceDamageRegion = Region::INVALID_REGION;
1092 } else {
1093 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1094 }
1095}
1096
1097void Layer::useEmptyDamage() {
1098 surfaceDamageRegion.clear();
1099}
1100
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001101// ----------------------------------------------------------------------------
1102// pageflip handling...
1103// ----------------------------------------------------------------------------
1104
Dan Stoza6b9454d2014-11-07 16:00:59 -08001105bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1106 Mutex::Autolock lock(mQueueItemLock);
1107 nsecs_t expectedPresent =
1108 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1109 return mQueueItems.empty() ?
1110 false : mQueueItems[0].mTimestamp < expectedPresent;
1111}
1112
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001113bool Layer::onPreComposition() {
1114 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001115 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001116}
1117
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001118void Layer::onPostComposition() {
1119 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001120 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001121 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1122
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001123 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001124 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001125 mFrameTracker.setFrameReadyFence(frameReadyFence);
1126 } else {
1127 // There was no fence for this frame, so assume that it was ready
1128 // to be presented at the desired present time.
1129 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1130 }
1131
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001132 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001133 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001134 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001135 mFrameTracker.setActualPresentFence(presentFence);
1136 } else {
1137 // The HWC doesn't support present fences, so use the refresh
1138 // timestamp instead.
1139 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1140 mFrameTracker.setActualPresentTime(presentTime);
1141 }
1142
1143 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001144 mFrameLatencyNeeded = false;
1145 }
1146}
1147
Mathias Agopianda27af92012-09-13 18:17:13 -07001148bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001149 const Layer::State& s(mDrawingState);
1150 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001151 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001152}
1153
Mathias Agopian4fec8732012-06-29 14:12:52 -07001154Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001155{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001156 ATRACE_CALL();
1157
Jesse Hall399184a2014-03-03 15:42:54 -08001158 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1159 // mSidebandStreamChanged was true
1160 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001161 if (mSidebandStream != NULL) {
1162 setTransactionFlags(eTransactionNeeded);
1163 mFlinger->setTransactionFlags(eTraversalNeeded);
1164 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001165 recomputeVisibleRegions = true;
1166
1167 const State& s(getDrawingState());
1168 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001169 }
1170
Mathias Agopian4fec8732012-06-29 14:12:52 -07001171 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001172 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001173
1174 // if we've already called updateTexImage() without going through
1175 // a composition step, we have to skip this layer at this point
1176 // because we cannot call updateTeximage() without a corresponding
1177 // compositionComplete() call.
1178 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001179 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001180 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001181 }
1182
Jamie Gennis351a5132011-09-14 18:23:37 -07001183 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001184 const State& s(getDrawingState());
1185 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001186 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001187
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001188 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001189 Layer::State& front;
1190 Layer::State& current;
1191 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001192 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001193 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001194 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001195 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001196 recomputeVisibleRegions(recomputeVisibleRegions),
1197 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001198 }
1199
1200 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001201 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001202 if (buf == NULL) {
1203 return false;
1204 }
1205
1206 uint32_t bufWidth = buf->getWidth();
1207 uint32_t bufHeight = buf->getHeight();
1208
1209 // check that we received a buffer of the right size
1210 // (Take the buffer's orientation into account)
1211 if (item.mTransform & Transform::ROT_90) {
1212 swap(bufWidth, bufHeight);
1213 }
1214
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001215 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1216 if (front.active != front.requested) {
1217
1218 if (isFixedSize ||
1219 (bufWidth == front.requested.w &&
1220 bufHeight == front.requested.h))
1221 {
1222 // Here we pretend the transaction happened by updating the
1223 // current and drawing states. Drawing state is only accessed
1224 // in this thread, no need to have it locked
1225 front.active = front.requested;
1226
1227 // We also need to update the current state so that
1228 // we don't end-up overwriting the drawing state with
1229 // this stale current state during the next transaction
1230 //
1231 // NOTE: We don't need to hold the transaction lock here
1232 // because State::active is only accessed from this thread.
1233 current.active = front.active;
1234
1235 // recompute visible region
1236 recomputeVisibleRegions = true;
1237 }
1238
1239 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001240 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001241 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1242 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001243 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001244 front.active.w, front.active.h,
1245 front.active.crop.left,
1246 front.active.crop.top,
1247 front.active.crop.right,
1248 front.active.crop.bottom,
1249 front.active.crop.getWidth(),
1250 front.active.crop.getHeight(),
1251 front.requested.w, front.requested.h,
1252 front.requested.crop.left,
1253 front.requested.crop.top,
1254 front.requested.crop.right,
1255 front.requested.crop.bottom,
1256 front.requested.crop.getWidth(),
1257 front.requested.crop.getHeight());
1258 }
1259
Ruben Brunk1681d952014-06-27 15:51:55 -07001260 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001261 if (front.active.w != bufWidth ||
1262 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001263 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001264 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1265 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001266 return true;
1267 }
1268 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001269
1270 // if the transparent region has changed (this test is
1271 // conservative, but that's fine, worst case we're doing
1272 // a bit of extra work), we latch the new one and we
1273 // trigger a visible-region recompute.
1274 if (!front.activeTransparentRegion.isTriviallyEqual(
1275 front.requestedTransparentRegion)) {
1276 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001277
1278 // We also need to update the current state so that
1279 // we don't end-up overwriting the drawing state with
1280 // this stale current state during the next transaction
1281 //
1282 // NOTE: We don't need to hold the transaction lock here
1283 // because State::active is only accessed from this thread.
1284 current.activeTransparentRegion = front.activeTransparentRegion;
1285
1286 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001287 recomputeVisibleRegions = true;
1288 }
1289
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001290 return false;
1291 }
1292 };
1293
Ruben Brunk1681d952014-06-27 15:51:55 -07001294 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1295 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001296
Dan Stozaa4650a52015-05-12 12:56:16 -07001297 uint64_t maxFrameNumber = 0;
1298 {
1299 Mutex::Autolock lock(mQueueItemLock);
1300 maxFrameNumber = mLastFrameNumberReceived;
1301 }
1302
Andy McFadden41d67d72014-04-25 16:58:34 -07001303 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Dan Stozaa4650a52015-05-12 12:56:16 -07001304 mFlinger->mPrimaryDispSync, maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001305 if (updateResult == BufferQueue::PRESENT_LATER) {
1306 // Producer doesn't want buffer to be displayed yet. Signal a
1307 // layer update so we check again at the next opportunity.
1308 mFlinger->signalLayerUpdate();
1309 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001310 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1311 // If the buffer has been rejected, remove it from the shadow queue
1312 // and return early
1313 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001314 mQueueItems.removeAt(0);
Dan Stozaecc50402015-04-28 14:42:06 -07001315 android_atomic_dec(&mQueuedFrames);
1316 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001317 }
1318
Dan Stoza6b9454d2014-11-07 16:00:59 -08001319 { // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001320 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1321
Dan Stoza6b9454d2014-11-07 16:00:59 -08001322 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001323
1324 // Remove any stale buffers that have been dropped during
1325 // updateTexImage
1326 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1327 mQueueItems.removeAt(0);
1328 android_atomic_dec(&mQueuedFrames);
1329 }
1330
Dan Stoza6b9454d2014-11-07 16:00:59 -08001331 mQueueItems.removeAt(0);
1332 }
1333
Dan Stozaecc50402015-04-28 14:42:06 -07001334
Andy McFadden1585c4d2013-06-28 13:52:40 -07001335 // Decrement the queued-frames count. Signal another event if we
1336 // have more frames pending.
1337 if (android_atomic_dec(&mQueuedFrames) > 1) {
1338 mFlinger->signalLayerUpdate();
1339 }
1340
1341 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001342 // something happened!
1343 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001344 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001345 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001346
Jamie Gennis351a5132011-09-14 18:23:37 -07001347 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001348 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001349 if (mActiveBuffer == NULL) {
1350 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001351 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001352 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001353
Mathias Agopian4824d402012-06-04 18:16:30 -07001354 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001355 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001356 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001357 // the first time we receive a buffer, we need to trigger a
1358 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001359 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001360 }
1361
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001362 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1363 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1364 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001365 if ((crop != mCurrentCrop) ||
1366 (transform != mCurrentTransform) ||
1367 (scalingMode != mCurrentScalingMode))
1368 {
1369 mCurrentCrop = crop;
1370 mCurrentTransform = transform;
1371 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001372 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001373 }
1374
1375 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001376 uint32_t bufWidth = mActiveBuffer->getWidth();
1377 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001378 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1379 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001380 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001381 }
1382 }
1383
1384 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001385 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001386 recomputeVisibleRegions = true;
1387 }
1388
Mathias Agopian4fec8732012-06-29 14:12:52 -07001389 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001390 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001391
1392 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001393 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001394 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001395 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001396}
1397
Mathias Agopiana67932f2011-04-20 14:20:59 -07001398uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001399{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001400 // TODO: should we do something special if mSecure is set?
1401 if (mProtectedByApp) {
1402 // need a hardware-protected path to external video sink
1403 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001404 }
Riley Andrews03414a12014-07-01 14:22:59 -07001405 if (mPotentialCursor) {
1406 usage |= GraphicBuffer::USAGE_CURSOR;
1407 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001408 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001409 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001410}
1411
Mathias Agopian84300952012-11-21 16:02:13 -08001412void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001413 uint32_t orientation = 0;
1414 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001415 // The transform hint is used to improve performance, but we can
1416 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001417 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001418 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001419 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001420 if (orientation & Transform::ROT_INVALID) {
1421 orientation = 0;
1422 }
1423 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001424 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001425}
1426
Mathias Agopian13127d82013-03-05 17:47:11 -08001427// ----------------------------------------------------------------------------
1428// debugging
1429// ----------------------------------------------------------------------------
1430
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001431void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001432{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001433 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001434
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001435 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001436 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001437 "+ %s %p (%s)\n",
1438 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001439 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001440
Mathias Agopian2ca79392013-04-02 18:30:32 -07001441 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001442 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001443 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001444 sp<Client> client(mClientRef.promote());
1445
Mathias Agopian74d211a2013-04-22 16:55:35 +02001446 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001447 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1448 "isOpaque=%1d, invalidate=%1d, "
1449 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1450 " client=%p\n",
1451 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1452 s.active.crop.left, s.active.crop.top,
1453 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001454 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001455 s.alpha, s.flags,
1456 s.transform[0][0], s.transform[0][1],
1457 s.transform[1][0], s.transform[1][1],
1458 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001459
1460 sp<const GraphicBuffer> buf0(mActiveBuffer);
1461 uint32_t w0=0, h0=0, s0=0, f0=0;
1462 if (buf0 != 0) {
1463 w0 = buf0->getWidth();
1464 h0 = buf0->getHeight();
1465 s0 = buf0->getStride();
1466 f0 = buf0->format;
1467 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001468 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001469 " "
1470 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1471 " queued-frames=%d, mRefreshPending=%d\n",
1472 mFormat, w0, h0, s0,f0,
1473 mQueuedFrames, mRefreshPending);
1474
Mathias Agopian13127d82013-03-05 17:47:11 -08001475 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001476 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001477 }
1478}
1479
Svetoslavd85084b2014-03-20 10:28:31 -07001480void Layer::dumpFrameStats(String8& result) const {
1481 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001482}
1483
Svetoslavd85084b2014-03-20 10:28:31 -07001484void Layer::clearFrameStats() {
1485 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001486}
1487
Jamie Gennis6547ff42013-07-16 20:12:42 -07001488void Layer::logFrameStats() {
1489 mFrameTracker.logAndResetStats(mName);
1490}
1491
Svetoslavd85084b2014-03-20 10:28:31 -07001492void Layer::getFrameStats(FrameStats* outStats) const {
1493 mFrameTracker.getStats(outStats);
1494}
1495
Mathias Agopian13127d82013-03-05 17:47:11 -08001496// ---------------------------------------------------------------------------
1497
1498Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1499 const sp<Layer>& layer)
1500 : mFlinger(flinger), mLayer(layer) {
1501}
1502
1503Layer::LayerCleaner::~LayerCleaner() {
1504 // destroy client resources
1505 mFlinger->onLayerDestroyed(mLayer);
1506}
1507
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001508// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001509}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001510
1511#if defined(__gl_h_)
1512#error "don't include gl/gl.h in this file"
1513#endif
1514
1515#if defined(__gl2_h_)
1516#error "don't include gl2/gl2.h in this file"
1517#endif