blob: 019d89223b75473dec826d911c7f0363874486b8 [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"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043#include "SurfaceFlinger.h"
Mathias Agopiana67932f2011-04-20 14:20:59 -070044#include "SurfaceTextureLayer.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),
82 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080083{
Mathias Agopiana67932f2011-04-20 14:20:59 -070084 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070085 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070086 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070087
88 uint32_t layerFlags = 0;
89 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080090 layerFlags |= layer_state_t::eLayerHidden;
91 if (flags & ISurfaceComposerClient::eOpaque)
92 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070093
94 if (flags & ISurfaceComposerClient::eNonPremultiplied)
95 mPremultipliedAlpha = false;
96
97 mName = name;
98
99 mCurrentState.active.w = w;
100 mCurrentState.active.h = h;
101 mCurrentState.active.crop.makeInvalid();
102 mCurrentState.z = 0;
103 mCurrentState.alpha = 0xFF;
104 mCurrentState.layerStack = 0;
105 mCurrentState.flags = layerFlags;
106 mCurrentState.sequence = 0;
107 mCurrentState.transform.set(0, 0);
108 mCurrentState.requested = mCurrentState.active;
109
110 // drawing state & current state are identical
111 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700112
113 nsecs_t displayPeriod =
114 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
115 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800116}
117
Mathias Agopian3f844832013-08-07 21:24:32 -0700118void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800119 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700120 mBufferQueue = new SurfaceTextureLayer(mFlinger);
Mathias Agopian3f844832013-08-07 21:24:32 -0700121 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800122 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800123 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700124 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800125
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700126#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
127#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800128 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700129#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800130 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800131#endif
Andy McFadden69052052012-09-14 16:10:11 -0700132
Mathias Agopian84300952012-11-21 16:02:13 -0800133 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
134 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700135}
136
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700137Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800138 sp<Client> c(mClientRef.promote());
139 if (c != 0) {
140 c->detachLayer(this);
141 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700142 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700143 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700144}
145
Mathias Agopian13127d82013-03-05 17:47:11 -0800146// ---------------------------------------------------------------------------
147// callbacks
148// ---------------------------------------------------------------------------
149
Dan Stozac7014012014-02-14 15:03:43 -0800150void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800151 HWComposer::HWCLayerInterface* layer) {
152 if (layer) {
153 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700154 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800155 }
156}
157
Igor Murashkina4a31492012-10-29 13:36:11 -0700158void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700159 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800160 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700161}
162
Jesse Hall399184a2014-03-03 15:42:54 -0800163void Layer::onSidebandStreamChanged() {
164 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
165 // mSidebandStreamChanged was false
166 mFlinger->signalLayerUpdate();
167 }
168}
169
Mathias Agopian67106042013-03-14 19:18:13 -0700170// called with SurfaceFlinger::mStateLock from the drawing thread after
171// the layer has been remove from the current state list (and just before
172// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800173void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800174 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700175}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700176
Mathias Agopian13127d82013-03-05 17:47:11 -0800177// ---------------------------------------------------------------------------
178// set-up
179// ---------------------------------------------------------------------------
180
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700181const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800182 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800183}
184
Mathias Agopianf9d93272009-06-19 17:00:27 -0700185status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800186 PixelFormat format, uint32_t flags)
187{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700188 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700189 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700190
191 // never allow a surface larger than what our underlying GL implementation
192 // can handle.
193 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800194 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700195 return BAD_VALUE;
196 }
197
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700198 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700199
Mathias Agopian3165cc22012-08-08 19:42:09 -0700200 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
201 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700202 mCurrentOpacity = getOpacityForFormat(format);
203
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800204 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
205 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
206 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700207
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800208 return NO_ERROR;
209}
210
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700211sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800212 Mutex::Autolock _l(mLock);
213
214 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700215 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800216
217 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700218
219 /*
220 * The layer handle is just a BBinder object passed to the client
221 * (remote process) -- we don't keep any reference on our side such that
222 * the dtor is called when the remote side let go of its reference.
223 *
224 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
225 * this layer when the handle is destroyed.
226 */
227
228 class Handle : public BBinder, public LayerCleaner {
229 wp<const Layer> mOwner;
230 public:
231 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
232 : LayerCleaner(flinger, layer), mOwner(layer) {
233 }
234 };
235
236 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800237}
238
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700239sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
240 return mBufferQueue;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700241}
242
Mathias Agopian13127d82013-03-05 17:47:11 -0800243// ---------------------------------------------------------------------------
244// h/w composer set-up
245// ---------------------------------------------------------------------------
246
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800247Rect Layer::getContentCrop() const {
248 // this is the crop rectangle that applies to the buffer
249 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700250 Rect crop;
251 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800252 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700253 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800254 } else if (mActiveBuffer != NULL) {
255 // otherwise we use the whole buffer
256 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700257 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800258 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700259 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700260 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700261 return crop;
262}
263
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700264static Rect reduce(const Rect& win, const Region& exclude) {
265 if (CC_LIKELY(exclude.isEmpty())) {
266 return win;
267 }
268 if (exclude.isRect()) {
269 return win.reduce(exclude.getBounds());
270 }
271 return Region(win).subtract(exclude).getBounds();
272}
273
Mathias Agopian13127d82013-03-05 17:47:11 -0800274Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700275 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800276 Rect win(s.active.w, s.active.h);
277 if (!s.active.crop.isEmpty()) {
278 win.intersect(s.active.crop, &win);
279 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700280 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700281 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800282}
283
Mathias Agopian6b442672013-07-09 21:24:52 -0700284FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800285 // the content crop is the area of the content that gets scaled to the
286 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700287 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800288
289 // the active.crop is the area of the window that gets cropped, but not
290 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700291 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800292
293 // apply the projection's clipping to the window crop in
294 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700295 // if there are no window scaling involved, this operation will map to full
296 // pixels in the buffer.
297 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
298 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700299
300 Rect activeCrop(s.active.w, s.active.h);
301 if (!s.active.crop.isEmpty()) {
302 activeCrop = s.active.crop;
303 }
304
305 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800306 activeCrop.intersect(hw->getViewport(), &activeCrop);
307 activeCrop = s.transform.inverse().transform(activeCrop);
308
309 // paranoia: make sure the window-crop is constrained in the
310 // window's bounds
311 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
312
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700313 // subtract the transparent region and snap to the bounds
314 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
315
Mathias Agopian13127d82013-03-05 17:47:11 -0800316 if (!activeCrop.isEmpty()) {
317 // Transform the window crop to match the buffer coordinate system,
318 // which means using the inverse of the current transform set on the
319 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700320 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800321 int winWidth = s.active.w;
322 int winHeight = s.active.h;
323 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
324 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
325 NATIVE_WINDOW_TRANSFORM_FLIP_H;
326 winWidth = s.active.h;
327 winHeight = s.active.w;
328 }
329 const Rect winCrop = activeCrop.transform(
330 invTransform, s.active.w, s.active.h);
331
Mathias Agopian6b442672013-07-09 21:24:52 -0700332 // below, crop is intersected with winCrop expressed in crop's coordinate space
333 float xScale = crop.getWidth() / float(winWidth);
334 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800335
Mathias Agopian6b442672013-07-09 21:24:52 -0700336 float insetL = winCrop.left * xScale;
337 float insetT = winCrop.top * yScale;
338 float insetR = (winWidth - winCrop.right ) * xScale;
339 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800340
341 crop.left += insetL;
342 crop.top += insetT;
343 crop.right -= insetR;
344 crop.bottom -= insetB;
345 }
346 return crop;
347}
348
Mathias Agopian4fec8732012-06-29 14:12:52 -0700349void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700350 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700351 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700352{
Mathias Agopian13127d82013-03-05 17:47:11 -0800353 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700354
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700355 // enable this layer
356 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700357
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700358 if (isSecure() && !hw->isSecure()) {
359 layer.setSkip(true);
360 }
361
Mathias Agopian13127d82013-03-05 17:47:11 -0800362 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700363 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800364 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800365 layer.setBlending(mPremultipliedAlpha ?
366 HWC_BLENDING_PREMULT :
367 HWC_BLENDING_COVERAGE);
368 }
369
370 // apply the layer's transform, followed by the display's global transform
371 // here we're guaranteed that the layer's transform preserves rects
372 Rect frame(s.transform.transform(computeBounds()));
373 frame.intersect(hw->getViewport(), &frame);
374 const Transform& tr(hw->getTransform());
375 layer.setFrame(tr.transform(frame));
376 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800377 layer.setPlaneAlpha(s.alpha);
378
Mathias Agopian29a367b2011-07-12 14:51:45 -0700379 /*
380 * Transformations are applied in this order:
381 * 1) buffer orientation/flip/mirror
382 * 2) state transformation (window manager)
383 * 3) layer orientation (screen orientation)
384 * (NOTE: the matrices are multiplied in reverse order)
385 */
386
387 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700388 Transform transform(tr * s.transform * bufferOrientation);
389
390 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
391 /*
392 * the code below applies the display's inverse transform to the buffer
393 */
394 uint32_t invTransform = hw->getOrientationTransform();
395 // calculate the inverse transform
396 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
397 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
398 NATIVE_WINDOW_TRANSFORM_FLIP_H;
399 }
400 // and apply to the current transform
401 transform = transform * Transform(invTransform);
402 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700403
404 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800405 const uint32_t orientation = transform.getOrientation();
406 if (orientation & Transform::ROT_INVALID) {
407 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700408 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700409 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800410 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700411 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700412}
413
Mathias Agopian42977342012-08-05 00:40:46 -0700414void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700415 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800416 // we have to set the visible region on every frame because
417 // we currently free it during onLayerDisplayed(), which is called
418 // after HWComposer::commit() -- every frame.
419 // Apply this display's projection's viewport to the visible region
420 // before giving it to the HWC HAL.
421 const Transform& tr = hw->getTransform();
422 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
423 layer.setVisibleRegionScreen(visible);
424
Jesse Hall399184a2014-03-03 15:42:54 -0800425 if (mSidebandStream.get()) {
426 layer.setSidebandStream(mSidebandStream);
427 } else {
428 // NOTE: buffer can be NULL if the client never drew into this
429 // layer yet, or if we ran out of memory
430 layer.setBuffer(mActiveBuffer);
431 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700432}
Jesse Halldc5b4852012-06-29 15:21:18 -0700433
Dan Stozac7014012014-02-14 15:03:43 -0800434void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700435 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700436 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700437
438 // TODO: there is a possible optimization here: we only need to set the
439 // acquire fence the first time a new buffer is acquired on EACH display.
440
441 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800442 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800443 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700444 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700445 if (fenceFd == -1) {
446 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
447 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700448 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700449 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700450 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700451}
452
Mathias Agopian13127d82013-03-05 17:47:11 -0800453// ---------------------------------------------------------------------------
454// drawing...
455// ---------------------------------------------------------------------------
456
457void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800458 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800459}
460
Dan Stozac7014012014-02-14 15:03:43 -0800461void Layer::draw(const sp<const DisplayDevice>& hw,
462 bool useIdentityTransform) const {
463 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800464}
465
Dan Stozac7014012014-02-14 15:03:43 -0800466void Layer::draw(const sp<const DisplayDevice>& hw) const {
467 onDraw(hw, Region(hw->bounds()), false);
468}
469
470void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
471 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800472{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800473 ATRACE_CALL();
474
Mathias Agopiana67932f2011-04-20 14:20:59 -0700475 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800476 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700477 // in fact never been drawn into. This happens frequently with
478 // SurfaceView because the WindowManager can't know when the client
479 // has drawn the first time.
480
481 // If there is nothing under us, we paint the screen in black, otherwise
482 // we just skip this update.
483
484 // figure out if there is something below us
485 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700486 const SurfaceFlinger::LayerVector& drawingLayers(
487 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700488 const size_t count = drawingLayers.size();
489 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800490 const sp<Layer>& layer(drawingLayers[i]);
491 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700492 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700493 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700494 }
495 // if not everything below us is covered, we plug the holes!
496 Region holes(clip.subtract(under));
497 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700498 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700499 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800500 return;
501 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700502
Andy McFadden97eba892012-12-11 15:21:45 -0800503 // Bind the current buffer to the GL texture, and wait for it to be
504 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800505 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
506 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800507 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700508 // Go ahead and draw the buffer anyway; no matter what we do the screen
509 // is probably going to have something visibly wrong.
510 }
511
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700512 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
513
Mathias Agopian875d8e12013-06-07 15:35:48 -0700514 RenderEngine& engine(mFlinger->getRenderEngine());
515
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700516 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700517 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700518 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700519
520 // Query the texture matrix given our current filtering mode.
521 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800522 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
523 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700524
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700525 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
526
527 /*
528 * the code below applies the display's inverse transform to the texture transform
529 */
530
531 // create a 4x4 transform matrix from the display transform flags
532 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
533 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
534 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
535
536 mat4 tr;
537 uint32_t transform = hw->getOrientationTransform();
538 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
539 tr = tr * rot90;
540 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
541 tr = tr * flipH;
542 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
543 tr = tr * flipV;
544
545 // calculate the inverse
546 tr = inverse(tr);
547
548 // and finally apply it to the original texture matrix
549 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
550 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
551 }
552
Jamie Genniscbb1a952012-05-08 17:05:52 -0700553 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700554 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
555 mTexture.setFiltering(useFiltering);
556 mTexture.setMatrix(textureMatrix);
557
558 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700559 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700560 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700561 }
Dan Stozac7014012014-02-14 15:03:43 -0800562 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700563 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800564}
565
Mathias Agopian13127d82013-03-05 17:47:11 -0800566
Dan Stozac7014012014-02-14 15:03:43 -0800567void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
568 const Region& /* clip */, float red, float green, float blue,
569 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800570{
Mathias Agopian19733a32013-08-28 18:13:56 -0700571 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800572 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700573 engine.setupFillWithColor(red, green, blue, alpha);
574 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800575}
576
577void Layer::clearWithOpenGL(
578 const sp<const DisplayDevice>& hw, const Region& clip) const {
579 clearWithOpenGL(hw, clip, 0,0,0,0);
580}
581
Dan Stozac7014012014-02-14 15:03:43 -0800582void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
583 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800584 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700585 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800586
Dan Stozac7014012014-02-14 15:03:43 -0800587 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800588
Mathias Agopian13127d82013-03-05 17:47:11 -0800589 /*
590 * NOTE: the way we compute the texture coordinates here produces
591 * different results than when we take the HWC path -- in the later case
592 * the "source crop" is rounded to texel boundaries.
593 * This can produce significantly different results when the texture
594 * is scaled by a large amount.
595 *
596 * The GL code below is more logical (imho), and the difference with
597 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700598 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800599 * GL composition when a buffer scaling is applied (maybe with some
600 * minimal value)? Or, we could make GL behave like HWC -- but this feel
601 * like more of a hack.
602 */
603 const Rect win(computeBounds());
604
Mathias Agopian3f844832013-08-07 21:24:32 -0700605 float left = float(win.left) / float(s.active.w);
606 float top = float(win.top) / float(s.active.h);
607 float right = float(win.right) / float(s.active.w);
608 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800609
Mathias Agopian875d8e12013-06-07 15:35:48 -0700610 // TODO: we probably want to generate the texture coords with the mesh
611 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700612 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
613 texCoords[0] = vec2(left, 1.0f - top);
614 texCoords[1] = vec2(left, 1.0f - bottom);
615 texCoords[2] = vec2(right, 1.0f - bottom);
616 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800617
Mathias Agopian875d8e12013-06-07 15:35:48 -0700618 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800619 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700620 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700621 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800622}
623
624void Layer::setFiltering(bool filtering) {
625 mFiltering = filtering;
626}
627
628bool Layer::getFiltering() const {
629 return mFiltering;
630}
631
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800632// As documented in libhardware header, formats in the range
633// 0x100 - 0x1FF are specific to the HAL implementation, and
634// are known to have no alpha channel
635// TODO: move definition for device-specific range into
636// hardware.h, instead of using hard-coded values here.
637#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
638
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700639bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700640 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
641 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800642 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700643 switch (format) {
644 case HAL_PIXEL_FORMAT_RGBA_8888:
645 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700646 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700647 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700648 }
649 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700650 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800651}
652
Mathias Agopian13127d82013-03-05 17:47:11 -0800653// ----------------------------------------------------------------------------
654// local state
655// ----------------------------------------------------------------------------
656
Dan Stozac7014012014-02-14 15:03:43 -0800657void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
658 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800659{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700660 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800661 const Transform tr(useIdentityTransform ?
662 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800663 const uint32_t hw_h = hw->getHeight();
664 Rect win(s.active.w, s.active.h);
665 if (!s.active.crop.isEmpty()) {
666 win.intersect(s.active.crop, &win);
667 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700668 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700669 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700670
Mathias Agopianff2ed702013-09-01 21:36:12 -0700671 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
672 position[0] = tr.transform(win.left, win.top);
673 position[1] = tr.transform(win.left, win.bottom);
674 position[2] = tr.transform(win.right, win.bottom);
675 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700676 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700677 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800678 }
679}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800680
Andy McFadden4125a4f2014-01-29 17:17:11 -0800681bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700682{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700683 // if we don't have a buffer yet, we're translucent regardless of the
684 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700685 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700686 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700687 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700688
689 // if the layer has the opaque flag, then we're always opaque,
690 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800691 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700692}
693
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800694bool Layer::isProtected() const
695{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700696 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800697 return (activeBuffer != 0) &&
698 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
699}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700700
Mathias Agopian13127d82013-03-05 17:47:11 -0800701bool Layer::isFixedSize() const {
702 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
703}
704
705bool Layer::isCropped() const {
706 return !mCurrentCrop.isEmpty();
707}
708
709bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
710 return mNeedsFiltering || hw->needsFiltering();
711}
712
713void Layer::setVisibleRegion(const Region& visibleRegion) {
714 // always called from main thread
715 this->visibleRegion = visibleRegion;
716}
717
718void Layer::setCoveredRegion(const Region& coveredRegion) {
719 // always called from main thread
720 this->coveredRegion = coveredRegion;
721}
722
723void Layer::setVisibleNonTransparentRegion(const Region&
724 setVisibleNonTransparentRegion) {
725 // always called from main thread
726 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
727}
728
729// ----------------------------------------------------------------------------
730// transaction
731// ----------------------------------------------------------------------------
732
733uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800734 ATRACE_CALL();
735
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700736 const Layer::State& s(getDrawingState());
737 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800738
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700739 const bool sizeChanged = (c.requested.w != s.requested.w) ||
740 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700741
742 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700743 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000744 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700745 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700746 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
747 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
748 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
749 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700750 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
751 c.active.w, c.active.h,
752 c.active.crop.left,
753 c.active.crop.top,
754 c.active.crop.right,
755 c.active.crop.bottom,
756 c.active.crop.getWidth(),
757 c.active.crop.getHeight(),
758 c.requested.w, c.requested.h,
759 c.requested.crop.left,
760 c.requested.crop.top,
761 c.requested.crop.right,
762 c.requested.crop.bottom,
763 c.requested.crop.getWidth(),
764 c.requested.crop.getHeight(),
765 s.active.w, s.active.h,
766 s.active.crop.left,
767 s.active.crop.top,
768 s.active.crop.right,
769 s.active.crop.bottom,
770 s.active.crop.getWidth(),
771 s.active.crop.getHeight(),
772 s.requested.w, s.requested.h,
773 s.requested.crop.left,
774 s.requested.crop.top,
775 s.requested.crop.right,
776 s.requested.crop.bottom,
777 s.requested.crop.getWidth(),
778 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800779
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700780 // record the new size, form this point on, when the client request
781 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800782 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700783 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800784 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700785
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700786 if (!isFixedSize()) {
787
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700788 const bool resizePending = (c.requested.w != c.active.w) ||
789 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700790
791 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800792 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700793 // if we have a pending resize, unless we are in fixed-size mode.
794 // the drawing state will be updated only once we receive a buffer
795 // with the correct size.
796 //
797 // in particular, we want to make sure the clip (which is part
798 // of the geometry state) is latched together with the size but is
799 // latched immediately when no resizing is involved.
800
801 flags |= eDontUpdateGeometryState;
802 }
803 }
804
Mathias Agopian13127d82013-03-05 17:47:11 -0800805 // always set active to requested, unless we're asked not to
806 // this is used by Layer, which special cases resizes.
807 if (flags & eDontUpdateGeometryState) {
808 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700809 Layer::State& editCurrentState(getCurrentState());
810 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800811 }
812
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700813 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800814 // invalidate and recompute the visible regions if needed
815 flags |= Layer::eVisibleRegion;
816 }
817
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700818 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800819 // invalidate and recompute the visible regions if needed
820 flags |= eVisibleRegion;
821 this->contentDirty = true;
822
823 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700824 const uint8_t type = c.transform.getType();
825 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800826 (type >= Transform::SCALE));
827 }
828
829 // Commit the transaction
830 commitTransaction();
831 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800832}
833
Mathias Agopian13127d82013-03-05 17:47:11 -0800834void Layer::commitTransaction() {
835 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700836}
837
Mathias Agopian13127d82013-03-05 17:47:11 -0800838uint32_t Layer::getTransactionFlags(uint32_t flags) {
839 return android_atomic_and(~flags, &mTransactionFlags) & flags;
840}
841
842uint32_t Layer::setTransactionFlags(uint32_t flags) {
843 return android_atomic_or(flags, &mTransactionFlags);
844}
845
846bool Layer::setPosition(float x, float y) {
847 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
848 return false;
849 mCurrentState.sequence++;
850 mCurrentState.transform.set(x, y);
851 setTransactionFlags(eTransactionNeeded);
852 return true;
853}
854bool Layer::setLayer(uint32_t z) {
855 if (mCurrentState.z == z)
856 return false;
857 mCurrentState.sequence++;
858 mCurrentState.z = z;
859 setTransactionFlags(eTransactionNeeded);
860 return true;
861}
862bool Layer::setSize(uint32_t w, uint32_t h) {
863 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
864 return false;
865 mCurrentState.requested.w = w;
866 mCurrentState.requested.h = h;
867 setTransactionFlags(eTransactionNeeded);
868 return true;
869}
870bool Layer::setAlpha(uint8_t alpha) {
871 if (mCurrentState.alpha == alpha)
872 return false;
873 mCurrentState.sequence++;
874 mCurrentState.alpha = alpha;
875 setTransactionFlags(eTransactionNeeded);
876 return true;
877}
878bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
879 mCurrentState.sequence++;
880 mCurrentState.transform.set(
881 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
882 setTransactionFlags(eTransactionNeeded);
883 return true;
884}
885bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700886 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800887 setTransactionFlags(eTransactionNeeded);
888 return true;
889}
890bool Layer::setFlags(uint8_t flags, uint8_t mask) {
891 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
892 if (mCurrentState.flags == newFlags)
893 return false;
894 mCurrentState.sequence++;
895 mCurrentState.flags = newFlags;
896 setTransactionFlags(eTransactionNeeded);
897 return true;
898}
899bool Layer::setCrop(const Rect& crop) {
900 if (mCurrentState.requested.crop == crop)
901 return false;
902 mCurrentState.sequence++;
903 mCurrentState.requested.crop = crop;
904 setTransactionFlags(eTransactionNeeded);
905 return true;
906}
907
908bool Layer::setLayerStack(uint32_t layerStack) {
909 if (mCurrentState.layerStack == layerStack)
910 return false;
911 mCurrentState.sequence++;
912 mCurrentState.layerStack = layerStack;
913 setTransactionFlags(eTransactionNeeded);
914 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700915}
916
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800917// ----------------------------------------------------------------------------
918// pageflip handling...
919// ----------------------------------------------------------------------------
920
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800921bool Layer::onPreComposition() {
922 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800923 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800924}
925
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700926void Layer::onPostComposition() {
927 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800928 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800929 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
930
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800931 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800932 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800933 mFrameTracker.setFrameReadyFence(frameReadyFence);
934 } else {
935 // There was no fence for this frame, so assume that it was ready
936 // to be presented at the desired present time.
937 mFrameTracker.setFrameReadyTime(desiredPresentTime);
938 }
939
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700940 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800941 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800942 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800943 mFrameTracker.setActualPresentFence(presentFence);
944 } else {
945 // The HWC doesn't support present fences, so use the refresh
946 // timestamp instead.
947 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
948 mFrameTracker.setActualPresentTime(presentTime);
949 }
950
951 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700952 mFrameLatencyNeeded = false;
953 }
954}
955
Mathias Agopianda27af92012-09-13 18:17:13 -0700956bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800957 const Layer::State& s(mDrawingState);
958 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
959 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700960}
961
Mathias Agopian4fec8732012-06-29 14:12:52 -0700962Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800963{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800964 ATRACE_CALL();
965
Jesse Hall399184a2014-03-03 15:42:54 -0800966 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
967 // mSidebandStreamChanged was true
968 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
969 }
970
Mathias Agopian4fec8732012-06-29 14:12:52 -0700971 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700972 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800973
974 // if we've already called updateTexImage() without going through
975 // a composition step, we have to skip this layer at this point
976 // because we cannot call updateTeximage() without a corresponding
977 // compositionComplete() call.
978 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800979 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700980 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800981 }
982
Jamie Gennis351a5132011-09-14 18:23:37 -0700983 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -0800984 const State& s(getDrawingState());
985 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -0700986 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700987
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800988 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700989 Layer::State& front;
990 Layer::State& current;
991 bool& recomputeVisibleRegions;
992 Reject(Layer::State& front, Layer::State& current,
993 bool& recomputeVisibleRegions)
994 : front(front), current(current),
995 recomputeVisibleRegions(recomputeVisibleRegions) {
996 }
997
998 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700999 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001000 if (buf == NULL) {
1001 return false;
1002 }
1003
1004 uint32_t bufWidth = buf->getWidth();
1005 uint32_t bufHeight = buf->getHeight();
1006
1007 // check that we received a buffer of the right size
1008 // (Take the buffer's orientation into account)
1009 if (item.mTransform & Transform::ROT_90) {
1010 swap(bufWidth, bufHeight);
1011 }
1012
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001013 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1014 if (front.active != front.requested) {
1015
1016 if (isFixedSize ||
1017 (bufWidth == front.requested.w &&
1018 bufHeight == front.requested.h))
1019 {
1020 // Here we pretend the transaction happened by updating the
1021 // current and drawing states. Drawing state is only accessed
1022 // in this thread, no need to have it locked
1023 front.active = front.requested;
1024
1025 // We also need to update the current state so that
1026 // we don't end-up overwriting the drawing state with
1027 // this stale current state during the next transaction
1028 //
1029 // NOTE: We don't need to hold the transaction lock here
1030 // because State::active is only accessed from this thread.
1031 current.active = front.active;
1032
1033 // recompute visible region
1034 recomputeVisibleRegions = true;
1035 }
1036
1037 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001038 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001039 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1040 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001041 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001042 front.active.w, front.active.h,
1043 front.active.crop.left,
1044 front.active.crop.top,
1045 front.active.crop.right,
1046 front.active.crop.bottom,
1047 front.active.crop.getWidth(),
1048 front.active.crop.getHeight(),
1049 front.requested.w, front.requested.h,
1050 front.requested.crop.left,
1051 front.requested.crop.top,
1052 front.requested.crop.right,
1053 front.requested.crop.bottom,
1054 front.requested.crop.getWidth(),
1055 front.requested.crop.getHeight());
1056 }
1057
1058 if (!isFixedSize) {
1059 if (front.active.w != bufWidth ||
1060 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001061 // reject this buffer
Mathias Agopian4ceff3d2013-08-21 15:23:15 -07001062 //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1063 // bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001064 return true;
1065 }
1066 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001067
1068 // if the transparent region has changed (this test is
1069 // conservative, but that's fine, worst case we're doing
1070 // a bit of extra work), we latch the new one and we
1071 // trigger a visible-region recompute.
1072 if (!front.activeTransparentRegion.isTriviallyEqual(
1073 front.requestedTransparentRegion)) {
1074 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001075
1076 // We also need to update the current state so that
1077 // we don't end-up overwriting the drawing state with
1078 // this stale current state during the next transaction
1079 //
1080 // NOTE: We don't need to hold the transaction lock here
1081 // because State::active is only accessed from this thread.
1082 current.activeTransparentRegion = front.activeTransparentRegion;
1083
1084 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001085 recomputeVisibleRegions = true;
1086 }
1087
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001088 return false;
1089 }
1090 };
1091
1092
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001093 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001094
Andy McFadden1585c4d2013-06-28 13:52:40 -07001095 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1096 if (updateResult == BufferQueue::PRESENT_LATER) {
1097 // Producer doesn't want buffer to be displayed yet. Signal a
1098 // layer update so we check again at the next opportunity.
1099 mFlinger->signalLayerUpdate();
1100 return outDirtyRegion;
1101 }
1102
1103 // Decrement the queued-frames count. Signal another event if we
1104 // have more frames pending.
1105 if (android_atomic_dec(&mQueuedFrames) > 1) {
1106 mFlinger->signalLayerUpdate();
1107 }
1108
1109 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001110 // something happened!
1111 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001112 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001113 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001114
Jamie Gennis351a5132011-09-14 18:23:37 -07001115 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001116 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001117 if (mActiveBuffer == NULL) {
1118 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001119 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001120 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001121
Mathias Agopian4824d402012-06-04 18:16:30 -07001122 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001123 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001124 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001125 // the first time we receive a buffer, we need to trigger a
1126 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001127 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001128 }
1129
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001130 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1131 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1132 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001133 if ((crop != mCurrentCrop) ||
1134 (transform != mCurrentTransform) ||
1135 (scalingMode != mCurrentScalingMode))
1136 {
1137 mCurrentCrop = crop;
1138 mCurrentTransform = transform;
1139 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001140 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001141 }
1142
1143 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001144 uint32_t bufWidth = mActiveBuffer->getWidth();
1145 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001146 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1147 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001148 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001149 }
1150 }
1151
1152 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001153 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001154 recomputeVisibleRegions = true;
1155 }
1156
Mathias Agopian4fec8732012-06-29 14:12:52 -07001157 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001158 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001159
1160 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001161 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001162 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001163 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001164}
1165
Mathias Agopiana67932f2011-04-20 14:20:59 -07001166uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001167{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001168 // TODO: should we do something special if mSecure is set?
1169 if (mProtectedByApp) {
1170 // need a hardware-protected path to external video sink
1171 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001172 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001173 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001174 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001175}
1176
Mathias Agopian84300952012-11-21 16:02:13 -08001177void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001178 uint32_t orientation = 0;
1179 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001180 // The transform hint is used to improve performance, but we can
1181 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001182 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001183 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001184 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001185 if (orientation & Transform::ROT_INVALID) {
1186 orientation = 0;
1187 }
1188 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001189 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001190}
1191
Mathias Agopian13127d82013-03-05 17:47:11 -08001192// ----------------------------------------------------------------------------
1193// debugging
1194// ----------------------------------------------------------------------------
1195
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001196void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001197{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001198 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001199
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001200 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001201 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001202 "+ %s %p (%s)\n",
1203 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001204 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001205
Mathias Agopian2ca79392013-04-02 18:30:32 -07001206 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001207 visibleRegion.dump(result, "visibleRegion");
1208 sp<Client> client(mClientRef.promote());
1209
Mathias Agopian74d211a2013-04-22 16:55:35 +02001210 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001211 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1212 "isOpaque=%1d, invalidate=%1d, "
1213 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1214 " client=%p\n",
1215 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1216 s.active.crop.left, s.active.crop.top,
1217 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001218 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001219 s.alpha, s.flags,
1220 s.transform[0][0], s.transform[0][1],
1221 s.transform[1][0], s.transform[1][1],
1222 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001223
1224 sp<const GraphicBuffer> buf0(mActiveBuffer);
1225 uint32_t w0=0, h0=0, s0=0, f0=0;
1226 if (buf0 != 0) {
1227 w0 = buf0->getWidth();
1228 h0 = buf0->getHeight();
1229 s0 = buf0->getStride();
1230 f0 = buf0->format;
1231 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001232 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001233 " "
1234 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1235 " queued-frames=%d, mRefreshPending=%d\n",
1236 mFormat, w0, h0, s0,f0,
1237 mQueuedFrames, mRefreshPending);
1238
Mathias Agopian13127d82013-03-05 17:47:11 -08001239 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001240 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001241 }
1242}
1243
Mathias Agopian74d211a2013-04-22 16:55:35 +02001244void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001245 mFrameTracker.dump(result);
1246}
1247
1248void Layer::clearStats() {
1249 mFrameTracker.clear();
1250}
1251
Jamie Gennis6547ff42013-07-16 20:12:42 -07001252void Layer::logFrameStats() {
1253 mFrameTracker.logAndResetStats(mName);
1254}
1255
Mathias Agopian13127d82013-03-05 17:47:11 -08001256// ---------------------------------------------------------------------------
1257
1258Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1259 const sp<Layer>& layer)
1260 : mFlinger(flinger), mLayer(layer) {
1261}
1262
1263Layer::LayerCleaner::~LayerCleaner() {
1264 // destroy client resources
1265 mFlinger->onLayerDestroyed(mLayer);
1266}
1267
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001268// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001269}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001270
1271#if defined(__gl_h_)
1272#error "don't include gl/gl.h in this file"
1273#endif
1274
1275#if defined(__gl2_h_)
1276#error "don't include gl2/gl2.h in this file"
1277#endif