blob: 5ff79a9e3bf2629608e95eccd34926167d3a0c2e [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"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800138 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700139#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800140 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800141#endif
Andy McFadden69052052012-09-14 16:10:11 -0700142
Mathias Agopian84300952012-11-21 16:02:13 -0800143 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
144 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700145}
146
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700147Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800148 sp<Client> c(mClientRef.promote());
149 if (c != 0) {
150 c->detachLayer(this);
151 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700152 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700153 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700154}
155
Mathias Agopian13127d82013-03-05 17:47:11 -0800156// ---------------------------------------------------------------------------
157// callbacks
158// ---------------------------------------------------------------------------
159
Dan Stozac7014012014-02-14 15:03:43 -0800160void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800161 HWComposer::HWCLayerInterface* layer) {
162 if (layer) {
163 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700164 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800165 }
166}
167
Dan Stoza6b9454d2014-11-07 16:00:59 -0800168void Layer::onFrameAvailable(const BufferItem& item) {
169 // Add this buffer from our internal queue tracker
170 { // Autolock scope
171 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700172
173 // Reset the frame number tracker when we receive the first buffer after
174 // a frame number reset
175 if (item.mFrameNumber == 1) {
176 mLastFrameNumberReceived = 0;
177 }
178
179 // Ensure that callbacks are handled in order
180 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
181 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
182 ms2ns(500));
183 if (result != NO_ERROR) {
184 ALOGE("[%s] Timed out waiting on callback", mName.string());
185 }
186 }
187
Dan Stoza6b9454d2014-11-07 16:00:59 -0800188 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700189 android_atomic_inc(&mQueuedFrames);
Dan Stozaa4650a52015-05-12 12:56:16 -0700190
191 // Wake up any pending callbacks
192 mLastFrameNumberReceived = item.mFrameNumber;
193 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800194 }
195
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800196 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700197}
198
Dan Stoza6b9454d2014-11-07 16:00:59 -0800199void Layer::onFrameReplaced(const BufferItem& item) {
200 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaa4650a52015-05-12 12:56:16 -0700201
202 // Ensure that callbacks are handled in order
203 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
204 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
205 ms2ns(500));
206 if (result != NO_ERROR) {
207 ALOGE("[%s] Timed out waiting on callback", mName.string());
208 }
209 }
210
Dan Stoza6b9454d2014-11-07 16:00:59 -0800211 if (mQueueItems.empty()) {
212 ALOGE("Can't replace a frame on an empty queue");
213 return;
214 }
215 mQueueItems.editItemAt(0) = item;
Dan Stozaa4650a52015-05-12 12:56:16 -0700216
217 // Wake up any pending callbacks
218 mLastFrameNumberReceived = item.mFrameNumber;
219 mQueueItemCondition.broadcast();
Dan Stoza6b9454d2014-11-07 16:00:59 -0800220}
221
Jesse Hall399184a2014-03-03 15:42:54 -0800222void Layer::onSidebandStreamChanged() {
223 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
224 // mSidebandStreamChanged was false
225 mFlinger->signalLayerUpdate();
226 }
227}
228
Mathias Agopian67106042013-03-14 19:18:13 -0700229// called with SurfaceFlinger::mStateLock from the drawing thread after
230// the layer has been remove from the current state list (and just before
231// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800232void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800233 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700234}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700235
Mathias Agopian13127d82013-03-05 17:47:11 -0800236// ---------------------------------------------------------------------------
237// set-up
238// ---------------------------------------------------------------------------
239
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700240const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800241 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800242}
243
Mathias Agopianf9d93272009-06-19 17:00:27 -0700244status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800245 PixelFormat format, uint32_t flags)
246{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700247 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700248 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700249
250 // never allow a surface larger than what our underlying GL implementation
251 // can handle.
252 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800253 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700254 return BAD_VALUE;
255 }
256
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700257 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700258
Riley Andrews03414a12014-07-01 14:22:59 -0700259 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700260 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700261 mCurrentOpacity = getOpacityForFormat(format);
262
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800263 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
264 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
265 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700266
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800267 return NO_ERROR;
268}
269
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700270sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800271 Mutex::Autolock _l(mLock);
272
273 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700274 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800275
276 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700277
278 /*
279 * The layer handle is just a BBinder object passed to the client
280 * (remote process) -- we don't keep any reference on our side such that
281 * the dtor is called when the remote side let go of its reference.
282 *
283 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
284 * this layer when the handle is destroyed.
285 */
286
287 class Handle : public BBinder, public LayerCleaner {
288 wp<const Layer> mOwner;
289 public:
290 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
291 : LayerCleaner(flinger, layer), mOwner(layer) {
292 }
293 };
294
295 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800296}
297
Dan Stozab9b08832014-03-13 11:55:57 -0700298sp<IGraphicBufferProducer> Layer::getProducer() const {
299 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700300}
301
Mathias Agopian13127d82013-03-05 17:47:11 -0800302// ---------------------------------------------------------------------------
303// h/w composer set-up
304// ---------------------------------------------------------------------------
305
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800306Rect Layer::getContentCrop() const {
307 // this is the crop rectangle that applies to the buffer
308 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700309 Rect crop;
310 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800311 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700312 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800313 } else if (mActiveBuffer != NULL) {
314 // otherwise we use the whole buffer
315 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700316 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800317 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700318 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700319 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700320 return crop;
321}
322
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700323static Rect reduce(const Rect& win, const Region& exclude) {
324 if (CC_LIKELY(exclude.isEmpty())) {
325 return win;
326 }
327 if (exclude.isRect()) {
328 return win.reduce(exclude.getBounds());
329 }
330 return Region(win).subtract(exclude).getBounds();
331}
332
Mathias Agopian13127d82013-03-05 17:47:11 -0800333Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700334 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700335 return computeBounds(s.activeTransparentRegion);
336}
337
338Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
339 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800340 Rect win(s.active.w, s.active.h);
341 if (!s.active.crop.isEmpty()) {
342 win.intersect(s.active.crop, &win);
343 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700344 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700345 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800346}
347
Mathias Agopian6b442672013-07-09 21:24:52 -0700348FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800349 // the content crop is the area of the content that gets scaled to the
350 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700351 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800352
353 // the active.crop is the area of the window that gets cropped, but not
354 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700355 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800356
357 // apply the projection's clipping to the window crop in
358 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700359 // if there are no window scaling involved, this operation will map to full
360 // pixels in the buffer.
361 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
362 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700363
364 Rect activeCrop(s.active.w, s.active.h);
365 if (!s.active.crop.isEmpty()) {
366 activeCrop = s.active.crop;
367 }
368
369 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800370 activeCrop.intersect(hw->getViewport(), &activeCrop);
371 activeCrop = s.transform.inverse().transform(activeCrop);
372
Michael Lentine28ea2172014-11-19 18:32:37 -0800373 // This needs to be here as transform.transform(Rect) computes the
374 // transformed rect and then takes the bounding box of the result before
375 // returning. This means
376 // transform.inverse().transform(transform.transform(Rect)) != Rect
377 // in which case we need to make sure the final rect is clipped to the
378 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800379 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
380
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700381 // subtract the transparent region and snap to the bounds
382 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
383
Mathias Agopian13127d82013-03-05 17:47:11 -0800384 if (!activeCrop.isEmpty()) {
385 // Transform the window crop to match the buffer coordinate system,
386 // which means using the inverse of the current transform set on the
387 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700388 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700389 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
390 /*
391 * the code below applies the display's inverse transform to the buffer
392 */
393 uint32_t invTransformOrient = hw->getOrientationTransform();
394 // calculate the inverse transform
395 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
396 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
397 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700398 // If the transform has been rotated the axis of flip has been swapped
399 // so we need to swap which flip operations we are performing
400 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
401 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
402 if (is_h_flipped != is_v_flipped) {
403 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
404 NATIVE_WINDOW_TRANSFORM_FLIP_H;
405 }
Michael Lentinef7551402014-08-18 16:35:43 -0700406 }
407 // and apply to the current transform
408 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
409 }
410
Mathias Agopian13127d82013-03-05 17:47:11 -0800411 int winWidth = s.active.w;
412 int winHeight = s.active.h;
413 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700414 // If the activeCrop has been rotate the ends are rotated but not
415 // the space itself so when transforming ends back we can't rely on
416 // a modification of the axes of rotation. To account for this we
417 // need to reorient the inverse rotation in terms of the current
418 // axes of rotation.
419 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
420 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
421 if (is_h_flipped == is_v_flipped) {
422 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
423 NATIVE_WINDOW_TRANSFORM_FLIP_H;
424 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800425 winWidth = s.active.h;
426 winHeight = s.active.w;
427 }
428 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700429 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800430
Mathias Agopian6b442672013-07-09 21:24:52 -0700431 // below, crop is intersected with winCrop expressed in crop's coordinate space
432 float xScale = crop.getWidth() / float(winWidth);
433 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800434
Michael Lentinef7551402014-08-18 16:35:43 -0700435 float insetL = winCrop.left * xScale;
436 float insetT = winCrop.top * yScale;
437 float insetR = (winWidth - winCrop.right ) * xScale;
438 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800439
440 crop.left += insetL;
441 crop.top += insetT;
442 crop.right -= insetR;
443 crop.bottom -= insetB;
444 }
445 return crop;
446}
447
Mathias Agopian4fec8732012-06-29 14:12:52 -0700448void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700449 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700450 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700451{
Mathias Agopian13127d82013-03-05 17:47:11 -0800452 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700453
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700454 // enable this layer
455 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700456
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700457 if (isSecure() && !hw->isSecure()) {
458 layer.setSkip(true);
459 }
460
Mathias Agopian13127d82013-03-05 17:47:11 -0800461 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700462 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800463 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800464 layer.setBlending(mPremultipliedAlpha ?
465 HWC_BLENDING_PREMULT :
466 HWC_BLENDING_COVERAGE);
467 }
468
469 // apply the layer's transform, followed by the display's global transform
470 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700471 Region activeTransparentRegion(s.activeTransparentRegion);
472 if (!s.active.crop.isEmpty()) {
473 Rect activeCrop(s.active.crop);
474 activeCrop = s.transform.transform(activeCrop);
475 activeCrop.intersect(hw->getViewport(), &activeCrop);
476 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800477 // This needs to be here as transform.transform(Rect) computes the
478 // transformed rect and then takes the bounding box of the result before
479 // returning. This means
480 // transform.inverse().transform(transform.transform(Rect)) != Rect
481 // in which case we need to make sure the final rect is clipped to the
482 // display bounds.
483 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700484 // mark regions outside the crop as transparent
485 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
486 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
487 s.active.w, s.active.h));
488 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
489 activeCrop.left, activeCrop.bottom));
490 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
491 s.active.w, activeCrop.bottom));
492 }
493 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800494 frame.intersect(hw->getViewport(), &frame);
495 const Transform& tr(hw->getTransform());
496 layer.setFrame(tr.transform(frame));
497 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800498 layer.setPlaneAlpha(s.alpha);
499
Mathias Agopian29a367b2011-07-12 14:51:45 -0700500 /*
501 * Transformations are applied in this order:
502 * 1) buffer orientation/flip/mirror
503 * 2) state transformation (window manager)
504 * 3) layer orientation (screen orientation)
505 * (NOTE: the matrices are multiplied in reverse order)
506 */
507
508 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700509 Transform transform(tr * s.transform * bufferOrientation);
510
511 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
512 /*
513 * the code below applies the display's inverse transform to the buffer
514 */
515 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700516 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700517 // calculate the inverse transform
518 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
519 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
520 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700521 // If the transform has been rotated the axis of flip has been swapped
522 // so we need to swap which flip operations we are performing
523 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
524 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
525 if (is_h_flipped != is_v_flipped) {
526 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
527 NATIVE_WINDOW_TRANSFORM_FLIP_H;
528 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700529 }
530 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700531 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700532 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700533
534 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800535 const uint32_t orientation = transform.getOrientation();
536 if (orientation & Transform::ROT_INVALID) {
537 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700538 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700539 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800540 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700541 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700542}
543
Mathias Agopian42977342012-08-05 00:40:46 -0700544void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700545 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800546 // we have to set the visible region on every frame because
547 // we currently free it during onLayerDisplayed(), which is called
548 // after HWComposer::commit() -- every frame.
549 // Apply this display's projection's viewport to the visible region
550 // before giving it to the HWC HAL.
551 const Transform& tr = hw->getTransform();
552 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
553 layer.setVisibleRegionScreen(visible);
Dan Stozadb4850c2015-06-25 16:10:18 -0700554 layer.setSurfaceDamage(surfaceDamageRegion);
Dan Stozaee44edd2015-03-23 15:50:23 -0700555
Jesse Hall399184a2014-03-03 15:42:54 -0800556 if (mSidebandStream.get()) {
557 layer.setSidebandStream(mSidebandStream);
558 } else {
559 // NOTE: buffer can be NULL if the client never drew into this
560 // layer yet, or if we ran out of memory
561 layer.setBuffer(mActiveBuffer);
562 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700563}
Jesse Halldc5b4852012-06-29 15:21:18 -0700564
Dan Stozac7014012014-02-14 15:03:43 -0800565void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700566 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700567 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700568
569 // TODO: there is a possible optimization here: we only need to set the
570 // acquire fence the first time a new buffer is acquired on EACH display.
571
Riley Andrews03414a12014-07-01 14:22:59 -0700572 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800573 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800574 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700575 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700576 if (fenceFd == -1) {
577 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
578 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700579 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700580 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700581 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700582}
583
Riley Andrews03414a12014-07-01 14:22:59 -0700584Rect Layer::getPosition(
585 const sp<const DisplayDevice>& hw)
586{
587 // this gives us only the "orientation" component of the transform
588 const State& s(getCurrentState());
589
590 // apply the layer's transform, followed by the display's global transform
591 // here we're guaranteed that the layer's transform preserves rects
592 Rect win(s.active.w, s.active.h);
593 if (!s.active.crop.isEmpty()) {
594 win.intersect(s.active.crop, &win);
595 }
596 // subtract the transparent region and snap to the bounds
597 Rect bounds = reduce(win, s.activeTransparentRegion);
598 Rect frame(s.transform.transform(bounds));
599 frame.intersect(hw->getViewport(), &frame);
600 const Transform& tr(hw->getTransform());
601 return Rect(tr.transform(frame));
602}
603
Mathias Agopian13127d82013-03-05 17:47:11 -0800604// ---------------------------------------------------------------------------
605// drawing...
606// ---------------------------------------------------------------------------
607
608void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800609 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800610}
611
Dan Stozac7014012014-02-14 15:03:43 -0800612void Layer::draw(const sp<const DisplayDevice>& hw,
613 bool useIdentityTransform) const {
614 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800615}
616
Dan Stozac7014012014-02-14 15:03:43 -0800617void Layer::draw(const sp<const DisplayDevice>& hw) const {
618 onDraw(hw, Region(hw->bounds()), false);
619}
620
621void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
622 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800623{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800624 ATRACE_CALL();
625
Mathias Agopiana67932f2011-04-20 14:20:59 -0700626 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800627 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700628 // in fact never been drawn into. This happens frequently with
629 // SurfaceView because the WindowManager can't know when the client
630 // has drawn the first time.
631
632 // If there is nothing under us, we paint the screen in black, otherwise
633 // we just skip this update.
634
635 // figure out if there is something below us
636 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700637 const SurfaceFlinger::LayerVector& drawingLayers(
638 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700639 const size_t count = drawingLayers.size();
640 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800641 const sp<Layer>& layer(drawingLayers[i]);
642 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700643 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700644 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700645 }
646 // if not everything below us is covered, we plug the holes!
647 Region holes(clip.subtract(under));
648 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700649 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700650 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800651 return;
652 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700653
Andy McFadden97eba892012-12-11 15:21:45 -0800654 // Bind the current buffer to the GL texture, and wait for it to be
655 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800656 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
657 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800658 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700659 // Go ahead and draw the buffer anyway; no matter what we do the screen
660 // is probably going to have something visibly wrong.
661 }
662
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700663 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
664
Mathias Agopian875d8e12013-06-07 15:35:48 -0700665 RenderEngine& engine(mFlinger->getRenderEngine());
666
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700667 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700668 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700669 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700670
671 // Query the texture matrix given our current filtering mode.
672 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800673 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
674 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700675
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700676 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
677
678 /*
679 * the code below applies the display's inverse transform to the texture transform
680 */
681
682 // create a 4x4 transform matrix from the display transform flags
683 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
684 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
685 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
686
687 mat4 tr;
688 uint32_t transform = hw->getOrientationTransform();
689 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
690 tr = tr * rot90;
691 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
692 tr = tr * flipH;
693 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
694 tr = tr * flipV;
695
696 // calculate the inverse
697 tr = inverse(tr);
698
699 // and finally apply it to the original texture matrix
700 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
701 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
702 }
703
Jamie Genniscbb1a952012-05-08 17:05:52 -0700704 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700705 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
706 mTexture.setFiltering(useFiltering);
707 mTexture.setMatrix(textureMatrix);
708
709 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700710 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700711 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700712 }
Dan Stozac7014012014-02-14 15:03:43 -0800713 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700714 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800715}
716
Mathias Agopian13127d82013-03-05 17:47:11 -0800717
Dan Stozac7014012014-02-14 15:03:43 -0800718void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
719 const Region& /* clip */, float red, float green, float blue,
720 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800721{
Mathias Agopian19733a32013-08-28 18:13:56 -0700722 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800723 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700724 engine.setupFillWithColor(red, green, blue, alpha);
725 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800726}
727
728void Layer::clearWithOpenGL(
729 const sp<const DisplayDevice>& hw, const Region& clip) const {
730 clearWithOpenGL(hw, clip, 0,0,0,0);
731}
732
Dan Stozac7014012014-02-14 15:03:43 -0800733void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
734 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700735 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800736
Dan Stozac7014012014-02-14 15:03:43 -0800737 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800738
Mathias Agopian13127d82013-03-05 17:47:11 -0800739 /*
740 * NOTE: the way we compute the texture coordinates here produces
741 * different results than when we take the HWC path -- in the later case
742 * the "source crop" is rounded to texel boundaries.
743 * This can produce significantly different results when the texture
744 * is scaled by a large amount.
745 *
746 * The GL code below is more logical (imho), and the difference with
747 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700748 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800749 * GL composition when a buffer scaling is applied (maybe with some
750 * minimal value)? Or, we could make GL behave like HWC -- but this feel
751 * like more of a hack.
752 */
753 const Rect win(computeBounds());
754
Mathias Agopian3f844832013-08-07 21:24:32 -0700755 float left = float(win.left) / float(s.active.w);
756 float top = float(win.top) / float(s.active.h);
757 float right = float(win.right) / float(s.active.w);
758 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800759
Mathias Agopian875d8e12013-06-07 15:35:48 -0700760 // TODO: we probably want to generate the texture coords with the mesh
761 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700762 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
763 texCoords[0] = vec2(left, 1.0f - top);
764 texCoords[1] = vec2(left, 1.0f - bottom);
765 texCoords[2] = vec2(right, 1.0f - bottom);
766 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800767
Mathias Agopian875d8e12013-06-07 15:35:48 -0700768 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800769 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700770 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700771 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800772}
773
Ruben Brunk1681d952014-06-27 15:51:55 -0700774uint32_t Layer::getProducerStickyTransform() const {
775 int producerStickyTransform = 0;
776 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
777 if (ret != OK) {
778 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
779 strerror(-ret), ret);
780 return 0;
781 }
782 return static_cast<uint32_t>(producerStickyTransform);
783}
784
Mathias Agopian13127d82013-03-05 17:47:11 -0800785void Layer::setFiltering(bool filtering) {
786 mFiltering = filtering;
787}
788
789bool Layer::getFiltering() const {
790 return mFiltering;
791}
792
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800793// As documented in libhardware header, formats in the range
794// 0x100 - 0x1FF are specific to the HAL implementation, and
795// are known to have no alpha channel
796// TODO: move definition for device-specific range into
797// hardware.h, instead of using hard-coded values here.
798#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
799
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700800bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700801 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
802 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800803 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700804 switch (format) {
805 case HAL_PIXEL_FORMAT_RGBA_8888:
806 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700807 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700808 }
809 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700810 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800811}
812
Mathias Agopian13127d82013-03-05 17:47:11 -0800813// ----------------------------------------------------------------------------
814// local state
815// ----------------------------------------------------------------------------
816
Dan Stozac7014012014-02-14 15:03:43 -0800817void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
818 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800819{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700820 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800821 const Transform tr(useIdentityTransform ?
822 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800823 const uint32_t hw_h = hw->getHeight();
824 Rect win(s.active.w, s.active.h);
825 if (!s.active.crop.isEmpty()) {
826 win.intersect(s.active.crop, &win);
827 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700828 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700829 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700830
Mathias Agopianff2ed702013-09-01 21:36:12 -0700831 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
832 position[0] = tr.transform(win.left, win.top);
833 position[1] = tr.transform(win.left, win.bottom);
834 position[2] = tr.transform(win.right, win.bottom);
835 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700836 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700837 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800838 }
839}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800840
Andy McFadden4125a4f2014-01-29 17:17:11 -0800841bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700842{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700843 // if we don't have a buffer yet, we're translucent regardless of the
844 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700845 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700846 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700847 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700848
849 // if the layer has the opaque flag, then we're always opaque,
850 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800851 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700852}
853
Dan Stoza23116082015-06-18 14:58:39 -0700854bool Layer::isSecure() const
855{
856 const Layer::State& s(mDrawingState);
857 return (s.flags & layer_state_t::eLayerSecure);
858}
859
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800860bool Layer::isProtected() const
861{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700862 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800863 return (activeBuffer != 0) &&
864 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
865}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700866
Mathias Agopian13127d82013-03-05 17:47:11 -0800867bool Layer::isFixedSize() const {
868 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
869}
870
871bool Layer::isCropped() const {
872 return !mCurrentCrop.isEmpty();
873}
874
875bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
876 return mNeedsFiltering || hw->needsFiltering();
877}
878
879void Layer::setVisibleRegion(const Region& visibleRegion) {
880 // always called from main thread
881 this->visibleRegion = visibleRegion;
882}
883
884void Layer::setCoveredRegion(const Region& coveredRegion) {
885 // always called from main thread
886 this->coveredRegion = coveredRegion;
887}
888
889void Layer::setVisibleNonTransparentRegion(const Region&
890 setVisibleNonTransparentRegion) {
891 // always called from main thread
892 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
893}
894
895// ----------------------------------------------------------------------------
896// transaction
897// ----------------------------------------------------------------------------
898
899uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800900 ATRACE_CALL();
901
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700902 const Layer::State& s(getDrawingState());
903 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800904
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700905 const bool sizeChanged = (c.requested.w != s.requested.w) ||
906 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700907
908 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700909 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000910 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700911 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700912 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
913 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
914 " drawing={ 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",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700916 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
917 c.active.w, c.active.h,
918 c.active.crop.left,
919 c.active.crop.top,
920 c.active.crop.right,
921 c.active.crop.bottom,
922 c.active.crop.getWidth(),
923 c.active.crop.getHeight(),
924 c.requested.w, c.requested.h,
925 c.requested.crop.left,
926 c.requested.crop.top,
927 c.requested.crop.right,
928 c.requested.crop.bottom,
929 c.requested.crop.getWidth(),
930 c.requested.crop.getHeight(),
931 s.active.w, s.active.h,
932 s.active.crop.left,
933 s.active.crop.top,
934 s.active.crop.right,
935 s.active.crop.bottom,
936 s.active.crop.getWidth(),
937 s.active.crop.getHeight(),
938 s.requested.w, s.requested.h,
939 s.requested.crop.left,
940 s.requested.crop.top,
941 s.requested.crop.right,
942 s.requested.crop.bottom,
943 s.requested.crop.getWidth(),
944 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800945
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700946 // record the new size, form this point on, when the client request
947 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800948 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700949 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800950 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700951
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700952 if (!isFixedSize()) {
953
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700954 const bool resizePending = (c.requested.w != c.active.w) ||
955 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700956
Dan Stoza9e9b0442015-04-22 14:59:08 -0700957 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800958 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700959 // if we have a pending resize, unless we are in fixed-size mode.
960 // the drawing state will be updated only once we receive a buffer
961 // with the correct size.
962 //
963 // in particular, we want to make sure the clip (which is part
964 // of the geometry state) is latched together with the size but is
965 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -0700966 //
967 // If a sideband stream is attached, however, we want to skip this
968 // optimization so that transactions aren't missed when a buffer
969 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700970
971 flags |= eDontUpdateGeometryState;
972 }
973 }
974
Mathias Agopian13127d82013-03-05 17:47:11 -0800975 // always set active to requested, unless we're asked not to
976 // this is used by Layer, which special cases resizes.
977 if (flags & eDontUpdateGeometryState) {
978 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700979 Layer::State& editCurrentState(getCurrentState());
980 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800981 }
982
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700983 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800984 // invalidate and recompute the visible regions if needed
985 flags |= Layer::eVisibleRegion;
986 }
987
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700988 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800989 // invalidate and recompute the visible regions if needed
990 flags |= eVisibleRegion;
991 this->contentDirty = true;
992
993 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700994 const uint8_t type = c.transform.getType();
995 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800996 (type >= Transform::SCALE));
997 }
998
999 // Commit the transaction
1000 commitTransaction();
1001 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001002}
1003
Mathias Agopian13127d82013-03-05 17:47:11 -08001004void Layer::commitTransaction() {
1005 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001006}
1007
Mathias Agopian13127d82013-03-05 17:47:11 -08001008uint32_t Layer::getTransactionFlags(uint32_t flags) {
1009 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1010}
1011
1012uint32_t Layer::setTransactionFlags(uint32_t flags) {
1013 return android_atomic_or(flags, &mTransactionFlags);
1014}
1015
1016bool Layer::setPosition(float x, float y) {
1017 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
1018 return false;
1019 mCurrentState.sequence++;
1020 mCurrentState.transform.set(x, y);
1021 setTransactionFlags(eTransactionNeeded);
1022 return true;
1023}
1024bool Layer::setLayer(uint32_t z) {
1025 if (mCurrentState.z == z)
1026 return false;
1027 mCurrentState.sequence++;
1028 mCurrentState.z = z;
1029 setTransactionFlags(eTransactionNeeded);
1030 return true;
1031}
1032bool Layer::setSize(uint32_t w, uint32_t h) {
1033 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1034 return false;
1035 mCurrentState.requested.w = w;
1036 mCurrentState.requested.h = h;
1037 setTransactionFlags(eTransactionNeeded);
1038 return true;
1039}
1040bool Layer::setAlpha(uint8_t alpha) {
1041 if (mCurrentState.alpha == alpha)
1042 return false;
1043 mCurrentState.sequence++;
1044 mCurrentState.alpha = alpha;
1045 setTransactionFlags(eTransactionNeeded);
1046 return true;
1047}
1048bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1049 mCurrentState.sequence++;
1050 mCurrentState.transform.set(
1051 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1052 setTransactionFlags(eTransactionNeeded);
1053 return true;
1054}
1055bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001056 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001057 setTransactionFlags(eTransactionNeeded);
1058 return true;
1059}
1060bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1061 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1062 if (mCurrentState.flags == newFlags)
1063 return false;
1064 mCurrentState.sequence++;
1065 mCurrentState.flags = newFlags;
1066 setTransactionFlags(eTransactionNeeded);
1067 return true;
1068}
1069bool Layer::setCrop(const Rect& crop) {
1070 if (mCurrentState.requested.crop == crop)
1071 return false;
1072 mCurrentState.sequence++;
1073 mCurrentState.requested.crop = crop;
1074 setTransactionFlags(eTransactionNeeded);
1075 return true;
1076}
1077
1078bool Layer::setLayerStack(uint32_t layerStack) {
1079 if (mCurrentState.layerStack == layerStack)
1080 return false;
1081 mCurrentState.sequence++;
1082 mCurrentState.layerStack = layerStack;
1083 setTransactionFlags(eTransactionNeeded);
1084 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001085}
1086
Dan Stozaee44edd2015-03-23 15:50:23 -07001087void Layer::useSurfaceDamage() {
1088 if (mFlinger->mForceFullDamage) {
1089 surfaceDamageRegion = Region::INVALID_REGION;
1090 } else {
1091 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1092 }
1093}
1094
1095void Layer::useEmptyDamage() {
1096 surfaceDamageRegion.clear();
1097}
1098
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001099// ----------------------------------------------------------------------------
1100// pageflip handling...
1101// ----------------------------------------------------------------------------
1102
Dan Stoza6b9454d2014-11-07 16:00:59 -08001103bool Layer::shouldPresentNow(const DispSync& dispSync) const {
Dan Stozad87defa2015-07-29 16:15:50 -07001104 if (mSidebandStreamChanged) {
1105 return true;
1106 }
1107
Dan Stoza6b9454d2014-11-07 16:00:59 -08001108 Mutex::Autolock lock(mQueueItemLock);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001109 if (mQueueItems.empty()) {
1110 return false;
1111 }
1112 auto timestamp = mQueueItems[0].mTimestamp;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001113 nsecs_t expectedPresent =
1114 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
Dan Stoza0eb2d392015-07-06 12:56:50 -07001115
1116 // Ignore timestamps more than a second in the future
1117 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
1118 ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
1119 "relative to expectedPresent %" PRId64, mName.string(), timestamp,
1120 expectedPresent);
1121
1122 bool isDue = timestamp < expectedPresent;
1123 return isDue || !isPlausible;
Dan Stoza6b9454d2014-11-07 16:00:59 -08001124}
1125
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001126bool Layer::onPreComposition() {
1127 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001128 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001129}
1130
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001131void Layer::onPostComposition() {
1132 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001133 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001134 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1135
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001136 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001137 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001138 mFrameTracker.setFrameReadyFence(frameReadyFence);
1139 } else {
1140 // There was no fence for this frame, so assume that it was ready
1141 // to be presented at the desired present time.
1142 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1143 }
1144
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001145 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001146 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001147 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001148 mFrameTracker.setActualPresentFence(presentFence);
1149 } else {
1150 // The HWC doesn't support present fences, so use the refresh
1151 // timestamp instead.
1152 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1153 mFrameTracker.setActualPresentTime(presentTime);
1154 }
1155
1156 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001157 mFrameLatencyNeeded = false;
1158 }
1159}
1160
Mathias Agopianda27af92012-09-13 18:17:13 -07001161bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001162 const Layer::State& s(mDrawingState);
1163 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001164 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001165}
1166
Mathias Agopian4fec8732012-06-29 14:12:52 -07001167Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001168{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001169 ATRACE_CALL();
1170
Jesse Hall399184a2014-03-03 15:42:54 -08001171 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1172 // mSidebandStreamChanged was true
1173 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Dan Stoza12e0a272015-05-05 14:00:52 -07001174 if (mSidebandStream != NULL) {
1175 setTransactionFlags(eTransactionNeeded);
1176 mFlinger->setTransactionFlags(eTraversalNeeded);
1177 }
Jesse Hall5bf786d2014-09-30 10:35:11 -07001178 recomputeVisibleRegions = true;
1179
1180 const State& s(getDrawingState());
1181 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001182 }
1183
Mathias Agopian4fec8732012-06-29 14:12:52 -07001184 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001185 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001186
1187 // if we've already called updateTexImage() without going through
1188 // a composition step, we have to skip this layer at this point
1189 // because we cannot call updateTeximage() without a corresponding
1190 // compositionComplete() call.
1191 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001192 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001193 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001194 }
1195
Jamie Gennis351a5132011-09-14 18:23:37 -07001196 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001197 const State& s(getDrawingState());
1198 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001199 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001200
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001201 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001202 Layer::State& front;
1203 Layer::State& current;
1204 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001205 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001206 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001207 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001208 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001209 recomputeVisibleRegions(recomputeVisibleRegions),
1210 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001211 }
1212
1213 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001214 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001215 if (buf == NULL) {
1216 return false;
1217 }
1218
1219 uint32_t bufWidth = buf->getWidth();
1220 uint32_t bufHeight = buf->getHeight();
1221
1222 // check that we received a buffer of the right size
1223 // (Take the buffer's orientation into account)
1224 if (item.mTransform & Transform::ROT_90) {
1225 swap(bufWidth, bufHeight);
1226 }
1227
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001228 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1229 if (front.active != front.requested) {
1230
1231 if (isFixedSize ||
1232 (bufWidth == front.requested.w &&
1233 bufHeight == front.requested.h))
1234 {
1235 // Here we pretend the transaction happened by updating the
1236 // current and drawing states. Drawing state is only accessed
1237 // in this thread, no need to have it locked
1238 front.active = front.requested;
1239
1240 // We also need to update the current state so that
1241 // we don't end-up overwriting the drawing state with
1242 // this stale current state during the next transaction
1243 //
1244 // NOTE: We don't need to hold the transaction lock here
1245 // because State::active is only accessed from this thread.
1246 current.active = front.active;
1247
1248 // recompute visible region
1249 recomputeVisibleRegions = true;
1250 }
1251
1252 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001253 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001254 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1255 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001256 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001257 front.active.w, front.active.h,
1258 front.active.crop.left,
1259 front.active.crop.top,
1260 front.active.crop.right,
1261 front.active.crop.bottom,
1262 front.active.crop.getWidth(),
1263 front.active.crop.getHeight(),
1264 front.requested.w, front.requested.h,
1265 front.requested.crop.left,
1266 front.requested.crop.top,
1267 front.requested.crop.right,
1268 front.requested.crop.bottom,
1269 front.requested.crop.getWidth(),
1270 front.requested.crop.getHeight());
1271 }
1272
Ruben Brunk1681d952014-06-27 15:51:55 -07001273 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001274 if (front.active.w != bufWidth ||
1275 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001276 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001277 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1278 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001279 return true;
1280 }
1281 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001282
1283 // if the transparent region has changed (this test is
1284 // conservative, but that's fine, worst case we're doing
1285 // a bit of extra work), we latch the new one and we
1286 // trigger a visible-region recompute.
1287 if (!front.activeTransparentRegion.isTriviallyEqual(
1288 front.requestedTransparentRegion)) {
1289 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001290
1291 // We also need to update the current state so that
1292 // we don't end-up overwriting the drawing state with
1293 // this stale current state during the next transaction
1294 //
1295 // NOTE: We don't need to hold the transaction lock here
1296 // because State::active is only accessed from this thread.
1297 current.activeTransparentRegion = front.activeTransparentRegion;
1298
1299 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001300 recomputeVisibleRegions = true;
1301 }
1302
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001303 return false;
1304 }
1305 };
1306
Ruben Brunk1681d952014-06-27 15:51:55 -07001307 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1308 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001309
Dan Stozaa4650a52015-05-12 12:56:16 -07001310 uint64_t maxFrameNumber = 0;
1311 {
1312 Mutex::Autolock lock(mQueueItemLock);
1313 maxFrameNumber = mLastFrameNumberReceived;
1314 }
1315
Andy McFadden41d67d72014-04-25 16:58:34 -07001316 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
Dan Stozaa4650a52015-05-12 12:56:16 -07001317 mFlinger->mPrimaryDispSync, maxFrameNumber);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001318 if (updateResult == BufferQueue::PRESENT_LATER) {
1319 // Producer doesn't want buffer to be displayed yet. Signal a
1320 // layer update so we check again at the next opportunity.
1321 mFlinger->signalLayerUpdate();
1322 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001323 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1324 // If the buffer has been rejected, remove it from the shadow queue
1325 // and return early
1326 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001327 mQueueItems.removeAt(0);
Dan Stozaecc50402015-04-28 14:42:06 -07001328 android_atomic_dec(&mQueuedFrames);
1329 return outDirtyRegion;
Dan Stoza65476f32015-05-14 09:27:25 -07001330 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
1331 // This can occur if something goes wrong when trying to create the
1332 // EGLImage for this buffer. If this happens, the buffer has already
1333 // been released, so we need to clean up the queue and bug out
1334 // early.
1335 {
1336 Mutex::Autolock lock(mQueueItemLock);
1337 mQueueItems.clear();
1338 android_atomic_and(0, &mQueuedFrames);
1339 }
1340
1341 // Once we have hit this state, the shadow queue may no longer
1342 // correctly reflect the incoming BufferQueue's contents, so even if
1343 // updateTexImage starts working, the only safe course of action is
1344 // to continue to ignore updates.
1345 mUpdateTexImageFailed = true;
1346
1347 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001348 }
1349
Dan Stoza6b9454d2014-11-07 16:00:59 -08001350 { // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001351 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1352
Dan Stoza6b9454d2014-11-07 16:00:59 -08001353 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001354
1355 // Remove any stale buffers that have been dropped during
1356 // updateTexImage
1357 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1358 mQueueItems.removeAt(0);
1359 android_atomic_dec(&mQueuedFrames);
1360 }
1361
Dan Stoza6b9454d2014-11-07 16:00:59 -08001362 mQueueItems.removeAt(0);
1363 }
1364
Dan Stozaecc50402015-04-28 14:42:06 -07001365
Andy McFadden1585c4d2013-06-28 13:52:40 -07001366 // Decrement the queued-frames count. Signal another event if we
1367 // have more frames pending.
1368 if (android_atomic_dec(&mQueuedFrames) > 1) {
1369 mFlinger->signalLayerUpdate();
1370 }
1371
1372 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001373 // something happened!
1374 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001375 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001376 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001377
Jamie Gennis351a5132011-09-14 18:23:37 -07001378 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001379 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001380 if (mActiveBuffer == NULL) {
1381 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001382 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001383 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001384
Mathias Agopian4824d402012-06-04 18:16:30 -07001385 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001386 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001387 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001388 // the first time we receive a buffer, we need to trigger a
1389 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001390 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001391 }
1392
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001393 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1394 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1395 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001396 if ((crop != mCurrentCrop) ||
1397 (transform != mCurrentTransform) ||
1398 (scalingMode != mCurrentScalingMode))
1399 {
1400 mCurrentCrop = crop;
1401 mCurrentTransform = transform;
1402 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001403 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001404 }
1405
1406 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001407 uint32_t bufWidth = mActiveBuffer->getWidth();
1408 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001409 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1410 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001411 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001412 }
1413 }
1414
1415 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001416 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001417 recomputeVisibleRegions = true;
1418 }
1419
Mathias Agopian4fec8732012-06-29 14:12:52 -07001420 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001421 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001422
1423 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001424 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001425 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001426 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001427}
1428
Mathias Agopiana67932f2011-04-20 14:20:59 -07001429uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001430{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001431 // TODO: should we do something special if mSecure is set?
1432 if (mProtectedByApp) {
1433 // need a hardware-protected path to external video sink
1434 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001435 }
Riley Andrews03414a12014-07-01 14:22:59 -07001436 if (mPotentialCursor) {
1437 usage |= GraphicBuffer::USAGE_CURSOR;
1438 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001439 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001440 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001441}
1442
Mathias Agopian84300952012-11-21 16:02:13 -08001443void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001444 uint32_t orientation = 0;
1445 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001446 // The transform hint is used to improve performance, but we can
1447 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001448 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001449 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001450 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001451 if (orientation & Transform::ROT_INVALID) {
1452 orientation = 0;
1453 }
1454 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001455 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001456}
1457
Mathias Agopian13127d82013-03-05 17:47:11 -08001458// ----------------------------------------------------------------------------
1459// debugging
1460// ----------------------------------------------------------------------------
1461
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001462void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001463{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001464 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001465
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001466 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001467 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001468 "+ %s %p (%s)\n",
1469 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001470 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001471
Mathias Agopian2ca79392013-04-02 18:30:32 -07001472 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001473 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001474 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001475 sp<Client> client(mClientRef.promote());
1476
Mathias Agopian74d211a2013-04-22 16:55:35 +02001477 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001478 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1479 "isOpaque=%1d, invalidate=%1d, "
1480 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1481 " client=%p\n",
1482 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1483 s.active.crop.left, s.active.crop.top,
1484 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001485 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001486 s.alpha, s.flags,
1487 s.transform[0][0], s.transform[0][1],
1488 s.transform[1][0], s.transform[1][1],
1489 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001490
1491 sp<const GraphicBuffer> buf0(mActiveBuffer);
1492 uint32_t w0=0, h0=0, s0=0, f0=0;
1493 if (buf0 != 0) {
1494 w0 = buf0->getWidth();
1495 h0 = buf0->getHeight();
1496 s0 = buf0->getStride();
1497 f0 = buf0->format;
1498 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001499 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001500 " "
1501 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1502 " queued-frames=%d, mRefreshPending=%d\n",
1503 mFormat, w0, h0, s0,f0,
1504 mQueuedFrames, mRefreshPending);
1505
Mathias Agopian13127d82013-03-05 17:47:11 -08001506 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001507 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001508 }
1509}
1510
Svetoslavd85084b2014-03-20 10:28:31 -07001511void Layer::dumpFrameStats(String8& result) const {
1512 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001513}
1514
Svetoslavd85084b2014-03-20 10:28:31 -07001515void Layer::clearFrameStats() {
1516 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001517}
1518
Jamie Gennis6547ff42013-07-16 20:12:42 -07001519void Layer::logFrameStats() {
1520 mFrameTracker.logAndResetStats(mName);
1521}
1522
Svetoslavd85084b2014-03-20 10:28:31 -07001523void Layer::getFrameStats(FrameStats* outStats) const {
1524 mFrameTracker.getStats(outStats);
1525}
1526
Mathias Agopian13127d82013-03-05 17:47:11 -08001527// ---------------------------------------------------------------------------
1528
1529Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1530 const sp<Layer>& layer)
1531 : mFlinger(flinger), mLayer(layer) {
1532}
1533
1534Layer::LayerCleaner::~LayerCleaner() {
1535 // destroy client resources
1536 mFlinger->onLayerDestroyed(mLayer);
1537}
1538
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001539// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001540}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001541
1542#if defined(__gl_h_)
1543#error "don't include gl/gl.h in this file"
1544#endif
1545
1546#if defined(__gl2_h_)
1547#error "don't include gl2/gl2.h in this file"
1548#endif