blob: 716d24ee9d15b4b7f1ce03dcc39070055bb6e2cf [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
Mathias Agopian90ac7992012-02-25 18:48:35 -080037#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038
39#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020040#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070041#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070043#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080044#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045
Mathias Agopian1b031492012-06-20 17:51:20 -070046#include "DisplayHardware/HWComposer.h"
47
Mathias Agopian875d8e12013-06-07 15:35:48 -070048#include "RenderEngine/RenderEngine.h"
49
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050#define DEBUG_RESIZE 0
51
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080052namespace android {
53
54// ---------------------------------------------------------------------------
55
Mathias Agopian13127d82013-03-05 17:47:11 -080056int32_t Layer::sSequence = 1;
57
Mathias Agopian4d9b8222013-03-12 17:11:48 -070058Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
59 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080060 : contentDirty(false),
61 sequence(uint32_t(android_atomic_inc(&sSequence))),
62 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070063 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080064 mPremultipliedAlpha(true),
65 mName("unnamed"),
66 mDebug(false),
67 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),
83 mPotentialCursor(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080084{
Mathias Agopiana67932f2011-04-20 14:20:59 -070085 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070086 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070087 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070088
89 uint32_t layerFlags = 0;
90 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080091 layerFlags |= layer_state_t::eLayerHidden;
92 if (flags & ISurfaceComposerClient::eOpaque)
93 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070094
95 if (flags & ISurfaceComposerClient::eNonPremultiplied)
96 mPremultipliedAlpha = false;
97
98 mName = name;
99
100 mCurrentState.active.w = w;
101 mCurrentState.active.h = h;
102 mCurrentState.active.crop.makeInvalid();
103 mCurrentState.z = 0;
104 mCurrentState.alpha = 0xFF;
105 mCurrentState.layerStack = 0;
106 mCurrentState.flags = layerFlags;
107 mCurrentState.sequence = 0;
108 mCurrentState.transform.set(0, 0);
109 mCurrentState.requested = mCurrentState.active;
110
111 // drawing state & current state are identical
112 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700113
114 nsecs_t displayPeriod =
115 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
116 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800117}
118
Mathias Agopian3f844832013-08-07 21:24:32 -0700119void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800120 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700121 sp<IGraphicBufferProducer> producer;
122 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700123 BufferQueue::createBufferQueue(&producer, &consumer);
124 mProducer = new MonitoredProducer(producer, mFlinger);
125 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800126 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800127 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700128 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800129
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700130#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
131#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800132 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700133#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800134 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800135#endif
Andy McFadden69052052012-09-14 16:10:11 -0700136
Mathias Agopian84300952012-11-21 16:02:13 -0800137 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
138 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700139}
140
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700141Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800142 sp<Client> c(mClientRef.promote());
143 if (c != 0) {
144 c->detachLayer(this);
145 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700146 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700147 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700148}
149
Mathias Agopian13127d82013-03-05 17:47:11 -0800150// ---------------------------------------------------------------------------
151// callbacks
152// ---------------------------------------------------------------------------
153
Dan Stozac7014012014-02-14 15:03:43 -0800154void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800155 HWComposer::HWCLayerInterface* layer) {
156 if (layer) {
157 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700158 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800159 }
160}
161
Igor Murashkina4a31492012-10-29 13:36:11 -0700162void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700163 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800164 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700165}
166
Jesse Hall399184a2014-03-03 15:42:54 -0800167void Layer::onSidebandStreamChanged() {
168 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
169 // mSidebandStreamChanged was false
170 mFlinger->signalLayerUpdate();
171 }
172}
173
Mathias Agopian67106042013-03-14 19:18:13 -0700174// called with SurfaceFlinger::mStateLock from the drawing thread after
175// the layer has been remove from the current state list (and just before
176// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800177void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800178 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700179}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700180
Mathias Agopian13127d82013-03-05 17:47:11 -0800181// ---------------------------------------------------------------------------
182// set-up
183// ---------------------------------------------------------------------------
184
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700185const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800186 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800187}
188
Mathias Agopianf9d93272009-06-19 17:00:27 -0700189status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800190 PixelFormat format, uint32_t flags)
191{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700192 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700193 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700194
195 // never allow a surface larger than what our underlying GL implementation
196 // can handle.
197 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800198 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700199 return BAD_VALUE;
200 }
201
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700202 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700203
Riley Andrews03414a12014-07-01 14:22:59 -0700204 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700205 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
206 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700207 mCurrentOpacity = getOpacityForFormat(format);
208
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800209 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
210 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
211 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700212
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800213 return NO_ERROR;
214}
215
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700216sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800217 Mutex::Autolock _l(mLock);
218
219 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700220 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800221
222 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700223
224 /*
225 * The layer handle is just a BBinder object passed to the client
226 * (remote process) -- we don't keep any reference on our side such that
227 * the dtor is called when the remote side let go of its reference.
228 *
229 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
230 * this layer when the handle is destroyed.
231 */
232
233 class Handle : public BBinder, public LayerCleaner {
234 wp<const Layer> mOwner;
235 public:
236 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
237 : LayerCleaner(flinger, layer), mOwner(layer) {
238 }
239 };
240
241 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800242}
243
Dan Stozab9b08832014-03-13 11:55:57 -0700244sp<IGraphicBufferProducer> Layer::getProducer() const {
245 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700246}
247
Mathias Agopian13127d82013-03-05 17:47:11 -0800248// ---------------------------------------------------------------------------
249// h/w composer set-up
250// ---------------------------------------------------------------------------
251
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800252Rect Layer::getContentCrop() const {
253 // this is the crop rectangle that applies to the buffer
254 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700255 Rect crop;
256 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800257 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700258 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800259 } else if (mActiveBuffer != NULL) {
260 // otherwise we use the whole buffer
261 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700262 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800263 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700264 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700265 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700266 return crop;
267}
268
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700269static Rect reduce(const Rect& win, const Region& exclude) {
270 if (CC_LIKELY(exclude.isEmpty())) {
271 return win;
272 }
273 if (exclude.isRect()) {
274 return win.reduce(exclude.getBounds());
275 }
276 return Region(win).subtract(exclude).getBounds();
277}
278
Mathias Agopian13127d82013-03-05 17:47:11 -0800279Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700280 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800281 Rect win(s.active.w, s.active.h);
282 if (!s.active.crop.isEmpty()) {
283 win.intersect(s.active.crop, &win);
284 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700285 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700286 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800287}
288
Mathias Agopian6b442672013-07-09 21:24:52 -0700289FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800290 // the content crop is the area of the content that gets scaled to the
291 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700292 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800293
294 // the active.crop is the area of the window that gets cropped, but not
295 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700296 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800297
298 // apply the projection's clipping to the window crop in
299 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700300 // if there are no window scaling involved, this operation will map to full
301 // pixels in the buffer.
302 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
303 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700304
305 Rect activeCrop(s.active.w, s.active.h);
306 if (!s.active.crop.isEmpty()) {
307 activeCrop = s.active.crop;
308 }
309
310 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800311 activeCrop.intersect(hw->getViewport(), &activeCrop);
312 activeCrop = s.transform.inverse().transform(activeCrop);
313
314 // paranoia: make sure the window-crop is constrained in the
315 // window's bounds
316 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
317
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700318 // subtract the transparent region and snap to the bounds
319 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
320
Mathias Agopian13127d82013-03-05 17:47:11 -0800321 if (!activeCrop.isEmpty()) {
322 // Transform the window crop to match the buffer coordinate system,
323 // which means using the inverse of the current transform set on the
324 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700325 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800326 int winWidth = s.active.w;
327 int winHeight = s.active.h;
328 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
329 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
330 NATIVE_WINDOW_TRANSFORM_FLIP_H;
331 winWidth = s.active.h;
332 winHeight = s.active.w;
333 }
334 const Rect winCrop = activeCrop.transform(
Michael Lentine5af281f2014-08-07 13:40:48 -0700335 invTransform, winWidth, winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800336
Mathias Agopian6b442672013-07-09 21:24:52 -0700337 // below, crop is intersected with winCrop expressed in crop's coordinate space
338 float xScale = crop.getWidth() / float(winWidth);
339 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800340
Michael Lentine5af281f2014-08-07 13:40:48 -0700341 float insetL = winCrop.left * xScale;
342 float insetT = winCrop.top * yScale;
343 float insetR = (s.active.w - winCrop.right ) * xScale;
344 float insetB = (s.active.h - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800345
346 crop.left += insetL;
347 crop.top += insetT;
348 crop.right -= insetR;
349 crop.bottom -= insetB;
350 }
351 return crop;
352}
353
Mathias Agopian4fec8732012-06-29 14:12:52 -0700354void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700355 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700356 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700357{
Mathias Agopian13127d82013-03-05 17:47:11 -0800358 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700359
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700360 // enable this layer
361 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700362
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700363 if (isSecure() && !hw->isSecure()) {
364 layer.setSkip(true);
365 }
366
Mathias Agopian13127d82013-03-05 17:47:11 -0800367 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700368 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800369 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800370 layer.setBlending(mPremultipliedAlpha ?
371 HWC_BLENDING_PREMULT :
372 HWC_BLENDING_COVERAGE);
373 }
374
375 // apply the layer's transform, followed by the display's global transform
376 // here we're guaranteed that the layer's transform preserves rects
377 Rect frame(s.transform.transform(computeBounds()));
378 frame.intersect(hw->getViewport(), &frame);
379 const Transform& tr(hw->getTransform());
380 layer.setFrame(tr.transform(frame));
381 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800382 layer.setPlaneAlpha(s.alpha);
383
Mathias Agopian29a367b2011-07-12 14:51:45 -0700384 /*
385 * Transformations are applied in this order:
386 * 1) buffer orientation/flip/mirror
387 * 2) state transformation (window manager)
388 * 3) layer orientation (screen orientation)
389 * (NOTE: the matrices are multiplied in reverse order)
390 */
391
392 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700393 Transform transform(tr * s.transform * bufferOrientation);
394
395 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
396 /*
397 * the code below applies the display's inverse transform to the buffer
398 */
399 uint32_t invTransform = hw->getOrientationTransform();
400 // calculate the inverse transform
401 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
402 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
403 NATIVE_WINDOW_TRANSFORM_FLIP_H;
404 }
405 // and apply to the current transform
406 transform = transform * Transform(invTransform);
407 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700408
409 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800410 const uint32_t orientation = transform.getOrientation();
411 if (orientation & Transform::ROT_INVALID) {
412 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700413 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700414 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800415 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700416 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700417}
418
Mathias Agopian42977342012-08-05 00:40:46 -0700419void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700420 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800421 // we have to set the visible region on every frame because
422 // we currently free it during onLayerDisplayed(), which is called
423 // after HWComposer::commit() -- every frame.
424 // Apply this display's projection's viewport to the visible region
425 // before giving it to the HWC HAL.
426 const Transform& tr = hw->getTransform();
427 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
428 layer.setVisibleRegionScreen(visible);
429
Jesse Hall399184a2014-03-03 15:42:54 -0800430 if (mSidebandStream.get()) {
431 layer.setSidebandStream(mSidebandStream);
432 } else {
433 // NOTE: buffer can be NULL if the client never drew into this
434 // layer yet, or if we ran out of memory
435 layer.setBuffer(mActiveBuffer);
436 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700437}
Jesse Halldc5b4852012-06-29 15:21:18 -0700438
Dan Stozac7014012014-02-14 15:03:43 -0800439void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700440 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700441 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700442
443 // TODO: there is a possible optimization here: we only need to set the
444 // acquire fence the first time a new buffer is acquired on EACH display.
445
Riley Andrews03414a12014-07-01 14:22:59 -0700446 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800447 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800448 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700449 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700450 if (fenceFd == -1) {
451 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
452 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700453 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700454 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700455 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700456}
457
Riley Andrews03414a12014-07-01 14:22:59 -0700458Rect Layer::getPosition(
459 const sp<const DisplayDevice>& hw)
460{
461 // this gives us only the "orientation" component of the transform
462 const State& s(getCurrentState());
463
464 // apply the layer's transform, followed by the display's global transform
465 // here we're guaranteed that the layer's transform preserves rects
466 Rect win(s.active.w, s.active.h);
467 if (!s.active.crop.isEmpty()) {
468 win.intersect(s.active.crop, &win);
469 }
470 // subtract the transparent region and snap to the bounds
471 Rect bounds = reduce(win, s.activeTransparentRegion);
472 Rect frame(s.transform.transform(bounds));
473 frame.intersect(hw->getViewport(), &frame);
474 const Transform& tr(hw->getTransform());
475 return Rect(tr.transform(frame));
476}
477
Mathias Agopian13127d82013-03-05 17:47:11 -0800478// ---------------------------------------------------------------------------
479// drawing...
480// ---------------------------------------------------------------------------
481
482void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800483 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800484}
485
Dan Stozac7014012014-02-14 15:03:43 -0800486void Layer::draw(const sp<const DisplayDevice>& hw,
487 bool useIdentityTransform) const {
488 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800489}
490
Dan Stozac7014012014-02-14 15:03:43 -0800491void Layer::draw(const sp<const DisplayDevice>& hw) const {
492 onDraw(hw, Region(hw->bounds()), false);
493}
494
495void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
496 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800497{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800498 ATRACE_CALL();
499
Mathias Agopiana67932f2011-04-20 14:20:59 -0700500 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800501 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700502 // in fact never been drawn into. This happens frequently with
503 // SurfaceView because the WindowManager can't know when the client
504 // has drawn the first time.
505
506 // If there is nothing under us, we paint the screen in black, otherwise
507 // we just skip this update.
508
509 // figure out if there is something below us
510 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700511 const SurfaceFlinger::LayerVector& drawingLayers(
512 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700513 const size_t count = drawingLayers.size();
514 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800515 const sp<Layer>& layer(drawingLayers[i]);
516 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700517 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700518 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700519 }
520 // if not everything below us is covered, we plug the holes!
521 Region holes(clip.subtract(under));
522 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700523 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700524 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800525 return;
526 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700527
Andy McFadden97eba892012-12-11 15:21:45 -0800528 // Bind the current buffer to the GL texture, and wait for it to be
529 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800530 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
531 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800532 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700533 // Go ahead and draw the buffer anyway; no matter what we do the screen
534 // is probably going to have something visibly wrong.
535 }
536
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700537 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
538
Mathias Agopian875d8e12013-06-07 15:35:48 -0700539 RenderEngine& engine(mFlinger->getRenderEngine());
540
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700541 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700542 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700543 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700544
545 // Query the texture matrix given our current filtering mode.
546 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800547 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
548 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700549
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700550 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
551
552 /*
553 * the code below applies the display's inverse transform to the texture transform
554 */
555
556 // create a 4x4 transform matrix from the display transform flags
557 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
558 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
559 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
560
561 mat4 tr;
562 uint32_t transform = hw->getOrientationTransform();
563 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
564 tr = tr * rot90;
565 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
566 tr = tr * flipH;
567 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
568 tr = tr * flipV;
569
570 // calculate the inverse
571 tr = inverse(tr);
572
573 // and finally apply it to the original texture matrix
574 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
575 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
576 }
577
Jamie Genniscbb1a952012-05-08 17:05:52 -0700578 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700579 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
580 mTexture.setFiltering(useFiltering);
581 mTexture.setMatrix(textureMatrix);
582
583 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700584 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700585 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700586 }
Dan Stozac7014012014-02-14 15:03:43 -0800587 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700588 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800589}
590
Mathias Agopian13127d82013-03-05 17:47:11 -0800591
Dan Stozac7014012014-02-14 15:03:43 -0800592void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
593 const Region& /* clip */, float red, float green, float blue,
594 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800595{
Mathias Agopian19733a32013-08-28 18:13:56 -0700596 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800597 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700598 engine.setupFillWithColor(red, green, blue, alpha);
599 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800600}
601
602void Layer::clearWithOpenGL(
603 const sp<const DisplayDevice>& hw, const Region& clip) const {
604 clearWithOpenGL(hw, clip, 0,0,0,0);
605}
606
Dan Stozac7014012014-02-14 15:03:43 -0800607void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
608 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800609 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700610 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800611
Dan Stozac7014012014-02-14 15:03:43 -0800612 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800613
Mathias Agopian13127d82013-03-05 17:47:11 -0800614 /*
615 * NOTE: the way we compute the texture coordinates here produces
616 * different results than when we take the HWC path -- in the later case
617 * the "source crop" is rounded to texel boundaries.
618 * This can produce significantly different results when the texture
619 * is scaled by a large amount.
620 *
621 * The GL code below is more logical (imho), and the difference with
622 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700623 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800624 * GL composition when a buffer scaling is applied (maybe with some
625 * minimal value)? Or, we could make GL behave like HWC -- but this feel
626 * like more of a hack.
627 */
628 const Rect win(computeBounds());
629
Mathias Agopian3f844832013-08-07 21:24:32 -0700630 float left = float(win.left) / float(s.active.w);
631 float top = float(win.top) / float(s.active.h);
632 float right = float(win.right) / float(s.active.w);
633 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800634
Mathias Agopian875d8e12013-06-07 15:35:48 -0700635 // TODO: we probably want to generate the texture coords with the mesh
636 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700637 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
638 texCoords[0] = vec2(left, 1.0f - top);
639 texCoords[1] = vec2(left, 1.0f - bottom);
640 texCoords[2] = vec2(right, 1.0f - bottom);
641 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800642
Mathias Agopian875d8e12013-06-07 15:35:48 -0700643 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800644 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700645 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700646 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800647}
648
Ruben Brunk1681d952014-06-27 15:51:55 -0700649uint32_t Layer::getProducerStickyTransform() const {
650 int producerStickyTransform = 0;
651 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
652 if (ret != OK) {
653 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
654 strerror(-ret), ret);
655 return 0;
656 }
657 return static_cast<uint32_t>(producerStickyTransform);
658}
659
Mathias Agopian13127d82013-03-05 17:47:11 -0800660void Layer::setFiltering(bool filtering) {
661 mFiltering = filtering;
662}
663
664bool Layer::getFiltering() const {
665 return mFiltering;
666}
667
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800668// As documented in libhardware header, formats in the range
669// 0x100 - 0x1FF are specific to the HAL implementation, and
670// are known to have no alpha channel
671// TODO: move definition for device-specific range into
672// hardware.h, instead of using hard-coded values here.
673#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
674
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700675bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700676 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
677 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800678 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700679 switch (format) {
680 case HAL_PIXEL_FORMAT_RGBA_8888:
681 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700682 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700683 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700684 }
685 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700686 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800687}
688
Mathias Agopian13127d82013-03-05 17:47:11 -0800689// ----------------------------------------------------------------------------
690// local state
691// ----------------------------------------------------------------------------
692
Dan Stozac7014012014-02-14 15:03:43 -0800693void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
694 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800695{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700696 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800697 const Transform tr(useIdentityTransform ?
698 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800699 const uint32_t hw_h = hw->getHeight();
700 Rect win(s.active.w, s.active.h);
701 if (!s.active.crop.isEmpty()) {
702 win.intersect(s.active.crop, &win);
703 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700704 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700705 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700706
Mathias Agopianff2ed702013-09-01 21:36:12 -0700707 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
708 position[0] = tr.transform(win.left, win.top);
709 position[1] = tr.transform(win.left, win.bottom);
710 position[2] = tr.transform(win.right, win.bottom);
711 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700712 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700713 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800714 }
715}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800716
Andy McFadden4125a4f2014-01-29 17:17:11 -0800717bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700718{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700719 // if we don't have a buffer yet, we're translucent regardless of the
720 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700721 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700722 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700723 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700724
725 // if the layer has the opaque flag, then we're always opaque,
726 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800727 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700728}
729
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800730bool Layer::isProtected() const
731{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700732 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800733 return (activeBuffer != 0) &&
734 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
735}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700736
Mathias Agopian13127d82013-03-05 17:47:11 -0800737bool Layer::isFixedSize() const {
738 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
739}
740
741bool Layer::isCropped() const {
742 return !mCurrentCrop.isEmpty();
743}
744
745bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
746 return mNeedsFiltering || hw->needsFiltering();
747}
748
749void Layer::setVisibleRegion(const Region& visibleRegion) {
750 // always called from main thread
751 this->visibleRegion = visibleRegion;
752}
753
754void Layer::setCoveredRegion(const Region& coveredRegion) {
755 // always called from main thread
756 this->coveredRegion = coveredRegion;
757}
758
759void Layer::setVisibleNonTransparentRegion(const Region&
760 setVisibleNonTransparentRegion) {
761 // always called from main thread
762 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
763}
764
765// ----------------------------------------------------------------------------
766// transaction
767// ----------------------------------------------------------------------------
768
769uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800770 ATRACE_CALL();
771
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700772 const Layer::State& s(getDrawingState());
773 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800774
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700775 const bool sizeChanged = (c.requested.w != s.requested.w) ||
776 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700777
778 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700779 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000780 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700781 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700782 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
783 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
784 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
785 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700786 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
787 c.active.w, c.active.h,
788 c.active.crop.left,
789 c.active.crop.top,
790 c.active.crop.right,
791 c.active.crop.bottom,
792 c.active.crop.getWidth(),
793 c.active.crop.getHeight(),
794 c.requested.w, c.requested.h,
795 c.requested.crop.left,
796 c.requested.crop.top,
797 c.requested.crop.right,
798 c.requested.crop.bottom,
799 c.requested.crop.getWidth(),
800 c.requested.crop.getHeight(),
801 s.active.w, s.active.h,
802 s.active.crop.left,
803 s.active.crop.top,
804 s.active.crop.right,
805 s.active.crop.bottom,
806 s.active.crop.getWidth(),
807 s.active.crop.getHeight(),
808 s.requested.w, s.requested.h,
809 s.requested.crop.left,
810 s.requested.crop.top,
811 s.requested.crop.right,
812 s.requested.crop.bottom,
813 s.requested.crop.getWidth(),
814 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800815
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700816 // record the new size, form this point on, when the client request
817 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800818 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700819 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800820 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700821
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700822 if (!isFixedSize()) {
823
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700824 const bool resizePending = (c.requested.w != c.active.w) ||
825 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700826
827 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800828 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700829 // if we have a pending resize, unless we are in fixed-size mode.
830 // the drawing state will be updated only once we receive a buffer
831 // with the correct size.
832 //
833 // in particular, we want to make sure the clip (which is part
834 // of the geometry state) is latched together with the size but is
835 // latched immediately when no resizing is involved.
836
837 flags |= eDontUpdateGeometryState;
838 }
839 }
840
Mathias Agopian13127d82013-03-05 17:47:11 -0800841 // always set active to requested, unless we're asked not to
842 // this is used by Layer, which special cases resizes.
843 if (flags & eDontUpdateGeometryState) {
844 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700845 Layer::State& editCurrentState(getCurrentState());
846 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800847 }
848
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700849 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800850 // invalidate and recompute the visible regions if needed
851 flags |= Layer::eVisibleRegion;
852 }
853
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700854 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800855 // invalidate and recompute the visible regions if needed
856 flags |= eVisibleRegion;
857 this->contentDirty = true;
858
859 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700860 const uint8_t type = c.transform.getType();
861 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800862 (type >= Transform::SCALE));
863 }
864
865 // Commit the transaction
866 commitTransaction();
867 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800868}
869
Mathias Agopian13127d82013-03-05 17:47:11 -0800870void Layer::commitTransaction() {
871 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700872}
873
Mathias Agopian13127d82013-03-05 17:47:11 -0800874uint32_t Layer::getTransactionFlags(uint32_t flags) {
875 return android_atomic_and(~flags, &mTransactionFlags) & flags;
876}
877
878uint32_t Layer::setTransactionFlags(uint32_t flags) {
879 return android_atomic_or(flags, &mTransactionFlags);
880}
881
882bool Layer::setPosition(float x, float y) {
883 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
884 return false;
885 mCurrentState.sequence++;
886 mCurrentState.transform.set(x, y);
887 setTransactionFlags(eTransactionNeeded);
888 return true;
889}
890bool Layer::setLayer(uint32_t z) {
891 if (mCurrentState.z == z)
892 return false;
893 mCurrentState.sequence++;
894 mCurrentState.z = z;
895 setTransactionFlags(eTransactionNeeded);
896 return true;
897}
898bool Layer::setSize(uint32_t w, uint32_t h) {
899 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
900 return false;
901 mCurrentState.requested.w = w;
902 mCurrentState.requested.h = h;
903 setTransactionFlags(eTransactionNeeded);
904 return true;
905}
906bool Layer::setAlpha(uint8_t alpha) {
907 if (mCurrentState.alpha == alpha)
908 return false;
909 mCurrentState.sequence++;
910 mCurrentState.alpha = alpha;
911 setTransactionFlags(eTransactionNeeded);
912 return true;
913}
914bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
915 mCurrentState.sequence++;
916 mCurrentState.transform.set(
917 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
918 setTransactionFlags(eTransactionNeeded);
919 return true;
920}
921bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700922 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800923 setTransactionFlags(eTransactionNeeded);
924 return true;
925}
926bool Layer::setFlags(uint8_t flags, uint8_t mask) {
927 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
928 if (mCurrentState.flags == newFlags)
929 return false;
930 mCurrentState.sequence++;
931 mCurrentState.flags = newFlags;
932 setTransactionFlags(eTransactionNeeded);
933 return true;
934}
935bool Layer::setCrop(const Rect& crop) {
936 if (mCurrentState.requested.crop == crop)
937 return false;
938 mCurrentState.sequence++;
939 mCurrentState.requested.crop = crop;
940 setTransactionFlags(eTransactionNeeded);
941 return true;
942}
943
944bool Layer::setLayerStack(uint32_t layerStack) {
945 if (mCurrentState.layerStack == layerStack)
946 return false;
947 mCurrentState.sequence++;
948 mCurrentState.layerStack = layerStack;
949 setTransactionFlags(eTransactionNeeded);
950 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700951}
952
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800953// ----------------------------------------------------------------------------
954// pageflip handling...
955// ----------------------------------------------------------------------------
956
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800957bool Layer::onPreComposition() {
958 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800959 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800960}
961
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700962void Layer::onPostComposition() {
963 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800964 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800965 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
966
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800967 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800968 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800969 mFrameTracker.setFrameReadyFence(frameReadyFence);
970 } else {
971 // There was no fence for this frame, so assume that it was ready
972 // to be presented at the desired present time.
973 mFrameTracker.setFrameReadyTime(desiredPresentTime);
974 }
975
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700976 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800977 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800978 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800979 mFrameTracker.setActualPresentFence(presentFence);
980 } else {
981 // The HWC doesn't support present fences, so use the refresh
982 // timestamp instead.
983 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
984 mFrameTracker.setActualPresentTime(presentTime);
985 }
986
987 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700988 mFrameLatencyNeeded = false;
989 }
990}
991
Mathias Agopianda27af92012-09-13 18:17:13 -0700992bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800993 const Layer::State& s(mDrawingState);
994 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +0900995 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700996}
997
Mathias Agopian4fec8732012-06-29 14:12:52 -0700998Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800999{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001000 ATRACE_CALL();
1001
Jesse Hall399184a2014-03-03 15:42:54 -08001002 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1003 // mSidebandStreamChanged was true
1004 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
1005 }
1006
Mathias Agopian4fec8732012-06-29 14:12:52 -07001007 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001008 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001009
1010 // if we've already called updateTexImage() without going through
1011 // a composition step, we have to skip this layer at this point
1012 // because we cannot call updateTeximage() without a corresponding
1013 // compositionComplete() call.
1014 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001015 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001016 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001017 }
1018
Jamie Gennis351a5132011-09-14 18:23:37 -07001019 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001020 const State& s(getDrawingState());
1021 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001022 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001023
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001024 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001025 Layer::State& front;
1026 Layer::State& current;
1027 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001028 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001029 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001030 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001031 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001032 recomputeVisibleRegions(recomputeVisibleRegions),
1033 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001034 }
1035
1036 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001037 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001038 if (buf == NULL) {
1039 return false;
1040 }
1041
1042 uint32_t bufWidth = buf->getWidth();
1043 uint32_t bufHeight = buf->getHeight();
1044
1045 // check that we received a buffer of the right size
1046 // (Take the buffer's orientation into account)
1047 if (item.mTransform & Transform::ROT_90) {
1048 swap(bufWidth, bufHeight);
1049 }
1050
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001051 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1052 if (front.active != front.requested) {
1053
1054 if (isFixedSize ||
1055 (bufWidth == front.requested.w &&
1056 bufHeight == front.requested.h))
1057 {
1058 // Here we pretend the transaction happened by updating the
1059 // current and drawing states. Drawing state is only accessed
1060 // in this thread, no need to have it locked
1061 front.active = front.requested;
1062
1063 // We also need to update the current state so that
1064 // we don't end-up overwriting the drawing state with
1065 // this stale current state during the next transaction
1066 //
1067 // NOTE: We don't need to hold the transaction lock here
1068 // because State::active is only accessed from this thread.
1069 current.active = front.active;
1070
1071 // recompute visible region
1072 recomputeVisibleRegions = true;
1073 }
1074
1075 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001076 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001077 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1078 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001079 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001080 front.active.w, front.active.h,
1081 front.active.crop.left,
1082 front.active.crop.top,
1083 front.active.crop.right,
1084 front.active.crop.bottom,
1085 front.active.crop.getWidth(),
1086 front.active.crop.getHeight(),
1087 front.requested.w, front.requested.h,
1088 front.requested.crop.left,
1089 front.requested.crop.top,
1090 front.requested.crop.right,
1091 front.requested.crop.bottom,
1092 front.requested.crop.getWidth(),
1093 front.requested.crop.getHeight());
1094 }
1095
Ruben Brunk1681d952014-06-27 15:51:55 -07001096 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001097 if (front.active.w != bufWidth ||
1098 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001099 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001100 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1101 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001102 return true;
1103 }
1104 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001105
1106 // if the transparent region has changed (this test is
1107 // conservative, but that's fine, worst case we're doing
1108 // a bit of extra work), we latch the new one and we
1109 // trigger a visible-region recompute.
1110 if (!front.activeTransparentRegion.isTriviallyEqual(
1111 front.requestedTransparentRegion)) {
1112 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001113
1114 // We also need to update the current state so that
1115 // we don't end-up overwriting the drawing state with
1116 // this stale current state during the next transaction
1117 //
1118 // NOTE: We don't need to hold the transaction lock here
1119 // because State::active is only accessed from this thread.
1120 current.activeTransparentRegion = front.activeTransparentRegion;
1121
1122 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001123 recomputeVisibleRegions = true;
1124 }
1125
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001126 return false;
1127 }
1128 };
1129
Ruben Brunk1681d952014-06-27 15:51:55 -07001130 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1131 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001132
Andy McFadden41d67d72014-04-25 16:58:34 -07001133 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1134 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001135 if (updateResult == BufferQueue::PRESENT_LATER) {
1136 // Producer doesn't want buffer to be displayed yet. Signal a
1137 // layer update so we check again at the next opportunity.
1138 mFlinger->signalLayerUpdate();
1139 return outDirtyRegion;
1140 }
1141
1142 // Decrement the queued-frames count. Signal another event if we
1143 // have more frames pending.
1144 if (android_atomic_dec(&mQueuedFrames) > 1) {
1145 mFlinger->signalLayerUpdate();
1146 }
1147
1148 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001149 // something happened!
1150 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001151 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001152 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001153
Jamie Gennis351a5132011-09-14 18:23:37 -07001154 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001155 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001156 if (mActiveBuffer == NULL) {
1157 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001158 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001159 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001160
Mathias Agopian4824d402012-06-04 18:16:30 -07001161 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001162 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001163 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001164 // the first time we receive a buffer, we need to trigger a
1165 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001166 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001167 }
1168
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001169 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1170 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1171 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001172 if ((crop != mCurrentCrop) ||
1173 (transform != mCurrentTransform) ||
1174 (scalingMode != mCurrentScalingMode))
1175 {
1176 mCurrentCrop = crop;
1177 mCurrentTransform = transform;
1178 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001179 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001180 }
1181
1182 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001183 uint32_t bufWidth = mActiveBuffer->getWidth();
1184 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001185 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1186 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001187 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001188 }
1189 }
1190
1191 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001192 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001193 recomputeVisibleRegions = true;
1194 }
1195
Mathias Agopian4fec8732012-06-29 14:12:52 -07001196 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001197 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001198
1199 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001200 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001201 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001202 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001203}
1204
Mathias Agopiana67932f2011-04-20 14:20:59 -07001205uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001206{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001207 // TODO: should we do something special if mSecure is set?
1208 if (mProtectedByApp) {
1209 // need a hardware-protected path to external video sink
1210 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001211 }
Riley Andrews03414a12014-07-01 14:22:59 -07001212 if (mPotentialCursor) {
1213 usage |= GraphicBuffer::USAGE_CURSOR;
1214 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001215 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001216 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001217}
1218
Mathias Agopian84300952012-11-21 16:02:13 -08001219void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001220 uint32_t orientation = 0;
1221 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001222 // The transform hint is used to improve performance, but we can
1223 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001224 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001225 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001226 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001227 if (orientation & Transform::ROT_INVALID) {
1228 orientation = 0;
1229 }
1230 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001231 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001232}
1233
Mathias Agopian13127d82013-03-05 17:47:11 -08001234// ----------------------------------------------------------------------------
1235// debugging
1236// ----------------------------------------------------------------------------
1237
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001238void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001239{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001240 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001241
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001242 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001243 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001244 "+ %s %p (%s)\n",
1245 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001246 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001247
Mathias Agopian2ca79392013-04-02 18:30:32 -07001248 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001249 visibleRegion.dump(result, "visibleRegion");
1250 sp<Client> client(mClientRef.promote());
1251
Mathias Agopian74d211a2013-04-22 16:55:35 +02001252 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001253 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1254 "isOpaque=%1d, invalidate=%1d, "
1255 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1256 " client=%p\n",
1257 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1258 s.active.crop.left, s.active.crop.top,
1259 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001260 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001261 s.alpha, s.flags,
1262 s.transform[0][0], s.transform[0][1],
1263 s.transform[1][0], s.transform[1][1],
1264 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001265
1266 sp<const GraphicBuffer> buf0(mActiveBuffer);
1267 uint32_t w0=0, h0=0, s0=0, f0=0;
1268 if (buf0 != 0) {
1269 w0 = buf0->getWidth();
1270 h0 = buf0->getHeight();
1271 s0 = buf0->getStride();
1272 f0 = buf0->format;
1273 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001274 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001275 " "
1276 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1277 " queued-frames=%d, mRefreshPending=%d\n",
1278 mFormat, w0, h0, s0,f0,
1279 mQueuedFrames, mRefreshPending);
1280
Mathias Agopian13127d82013-03-05 17:47:11 -08001281 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001282 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001283 }
1284}
1285
Svetoslavd85084b2014-03-20 10:28:31 -07001286void Layer::dumpFrameStats(String8& result) const {
1287 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001288}
1289
Svetoslavd85084b2014-03-20 10:28:31 -07001290void Layer::clearFrameStats() {
1291 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001292}
1293
Jamie Gennis6547ff42013-07-16 20:12:42 -07001294void Layer::logFrameStats() {
1295 mFrameTracker.logAndResetStats(mName);
1296}
1297
Svetoslavd85084b2014-03-20 10:28:31 -07001298void Layer::getFrameStats(FrameStats* outStats) const {
1299 mFrameTracker.getStats(outStats);
1300}
1301
Mathias Agopian13127d82013-03-05 17:47:11 -08001302// ---------------------------------------------------------------------------
1303
1304Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1305 const sp<Layer>& layer)
1306 : mFlinger(flinger), mLayer(layer) {
1307}
1308
1309Layer::LayerCleaner::~LayerCleaner() {
1310 // destroy client resources
1311 mFlinger->onLayerDestroyed(mLayer);
1312}
1313
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001314// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001315}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001316
1317#if defined(__gl_h_)
1318#error "don't include gl/gl.h in this file"
1319#endif
1320
1321#if defined(__gl2_h_)
1322#error "don't include gl2/gl2.h in this file"
1323#endif