blob: cf4979809b90de1b1e44b1b28c34f9ea85c8e52b [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;
Michael Lentinef7551402014-08-18 16:35:43 -0700326 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
327 /*
328 * the code below applies the display's inverse transform to the buffer
329 */
330 uint32_t invTransformOrient = hw->getOrientationTransform();
331 // calculate the inverse transform
332 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
333 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
334 NATIVE_WINDOW_TRANSFORM_FLIP_H;
335 }
336 // and apply to the current transform
337 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
338 }
339
Mathias Agopian13127d82013-03-05 17:47:11 -0800340 int winWidth = s.active.w;
341 int winHeight = s.active.h;
342 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
343 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
344 NATIVE_WINDOW_TRANSFORM_FLIP_H;
345 winWidth = s.active.h;
346 winHeight = s.active.w;
347 }
348 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700349 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800350
Mathias Agopian6b442672013-07-09 21:24:52 -0700351 // below, crop is intersected with winCrop expressed in crop's coordinate space
352 float xScale = crop.getWidth() / float(winWidth);
353 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800354
Michael Lentinef7551402014-08-18 16:35:43 -0700355 float insetL = winCrop.left * xScale;
356 float insetT = winCrop.top * yScale;
357 float insetR = (winWidth - winCrop.right ) * xScale;
358 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800359
360 crop.left += insetL;
361 crop.top += insetT;
362 crop.right -= insetR;
363 crop.bottom -= insetB;
364 }
365 return crop;
366}
367
Mathias Agopian4fec8732012-06-29 14:12:52 -0700368void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700369 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700370 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700371{
Mathias Agopian13127d82013-03-05 17:47:11 -0800372 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700373
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700374 // enable this layer
375 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700376
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700377 if (isSecure() && !hw->isSecure()) {
378 layer.setSkip(true);
379 }
380
Mathias Agopian13127d82013-03-05 17:47:11 -0800381 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700382 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800383 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800384 layer.setBlending(mPremultipliedAlpha ?
385 HWC_BLENDING_PREMULT :
386 HWC_BLENDING_COVERAGE);
387 }
388
389 // apply the layer's transform, followed by the display's global transform
390 // here we're guaranteed that the layer's transform preserves rects
391 Rect frame(s.transform.transform(computeBounds()));
392 frame.intersect(hw->getViewport(), &frame);
393 const Transform& tr(hw->getTransform());
394 layer.setFrame(tr.transform(frame));
395 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800396 layer.setPlaneAlpha(s.alpha);
397
Mathias Agopian29a367b2011-07-12 14:51:45 -0700398 /*
399 * Transformations are applied in this order:
400 * 1) buffer orientation/flip/mirror
401 * 2) state transformation (window manager)
402 * 3) layer orientation (screen orientation)
403 * (NOTE: the matrices are multiplied in reverse order)
404 */
405
406 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700407 Transform transform(tr * s.transform * bufferOrientation);
408
409 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
410 /*
411 * the code below applies the display's inverse transform to the buffer
412 */
413 uint32_t invTransform = hw->getOrientationTransform();
414 // calculate the inverse transform
415 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
416 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
417 NATIVE_WINDOW_TRANSFORM_FLIP_H;
418 }
419 // and apply to the current transform
420 transform = transform * Transform(invTransform);
421 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700422
423 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800424 const uint32_t orientation = transform.getOrientation();
425 if (orientation & Transform::ROT_INVALID) {
426 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700427 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700428 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800429 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700430 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700431}
432
Mathias Agopian42977342012-08-05 00:40:46 -0700433void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700434 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800435 // we have to set the visible region on every frame because
436 // we currently free it during onLayerDisplayed(), which is called
437 // after HWComposer::commit() -- every frame.
438 // Apply this display's projection's viewport to the visible region
439 // before giving it to the HWC HAL.
440 const Transform& tr = hw->getTransform();
441 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
442 layer.setVisibleRegionScreen(visible);
443
Jesse Hall399184a2014-03-03 15:42:54 -0800444 if (mSidebandStream.get()) {
445 layer.setSidebandStream(mSidebandStream);
446 } else {
447 // NOTE: buffer can be NULL if the client never drew into this
448 // layer yet, or if we ran out of memory
449 layer.setBuffer(mActiveBuffer);
450 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700451}
Jesse Halldc5b4852012-06-29 15:21:18 -0700452
Dan Stozac7014012014-02-14 15:03:43 -0800453void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700454 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700455 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700456
457 // TODO: there is a possible optimization here: we only need to set the
458 // acquire fence the first time a new buffer is acquired on EACH display.
459
Riley Andrews03414a12014-07-01 14:22:59 -0700460 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800461 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800462 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700463 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700464 if (fenceFd == -1) {
465 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
466 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700467 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700468 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700469 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700470}
471
Riley Andrews03414a12014-07-01 14:22:59 -0700472Rect Layer::getPosition(
473 const sp<const DisplayDevice>& hw)
474{
475 // this gives us only the "orientation" component of the transform
476 const State& s(getCurrentState());
477
478 // apply the layer's transform, followed by the display's global transform
479 // here we're guaranteed that the layer's transform preserves rects
480 Rect win(s.active.w, s.active.h);
481 if (!s.active.crop.isEmpty()) {
482 win.intersect(s.active.crop, &win);
483 }
484 // subtract the transparent region and snap to the bounds
485 Rect bounds = reduce(win, s.activeTransparentRegion);
486 Rect frame(s.transform.transform(bounds));
487 frame.intersect(hw->getViewport(), &frame);
488 const Transform& tr(hw->getTransform());
489 return Rect(tr.transform(frame));
490}
491
Mathias Agopian13127d82013-03-05 17:47:11 -0800492// ---------------------------------------------------------------------------
493// drawing...
494// ---------------------------------------------------------------------------
495
496void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800497 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800498}
499
Dan Stozac7014012014-02-14 15:03:43 -0800500void Layer::draw(const sp<const DisplayDevice>& hw,
501 bool useIdentityTransform) const {
502 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800503}
504
Dan Stozac7014012014-02-14 15:03:43 -0800505void Layer::draw(const sp<const DisplayDevice>& hw) const {
506 onDraw(hw, Region(hw->bounds()), false);
507}
508
509void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
510 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800511{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800512 ATRACE_CALL();
513
Mathias Agopiana67932f2011-04-20 14:20:59 -0700514 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800515 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700516 // in fact never been drawn into. This happens frequently with
517 // SurfaceView because the WindowManager can't know when the client
518 // has drawn the first time.
519
520 // If there is nothing under us, we paint the screen in black, otherwise
521 // we just skip this update.
522
523 // figure out if there is something below us
524 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700525 const SurfaceFlinger::LayerVector& drawingLayers(
526 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700527 const size_t count = drawingLayers.size();
528 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800529 const sp<Layer>& layer(drawingLayers[i]);
530 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700531 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700532 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700533 }
534 // if not everything below us is covered, we plug the holes!
535 Region holes(clip.subtract(under));
536 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700537 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700538 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800539 return;
540 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700541
Andy McFadden97eba892012-12-11 15:21:45 -0800542 // Bind the current buffer to the GL texture, and wait for it to be
543 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800544 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
545 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800546 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700547 // Go ahead and draw the buffer anyway; no matter what we do the screen
548 // is probably going to have something visibly wrong.
549 }
550
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700551 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
552
Mathias Agopian875d8e12013-06-07 15:35:48 -0700553 RenderEngine& engine(mFlinger->getRenderEngine());
554
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700555 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700556 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700557 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700558
559 // Query the texture matrix given our current filtering mode.
560 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800561 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
562 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700563
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700564 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
565
566 /*
567 * the code below applies the display's inverse transform to the texture transform
568 */
569
570 // create a 4x4 transform matrix from the display transform flags
571 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
572 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
573 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
574
575 mat4 tr;
576 uint32_t transform = hw->getOrientationTransform();
577 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
578 tr = tr * rot90;
579 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
580 tr = tr * flipH;
581 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
582 tr = tr * flipV;
583
584 // calculate the inverse
585 tr = inverse(tr);
586
587 // and finally apply it to the original texture matrix
588 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
589 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
590 }
591
Jamie Genniscbb1a952012-05-08 17:05:52 -0700592 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700593 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
594 mTexture.setFiltering(useFiltering);
595 mTexture.setMatrix(textureMatrix);
596
597 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700598 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700599 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700600 }
Dan Stozac7014012014-02-14 15:03:43 -0800601 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700602 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800603}
604
Mathias Agopian13127d82013-03-05 17:47:11 -0800605
Dan Stozac7014012014-02-14 15:03:43 -0800606void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
607 const Region& /* clip */, float red, float green, float blue,
608 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800609{
Mathias Agopian19733a32013-08-28 18:13:56 -0700610 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800611 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700612 engine.setupFillWithColor(red, green, blue, alpha);
613 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800614}
615
616void Layer::clearWithOpenGL(
617 const sp<const DisplayDevice>& hw, const Region& clip) const {
618 clearWithOpenGL(hw, clip, 0,0,0,0);
619}
620
Dan Stozac7014012014-02-14 15:03:43 -0800621void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
622 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800623 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700624 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800625
Dan Stozac7014012014-02-14 15:03:43 -0800626 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800627
Mathias Agopian13127d82013-03-05 17:47:11 -0800628 /*
629 * NOTE: the way we compute the texture coordinates here produces
630 * different results than when we take the HWC path -- in the later case
631 * the "source crop" is rounded to texel boundaries.
632 * This can produce significantly different results when the texture
633 * is scaled by a large amount.
634 *
635 * The GL code below is more logical (imho), and the difference with
636 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700637 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800638 * GL composition when a buffer scaling is applied (maybe with some
639 * minimal value)? Or, we could make GL behave like HWC -- but this feel
640 * like more of a hack.
641 */
642 const Rect win(computeBounds());
643
Mathias Agopian3f844832013-08-07 21:24:32 -0700644 float left = float(win.left) / float(s.active.w);
645 float top = float(win.top) / float(s.active.h);
646 float right = float(win.right) / float(s.active.w);
647 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800648
Mathias Agopian875d8e12013-06-07 15:35:48 -0700649 // TODO: we probably want to generate the texture coords with the mesh
650 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700651 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
652 texCoords[0] = vec2(left, 1.0f - top);
653 texCoords[1] = vec2(left, 1.0f - bottom);
654 texCoords[2] = vec2(right, 1.0f - bottom);
655 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800656
Mathias Agopian875d8e12013-06-07 15:35:48 -0700657 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800658 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700659 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700660 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800661}
662
Ruben Brunk1681d952014-06-27 15:51:55 -0700663uint32_t Layer::getProducerStickyTransform() const {
664 int producerStickyTransform = 0;
665 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
666 if (ret != OK) {
667 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
668 strerror(-ret), ret);
669 return 0;
670 }
671 return static_cast<uint32_t>(producerStickyTransform);
672}
673
Mathias Agopian13127d82013-03-05 17:47:11 -0800674void Layer::setFiltering(bool filtering) {
675 mFiltering = filtering;
676}
677
678bool Layer::getFiltering() const {
679 return mFiltering;
680}
681
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800682// As documented in libhardware header, formats in the range
683// 0x100 - 0x1FF are specific to the HAL implementation, and
684// are known to have no alpha channel
685// TODO: move definition for device-specific range into
686// hardware.h, instead of using hard-coded values here.
687#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
688
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700689bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700690 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
691 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800692 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700693 switch (format) {
694 case HAL_PIXEL_FORMAT_RGBA_8888:
695 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700696 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700697 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700698 }
699 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700700 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800701}
702
Mathias Agopian13127d82013-03-05 17:47:11 -0800703// ----------------------------------------------------------------------------
704// local state
705// ----------------------------------------------------------------------------
706
Dan Stozac7014012014-02-14 15:03:43 -0800707void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
708 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800709{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700710 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800711 const Transform tr(useIdentityTransform ?
712 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800713 const uint32_t hw_h = hw->getHeight();
714 Rect win(s.active.w, s.active.h);
715 if (!s.active.crop.isEmpty()) {
716 win.intersect(s.active.crop, &win);
717 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700718 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700719 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700720
Mathias Agopianff2ed702013-09-01 21:36:12 -0700721 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
722 position[0] = tr.transform(win.left, win.top);
723 position[1] = tr.transform(win.left, win.bottom);
724 position[2] = tr.transform(win.right, win.bottom);
725 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700726 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700727 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800728 }
729}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800730
Andy McFadden4125a4f2014-01-29 17:17:11 -0800731bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700732{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700733 // if we don't have a buffer yet, we're translucent regardless of the
734 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700735 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700736 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700737 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700738
739 // if the layer has the opaque flag, then we're always opaque,
740 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800741 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700742}
743
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800744bool Layer::isProtected() const
745{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700746 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800747 return (activeBuffer != 0) &&
748 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
749}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700750
Mathias Agopian13127d82013-03-05 17:47:11 -0800751bool Layer::isFixedSize() const {
752 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
753}
754
755bool Layer::isCropped() const {
756 return !mCurrentCrop.isEmpty();
757}
758
759bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
760 return mNeedsFiltering || hw->needsFiltering();
761}
762
763void Layer::setVisibleRegion(const Region& visibleRegion) {
764 // always called from main thread
765 this->visibleRegion = visibleRegion;
766}
767
768void Layer::setCoveredRegion(const Region& coveredRegion) {
769 // always called from main thread
770 this->coveredRegion = coveredRegion;
771}
772
773void Layer::setVisibleNonTransparentRegion(const Region&
774 setVisibleNonTransparentRegion) {
775 // always called from main thread
776 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
777}
778
779// ----------------------------------------------------------------------------
780// transaction
781// ----------------------------------------------------------------------------
782
783uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800784 ATRACE_CALL();
785
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700786 const Layer::State& s(getDrawingState());
787 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800788
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700789 const bool sizeChanged = (c.requested.w != s.requested.w) ||
790 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700791
792 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700793 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000794 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700795 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700796 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
797 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
798 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
799 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700800 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
801 c.active.w, c.active.h,
802 c.active.crop.left,
803 c.active.crop.top,
804 c.active.crop.right,
805 c.active.crop.bottom,
806 c.active.crop.getWidth(),
807 c.active.crop.getHeight(),
808 c.requested.w, c.requested.h,
809 c.requested.crop.left,
810 c.requested.crop.top,
811 c.requested.crop.right,
812 c.requested.crop.bottom,
813 c.requested.crop.getWidth(),
814 c.requested.crop.getHeight(),
815 s.active.w, s.active.h,
816 s.active.crop.left,
817 s.active.crop.top,
818 s.active.crop.right,
819 s.active.crop.bottom,
820 s.active.crop.getWidth(),
821 s.active.crop.getHeight(),
822 s.requested.w, s.requested.h,
823 s.requested.crop.left,
824 s.requested.crop.top,
825 s.requested.crop.right,
826 s.requested.crop.bottom,
827 s.requested.crop.getWidth(),
828 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800829
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700830 // record the new size, form this point on, when the client request
831 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800832 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700833 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800834 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700835
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700836 if (!isFixedSize()) {
837
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700838 const bool resizePending = (c.requested.w != c.active.w) ||
839 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700840
841 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800842 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700843 // if we have a pending resize, unless we are in fixed-size mode.
844 // the drawing state will be updated only once we receive a buffer
845 // with the correct size.
846 //
847 // in particular, we want to make sure the clip (which is part
848 // of the geometry state) is latched together with the size but is
849 // latched immediately when no resizing is involved.
850
851 flags |= eDontUpdateGeometryState;
852 }
853 }
854
Mathias Agopian13127d82013-03-05 17:47:11 -0800855 // always set active to requested, unless we're asked not to
856 // this is used by Layer, which special cases resizes.
857 if (flags & eDontUpdateGeometryState) {
858 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700859 Layer::State& editCurrentState(getCurrentState());
860 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800861 }
862
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700863 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800864 // invalidate and recompute the visible regions if needed
865 flags |= Layer::eVisibleRegion;
866 }
867
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700868 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800869 // invalidate and recompute the visible regions if needed
870 flags |= eVisibleRegion;
871 this->contentDirty = true;
872
873 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700874 const uint8_t type = c.transform.getType();
875 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800876 (type >= Transform::SCALE));
877 }
878
879 // Commit the transaction
880 commitTransaction();
881 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800882}
883
Mathias Agopian13127d82013-03-05 17:47:11 -0800884void Layer::commitTransaction() {
885 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700886}
887
Mathias Agopian13127d82013-03-05 17:47:11 -0800888uint32_t Layer::getTransactionFlags(uint32_t flags) {
889 return android_atomic_and(~flags, &mTransactionFlags) & flags;
890}
891
892uint32_t Layer::setTransactionFlags(uint32_t flags) {
893 return android_atomic_or(flags, &mTransactionFlags);
894}
895
896bool Layer::setPosition(float x, float y) {
897 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
898 return false;
899 mCurrentState.sequence++;
900 mCurrentState.transform.set(x, y);
901 setTransactionFlags(eTransactionNeeded);
902 return true;
903}
904bool Layer::setLayer(uint32_t z) {
905 if (mCurrentState.z == z)
906 return false;
907 mCurrentState.sequence++;
908 mCurrentState.z = z;
909 setTransactionFlags(eTransactionNeeded);
910 return true;
911}
912bool Layer::setSize(uint32_t w, uint32_t h) {
913 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
914 return false;
915 mCurrentState.requested.w = w;
916 mCurrentState.requested.h = h;
917 setTransactionFlags(eTransactionNeeded);
918 return true;
919}
920bool Layer::setAlpha(uint8_t alpha) {
921 if (mCurrentState.alpha == alpha)
922 return false;
923 mCurrentState.sequence++;
924 mCurrentState.alpha = alpha;
925 setTransactionFlags(eTransactionNeeded);
926 return true;
927}
928bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
929 mCurrentState.sequence++;
930 mCurrentState.transform.set(
931 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
932 setTransactionFlags(eTransactionNeeded);
933 return true;
934}
935bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700936 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800937 setTransactionFlags(eTransactionNeeded);
938 return true;
939}
940bool Layer::setFlags(uint8_t flags, uint8_t mask) {
941 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
942 if (mCurrentState.flags == newFlags)
943 return false;
944 mCurrentState.sequence++;
945 mCurrentState.flags = newFlags;
946 setTransactionFlags(eTransactionNeeded);
947 return true;
948}
949bool Layer::setCrop(const Rect& crop) {
950 if (mCurrentState.requested.crop == crop)
951 return false;
952 mCurrentState.sequence++;
953 mCurrentState.requested.crop = crop;
954 setTransactionFlags(eTransactionNeeded);
955 return true;
956}
957
958bool Layer::setLayerStack(uint32_t layerStack) {
959 if (mCurrentState.layerStack == layerStack)
960 return false;
961 mCurrentState.sequence++;
962 mCurrentState.layerStack = layerStack;
963 setTransactionFlags(eTransactionNeeded);
964 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700965}
966
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800967// ----------------------------------------------------------------------------
968// pageflip handling...
969// ----------------------------------------------------------------------------
970
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800971bool Layer::onPreComposition() {
972 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800973 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800974}
975
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700976void Layer::onPostComposition() {
977 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800978 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800979 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
980
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800981 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800982 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800983 mFrameTracker.setFrameReadyFence(frameReadyFence);
984 } else {
985 // There was no fence for this frame, so assume that it was ready
986 // to be presented at the desired present time.
987 mFrameTracker.setFrameReadyTime(desiredPresentTime);
988 }
989
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700990 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800991 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800992 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800993 mFrameTracker.setActualPresentFence(presentFence);
994 } else {
995 // The HWC doesn't support present fences, so use the refresh
996 // timestamp instead.
997 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
998 mFrameTracker.setActualPresentTime(presentTime);
999 }
1000
1001 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001002 mFrameLatencyNeeded = false;
1003 }
1004}
1005
Mathias Agopianda27af92012-09-13 18:17:13 -07001006bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001007 const Layer::State& s(mDrawingState);
1008 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001009 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001010}
1011
Mathias Agopian4fec8732012-06-29 14:12:52 -07001012Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001013{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001014 ATRACE_CALL();
1015
Jesse Hall399184a2014-03-03 15:42:54 -08001016 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1017 // mSidebandStreamChanged was true
1018 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
1019 }
1020
Mathias Agopian4fec8732012-06-29 14:12:52 -07001021 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001022 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001023
1024 // if we've already called updateTexImage() without going through
1025 // a composition step, we have to skip this layer at this point
1026 // because we cannot call updateTeximage() without a corresponding
1027 // compositionComplete() call.
1028 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001029 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001030 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001031 }
1032
Jamie Gennis351a5132011-09-14 18:23:37 -07001033 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001034 const State& s(getDrawingState());
1035 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001036 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001037
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001038 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001039 Layer::State& front;
1040 Layer::State& current;
1041 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001042 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001043 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001044 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001045 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001046 recomputeVisibleRegions(recomputeVisibleRegions),
1047 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001048 }
1049
1050 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001051 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001052 if (buf == NULL) {
1053 return false;
1054 }
1055
1056 uint32_t bufWidth = buf->getWidth();
1057 uint32_t bufHeight = buf->getHeight();
1058
1059 // check that we received a buffer of the right size
1060 // (Take the buffer's orientation into account)
1061 if (item.mTransform & Transform::ROT_90) {
1062 swap(bufWidth, bufHeight);
1063 }
1064
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001065 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1066 if (front.active != front.requested) {
1067
1068 if (isFixedSize ||
1069 (bufWidth == front.requested.w &&
1070 bufHeight == front.requested.h))
1071 {
1072 // Here we pretend the transaction happened by updating the
1073 // current and drawing states. Drawing state is only accessed
1074 // in this thread, no need to have it locked
1075 front.active = front.requested;
1076
1077 // We also need to update the current state so that
1078 // we don't end-up overwriting the drawing state with
1079 // this stale current state during the next transaction
1080 //
1081 // NOTE: We don't need to hold the transaction lock here
1082 // because State::active is only accessed from this thread.
1083 current.active = front.active;
1084
1085 // recompute visible region
1086 recomputeVisibleRegions = true;
1087 }
1088
1089 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001090 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001091 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1092 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001093 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001094 front.active.w, front.active.h,
1095 front.active.crop.left,
1096 front.active.crop.top,
1097 front.active.crop.right,
1098 front.active.crop.bottom,
1099 front.active.crop.getWidth(),
1100 front.active.crop.getHeight(),
1101 front.requested.w, front.requested.h,
1102 front.requested.crop.left,
1103 front.requested.crop.top,
1104 front.requested.crop.right,
1105 front.requested.crop.bottom,
1106 front.requested.crop.getWidth(),
1107 front.requested.crop.getHeight());
1108 }
1109
Ruben Brunk1681d952014-06-27 15:51:55 -07001110 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001111 if (front.active.w != bufWidth ||
1112 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001113 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001114 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1115 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001116 return true;
1117 }
1118 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001119
1120 // if the transparent region has changed (this test is
1121 // conservative, but that's fine, worst case we're doing
1122 // a bit of extra work), we latch the new one and we
1123 // trigger a visible-region recompute.
1124 if (!front.activeTransparentRegion.isTriviallyEqual(
1125 front.requestedTransparentRegion)) {
1126 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001127
1128 // We also need to update the current state so that
1129 // we don't end-up overwriting the drawing state with
1130 // this stale current state during the next transaction
1131 //
1132 // NOTE: We don't need to hold the transaction lock here
1133 // because State::active is only accessed from this thread.
1134 current.activeTransparentRegion = front.activeTransparentRegion;
1135
1136 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001137 recomputeVisibleRegions = true;
1138 }
1139
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001140 return false;
1141 }
1142 };
1143
Ruben Brunk1681d952014-06-27 15:51:55 -07001144 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1145 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001146
Andy McFadden41d67d72014-04-25 16:58:34 -07001147 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1148 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001149 if (updateResult == BufferQueue::PRESENT_LATER) {
1150 // Producer doesn't want buffer to be displayed yet. Signal a
1151 // layer update so we check again at the next opportunity.
1152 mFlinger->signalLayerUpdate();
1153 return outDirtyRegion;
1154 }
1155
1156 // Decrement the queued-frames count. Signal another event if we
1157 // have more frames pending.
1158 if (android_atomic_dec(&mQueuedFrames) > 1) {
1159 mFlinger->signalLayerUpdate();
1160 }
1161
1162 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001163 // something happened!
1164 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001165 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001166 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001167
Jamie Gennis351a5132011-09-14 18:23:37 -07001168 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001169 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001170 if (mActiveBuffer == NULL) {
1171 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001172 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001173 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001174
Mathias Agopian4824d402012-06-04 18:16:30 -07001175 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001176 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001177 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001178 // the first time we receive a buffer, we need to trigger a
1179 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001180 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001181 }
1182
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001183 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1184 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1185 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001186 if ((crop != mCurrentCrop) ||
1187 (transform != mCurrentTransform) ||
1188 (scalingMode != mCurrentScalingMode))
1189 {
1190 mCurrentCrop = crop;
1191 mCurrentTransform = transform;
1192 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001193 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001194 }
1195
1196 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001197 uint32_t bufWidth = mActiveBuffer->getWidth();
1198 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001199 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1200 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001201 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001202 }
1203 }
1204
1205 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001206 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001207 recomputeVisibleRegions = true;
1208 }
1209
Mathias Agopian4fec8732012-06-29 14:12:52 -07001210 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001211 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001212
1213 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001214 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001215 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001216 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001217}
1218
Mathias Agopiana67932f2011-04-20 14:20:59 -07001219uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001220{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001221 // TODO: should we do something special if mSecure is set?
1222 if (mProtectedByApp) {
1223 // need a hardware-protected path to external video sink
1224 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001225 }
Riley Andrews03414a12014-07-01 14:22:59 -07001226 if (mPotentialCursor) {
1227 usage |= GraphicBuffer::USAGE_CURSOR;
1228 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001229 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001230 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001231}
1232
Mathias Agopian84300952012-11-21 16:02:13 -08001233void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001234 uint32_t orientation = 0;
1235 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001236 // The transform hint is used to improve performance, but we can
1237 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001238 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001239 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001240 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001241 if (orientation & Transform::ROT_INVALID) {
1242 orientation = 0;
1243 }
1244 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001245 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001246}
1247
Mathias Agopian13127d82013-03-05 17:47:11 -08001248// ----------------------------------------------------------------------------
1249// debugging
1250// ----------------------------------------------------------------------------
1251
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001252void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001253{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001254 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001255
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001256 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001257 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001258 "+ %s %p (%s)\n",
1259 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001260 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001261
Mathias Agopian2ca79392013-04-02 18:30:32 -07001262 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001263 visibleRegion.dump(result, "visibleRegion");
1264 sp<Client> client(mClientRef.promote());
1265
Mathias Agopian74d211a2013-04-22 16:55:35 +02001266 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001267 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1268 "isOpaque=%1d, invalidate=%1d, "
1269 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1270 " client=%p\n",
1271 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1272 s.active.crop.left, s.active.crop.top,
1273 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001274 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001275 s.alpha, s.flags,
1276 s.transform[0][0], s.transform[0][1],
1277 s.transform[1][0], s.transform[1][1],
1278 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001279
1280 sp<const GraphicBuffer> buf0(mActiveBuffer);
1281 uint32_t w0=0, h0=0, s0=0, f0=0;
1282 if (buf0 != 0) {
1283 w0 = buf0->getWidth();
1284 h0 = buf0->getHeight();
1285 s0 = buf0->getStride();
1286 f0 = buf0->format;
1287 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001288 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001289 " "
1290 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1291 " queued-frames=%d, mRefreshPending=%d\n",
1292 mFormat, w0, h0, s0,f0,
1293 mQueuedFrames, mRefreshPending);
1294
Mathias Agopian13127d82013-03-05 17:47:11 -08001295 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001296 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001297 }
1298}
1299
Svetoslavd85084b2014-03-20 10:28:31 -07001300void Layer::dumpFrameStats(String8& result) const {
1301 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001302}
1303
Svetoslavd85084b2014-03-20 10:28:31 -07001304void Layer::clearFrameStats() {
1305 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001306}
1307
Jamie Gennis6547ff42013-07-16 20:12:42 -07001308void Layer::logFrameStats() {
1309 mFrameTracker.logAndResetStats(mName);
1310}
1311
Svetoslavd85084b2014-03-20 10:28:31 -07001312void Layer::getFrameStats(FrameStats* outStats) const {
1313 mFrameTracker.getStats(outStats);
1314}
1315
Mathias Agopian13127d82013-03-05 17:47:11 -08001316// ---------------------------------------------------------------------------
1317
1318Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1319 const sp<Layer>& layer)
1320 : mFlinger(flinger), mLayer(layer) {
1321}
1322
1323Layer::LayerCleaner::~LayerCleaner() {
1324 // destroy client resources
1325 mFlinger->onLayerDestroyed(mLayer);
1326}
1327
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001328// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001329}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001330
1331#if defined(__gl_h_)
1332#error "don't include gl/gl.h in this file"
1333#endif
1334
1335#if defined(__gl2_h_)
1336#error "don't include gl2/gl2.h in this file"
1337#endif