blob: 465d3764afd5fd5e98d5536dcc211260b0cb3ffa [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>
30#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080031#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080032
Mathias Agopian3330b202009-10-05 17:07:12 -070033#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080035
Mathias Agopian90ac7992012-02-25 18:48:35 -080036#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080037
38#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020039#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070040#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080041#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "SurfaceFlinger.h"
Mathias Agopiana67932f2011-04-20 14:20:59 -070043#include "SurfaceTextureLayer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080044
Mathias Agopian1b031492012-06-20 17:51:20 -070045#include "DisplayHardware/HWComposer.h"
46
Mathias Agopian875d8e12013-06-07 15:35:48 -070047#include "RenderEngine/RenderEngine.h"
48
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049#define DEBUG_RESIZE 0
50
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051namespace android {
52
53// ---------------------------------------------------------------------------
54
Mathias Agopian13127d82013-03-05 17:47:11 -080055int32_t Layer::sSequence = 1;
56
Mathias Agopian4d9b8222013-03-12 17:11:48 -070057Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
58 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080059 : contentDirty(false),
60 sequence(uint32_t(android_atomic_inc(&sSequence))),
61 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070062 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080063 mPremultipliedAlpha(true),
64 mName("unnamed"),
65 mDebug(false),
66 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070068 mQueuedFrames(0),
69 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070070 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080072 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080073 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080074 mFiltering(false),
75 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070076 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070077 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080078 mProtectedByApp(false),
79 mHasSurface(false),
80 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080081{
Mathias Agopiana67932f2011-04-20 14:20:59 -070082 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070083 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070084 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070085
86 uint32_t layerFlags = 0;
87 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080088 layerFlags |= layer_state_t::eLayerHidden;
89 if (flags & ISurfaceComposerClient::eOpaque)
90 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070091
92 if (flags & ISurfaceComposerClient::eNonPremultiplied)
93 mPremultipliedAlpha = false;
94
95 mName = name;
96
97 mCurrentState.active.w = w;
98 mCurrentState.active.h = h;
99 mCurrentState.active.crop.makeInvalid();
100 mCurrentState.z = 0;
101 mCurrentState.alpha = 0xFF;
102 mCurrentState.layerStack = 0;
103 mCurrentState.flags = layerFlags;
104 mCurrentState.sequence = 0;
105 mCurrentState.transform.set(0, 0);
106 mCurrentState.requested = mCurrentState.active;
107
108 // drawing state & current state are identical
109 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700110
111 nsecs_t displayPeriod =
112 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
113 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800114}
115
Mathias Agopian3f844832013-08-07 21:24:32 -0700116void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800117 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700118 mBufferQueue = new SurfaceTextureLayer(mFlinger);
Mathias Agopian3f844832013-08-07 21:24:32 -0700119 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800120 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
121 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700122 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800123
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700124#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
125#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800126 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700127#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800128 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800129#endif
Andy McFadden69052052012-09-14 16:10:11 -0700130
Mathias Agopian84300952012-11-21 16:02:13 -0800131 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
132 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700133}
134
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700135Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800136 sp<Client> c(mClientRef.promote());
137 if (c != 0) {
138 c->detachLayer(this);
139 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700140 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700141 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700142}
143
Mathias Agopian13127d82013-03-05 17:47:11 -0800144// ---------------------------------------------------------------------------
145// callbacks
146// ---------------------------------------------------------------------------
147
Dan Stozac7014012014-02-14 15:03:43 -0800148void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800149 HWComposer::HWCLayerInterface* layer) {
150 if (layer) {
151 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700152 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800153 }
154}
155
Igor Murashkina4a31492012-10-29 13:36:11 -0700156void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700157 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800158 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700159}
160
Mathias Agopian67106042013-03-14 19:18:13 -0700161// called with SurfaceFlinger::mStateLock from the drawing thread after
162// the layer has been remove from the current state list (and just before
163// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800164void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800165 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700166}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700167
Mathias Agopian13127d82013-03-05 17:47:11 -0800168// ---------------------------------------------------------------------------
169// set-up
170// ---------------------------------------------------------------------------
171
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700172const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800173 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800174}
175
Mathias Agopianf9d93272009-06-19 17:00:27 -0700176status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800177 PixelFormat format, uint32_t flags)
178{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700179 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700180 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700181
182 // never allow a surface larger than what our underlying GL implementation
183 // can handle.
184 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800185 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700186 return BAD_VALUE;
187 }
188
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700189 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700190
Mathias Agopian3165cc22012-08-08 19:42:09 -0700191 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
192 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700193 mCurrentOpacity = getOpacityForFormat(format);
194
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800195 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
196 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
197 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700198
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800199 return NO_ERROR;
200}
201
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700202sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800203 Mutex::Autolock _l(mLock);
204
205 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700206 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800207
208 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700209
210 /*
211 * The layer handle is just a BBinder object passed to the client
212 * (remote process) -- we don't keep any reference on our side such that
213 * the dtor is called when the remote side let go of its reference.
214 *
215 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
216 * this layer when the handle is destroyed.
217 */
218
219 class Handle : public BBinder, public LayerCleaner {
220 wp<const Layer> mOwner;
221 public:
222 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
223 : LayerCleaner(flinger, layer), mOwner(layer) {
224 }
225 };
226
227 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800228}
229
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700230sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
231 return mBufferQueue;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700232}
233
Mathias Agopian13127d82013-03-05 17:47:11 -0800234// ---------------------------------------------------------------------------
235// h/w composer set-up
236// ---------------------------------------------------------------------------
237
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800238Rect Layer::getContentCrop() const {
239 // this is the crop rectangle that applies to the buffer
240 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700241 Rect crop;
242 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800243 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700244 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800245 } else if (mActiveBuffer != NULL) {
246 // otherwise we use the whole buffer
247 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700248 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800249 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700250 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700251 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700252 return crop;
253}
254
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700255static Rect reduce(const Rect& win, const Region& exclude) {
256 if (CC_LIKELY(exclude.isEmpty())) {
257 return win;
258 }
259 if (exclude.isRect()) {
260 return win.reduce(exclude.getBounds());
261 }
262 return Region(win).subtract(exclude).getBounds();
263}
264
Mathias Agopian13127d82013-03-05 17:47:11 -0800265Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700266 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800267 Rect win(s.active.w, s.active.h);
268 if (!s.active.crop.isEmpty()) {
269 win.intersect(s.active.crop, &win);
270 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700271 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700272 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800273}
274
Mathias Agopian6b442672013-07-09 21:24:52 -0700275FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800276 // the content crop is the area of the content that gets scaled to the
277 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700278 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800279
280 // the active.crop is the area of the window that gets cropped, but not
281 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700282 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800283
284 // apply the projection's clipping to the window crop in
285 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700286 // if there are no window scaling involved, this operation will map to full
287 // pixels in the buffer.
288 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
289 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700290
291 Rect activeCrop(s.active.w, s.active.h);
292 if (!s.active.crop.isEmpty()) {
293 activeCrop = s.active.crop;
294 }
295
296 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800297 activeCrop.intersect(hw->getViewport(), &activeCrop);
298 activeCrop = s.transform.inverse().transform(activeCrop);
299
300 // paranoia: make sure the window-crop is constrained in the
301 // window's bounds
302 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
303
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700304 // subtract the transparent region and snap to the bounds
305 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
306
Mathias Agopian13127d82013-03-05 17:47:11 -0800307 if (!activeCrop.isEmpty()) {
308 // Transform the window crop to match the buffer coordinate system,
309 // which means using the inverse of the current transform set on the
310 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700311 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800312 int winWidth = s.active.w;
313 int winHeight = s.active.h;
314 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
315 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
316 NATIVE_WINDOW_TRANSFORM_FLIP_H;
317 winWidth = s.active.h;
318 winHeight = s.active.w;
319 }
320 const Rect winCrop = activeCrop.transform(
321 invTransform, s.active.w, s.active.h);
322
Mathias Agopian6b442672013-07-09 21:24:52 -0700323 // below, crop is intersected with winCrop expressed in crop's coordinate space
324 float xScale = crop.getWidth() / float(winWidth);
325 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800326
Mathias Agopian6b442672013-07-09 21:24:52 -0700327 float insetL = winCrop.left * xScale;
328 float insetT = winCrop.top * yScale;
329 float insetR = (winWidth - winCrop.right ) * xScale;
330 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800331
332 crop.left += insetL;
333 crop.top += insetT;
334 crop.right -= insetR;
335 crop.bottom -= insetB;
336 }
337 return crop;
338}
339
Mathias Agopian4fec8732012-06-29 14:12:52 -0700340void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700341 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700342 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700343{
Mathias Agopian13127d82013-03-05 17:47:11 -0800344 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700345
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700346 // enable this layer
347 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700348
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700349 if (isSecure() && !hw->isSecure()) {
350 layer.setSkip(true);
351 }
352
Mathias Agopian13127d82013-03-05 17:47:11 -0800353 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700354 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800355 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800356 layer.setBlending(mPremultipliedAlpha ?
357 HWC_BLENDING_PREMULT :
358 HWC_BLENDING_COVERAGE);
359 }
360
361 // apply the layer's transform, followed by the display's global transform
362 // here we're guaranteed that the layer's transform preserves rects
363 Rect frame(s.transform.transform(computeBounds()));
364 frame.intersect(hw->getViewport(), &frame);
365 const Transform& tr(hw->getTransform());
366 layer.setFrame(tr.transform(frame));
367 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800368 layer.setPlaneAlpha(s.alpha);
369
Mathias Agopian29a367b2011-07-12 14:51:45 -0700370 /*
371 * Transformations are applied in this order:
372 * 1) buffer orientation/flip/mirror
373 * 2) state transformation (window manager)
374 * 3) layer orientation (screen orientation)
375 * (NOTE: the matrices are multiplied in reverse order)
376 */
377
378 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700379 Transform transform(tr * s.transform * bufferOrientation);
380
381 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
382 /*
383 * the code below applies the display's inverse transform to the buffer
384 */
385 uint32_t invTransform = hw->getOrientationTransform();
386 // calculate the inverse transform
387 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
388 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
389 NATIVE_WINDOW_TRANSFORM_FLIP_H;
390 }
391 // and apply to the current transform
392 transform = transform * Transform(invTransform);
393 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700394
395 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800396 const uint32_t orientation = transform.getOrientation();
397 if (orientation & Transform::ROT_INVALID) {
398 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700399 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700400 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800401 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700402 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700403}
404
Mathias Agopian42977342012-08-05 00:40:46 -0700405void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700406 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800407 // we have to set the visible region on every frame because
408 // we currently free it during onLayerDisplayed(), which is called
409 // after HWComposer::commit() -- every frame.
410 // Apply this display's projection's viewport to the visible region
411 // before giving it to the HWC HAL.
412 const Transform& tr = hw->getTransform();
413 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
414 layer.setVisibleRegionScreen(visible);
415
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700416 // NOTE: buffer can be NULL if the client never drew into this
417 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700418 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700419}
Jesse Halldc5b4852012-06-29 15:21:18 -0700420
Dan Stozac7014012014-02-14 15:03:43 -0800421void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700422 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700423 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700424
425 // TODO: there is a possible optimization here: we only need to set the
426 // acquire fence the first time a new buffer is acquired on EACH display.
427
428 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800429 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800430 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700431 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700432 if (fenceFd == -1) {
433 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
434 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700435 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700436 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700437 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700438}
439
Mathias Agopian13127d82013-03-05 17:47:11 -0800440// ---------------------------------------------------------------------------
441// drawing...
442// ---------------------------------------------------------------------------
443
444void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800445 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800446}
447
Dan Stozac7014012014-02-14 15:03:43 -0800448void Layer::draw(const sp<const DisplayDevice>& hw,
449 bool useIdentityTransform) const {
450 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800451}
452
Dan Stozac7014012014-02-14 15:03:43 -0800453void Layer::draw(const sp<const DisplayDevice>& hw) const {
454 onDraw(hw, Region(hw->bounds()), false);
455}
456
457void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
458 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800459{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800460 ATRACE_CALL();
461
Mathias Agopiana67932f2011-04-20 14:20:59 -0700462 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800463 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700464 // in fact never been drawn into. This happens frequently with
465 // SurfaceView because the WindowManager can't know when the client
466 // has drawn the first time.
467
468 // If there is nothing under us, we paint the screen in black, otherwise
469 // we just skip this update.
470
471 // figure out if there is something below us
472 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700473 const SurfaceFlinger::LayerVector& drawingLayers(
474 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700475 const size_t count = drawingLayers.size();
476 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800477 const sp<Layer>& layer(drawingLayers[i]);
478 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700479 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700480 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700481 }
482 // if not everything below us is covered, we plug the holes!
483 Region holes(clip.subtract(under));
484 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700485 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700486 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800487 return;
488 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700489
Andy McFadden97eba892012-12-11 15:21:45 -0800490 // Bind the current buffer to the GL texture, and wait for it to be
491 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800492 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
493 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800494 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700495 // Go ahead and draw the buffer anyway; no matter what we do the screen
496 // is probably going to have something visibly wrong.
497 }
498
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700499 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
500
Mathias Agopian875d8e12013-06-07 15:35:48 -0700501 RenderEngine& engine(mFlinger->getRenderEngine());
502
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700503 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700504 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700505 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700506
507 // Query the texture matrix given our current filtering mode.
508 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800509 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
510 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700511
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700512 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
513
514 /*
515 * the code below applies the display's inverse transform to the texture transform
516 */
517
518 // create a 4x4 transform matrix from the display transform flags
519 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
520 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
521 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
522
523 mat4 tr;
524 uint32_t transform = hw->getOrientationTransform();
525 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
526 tr = tr * rot90;
527 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
528 tr = tr * flipH;
529 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
530 tr = tr * flipV;
531
532 // calculate the inverse
533 tr = inverse(tr);
534
535 // and finally apply it to the original texture matrix
536 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
537 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
538 }
539
Jamie Genniscbb1a952012-05-08 17:05:52 -0700540 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700541 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
542 mTexture.setFiltering(useFiltering);
543 mTexture.setMatrix(textureMatrix);
544
545 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700546 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700547 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700548 }
Dan Stozac7014012014-02-14 15:03:43 -0800549 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700550 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800551}
552
Mathias Agopian13127d82013-03-05 17:47:11 -0800553
Dan Stozac7014012014-02-14 15:03:43 -0800554void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
555 const Region& /* clip */, float red, float green, float blue,
556 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800557{
Mathias Agopian19733a32013-08-28 18:13:56 -0700558 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800559 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700560 engine.setupFillWithColor(red, green, blue, alpha);
561 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800562}
563
564void Layer::clearWithOpenGL(
565 const sp<const DisplayDevice>& hw, const Region& clip) const {
566 clearWithOpenGL(hw, clip, 0,0,0,0);
567}
568
Dan Stozac7014012014-02-14 15:03:43 -0800569void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
570 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800571 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700572 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800573
Dan Stozac7014012014-02-14 15:03:43 -0800574 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800575
Mathias Agopian13127d82013-03-05 17:47:11 -0800576 /*
577 * NOTE: the way we compute the texture coordinates here produces
578 * different results than when we take the HWC path -- in the later case
579 * the "source crop" is rounded to texel boundaries.
580 * This can produce significantly different results when the texture
581 * is scaled by a large amount.
582 *
583 * The GL code below is more logical (imho), and the difference with
584 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700585 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800586 * GL composition when a buffer scaling is applied (maybe with some
587 * minimal value)? Or, we could make GL behave like HWC -- but this feel
588 * like more of a hack.
589 */
590 const Rect win(computeBounds());
591
Mathias Agopian3f844832013-08-07 21:24:32 -0700592 float left = float(win.left) / float(s.active.w);
593 float top = float(win.top) / float(s.active.h);
594 float right = float(win.right) / float(s.active.w);
595 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800596
Mathias Agopian875d8e12013-06-07 15:35:48 -0700597 // TODO: we probably want to generate the texture coords with the mesh
598 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700599 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
600 texCoords[0] = vec2(left, 1.0f - top);
601 texCoords[1] = vec2(left, 1.0f - bottom);
602 texCoords[2] = vec2(right, 1.0f - bottom);
603 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800604
Mathias Agopian875d8e12013-06-07 15:35:48 -0700605 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800606 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700607 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700608 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800609}
610
611void Layer::setFiltering(bool filtering) {
612 mFiltering = filtering;
613}
614
615bool Layer::getFiltering() const {
616 return mFiltering;
617}
618
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800619// As documented in libhardware header, formats in the range
620// 0x100 - 0x1FF are specific to the HAL implementation, and
621// are known to have no alpha channel
622// TODO: move definition for device-specific range into
623// hardware.h, instead of using hard-coded values here.
624#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
625
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700626bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700627 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
628 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800629 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700630 switch (format) {
631 case HAL_PIXEL_FORMAT_RGBA_8888:
632 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700633 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700634 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700635 }
636 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700637 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800638}
639
Mathias Agopian13127d82013-03-05 17:47:11 -0800640// ----------------------------------------------------------------------------
641// local state
642// ----------------------------------------------------------------------------
643
Dan Stozac7014012014-02-14 15:03:43 -0800644void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
645 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800646{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700647 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800648 const Transform tr(useIdentityTransform ?
649 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800650 const uint32_t hw_h = hw->getHeight();
651 Rect win(s.active.w, s.active.h);
652 if (!s.active.crop.isEmpty()) {
653 win.intersect(s.active.crop, &win);
654 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700655 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700656 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700657
Mathias Agopianff2ed702013-09-01 21:36:12 -0700658 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
659 position[0] = tr.transform(win.left, win.top);
660 position[1] = tr.transform(win.left, win.bottom);
661 position[2] = tr.transform(win.right, win.bottom);
662 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700663 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700664 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800665 }
666}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800667
Andy McFadden4125a4f2014-01-29 17:17:11 -0800668bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700669{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700670 // if we don't have a buffer yet, we're translucent regardless of the
671 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700672 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700673 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700674 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700675
676 // if the layer has the opaque flag, then we're always opaque,
677 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800678 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700679}
680
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800681bool Layer::isProtected() const
682{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700683 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800684 return (activeBuffer != 0) &&
685 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
686}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700687
Mathias Agopian13127d82013-03-05 17:47:11 -0800688bool Layer::isFixedSize() const {
689 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
690}
691
692bool Layer::isCropped() const {
693 return !mCurrentCrop.isEmpty();
694}
695
696bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
697 return mNeedsFiltering || hw->needsFiltering();
698}
699
700void Layer::setVisibleRegion(const Region& visibleRegion) {
701 // always called from main thread
702 this->visibleRegion = visibleRegion;
703}
704
705void Layer::setCoveredRegion(const Region& coveredRegion) {
706 // always called from main thread
707 this->coveredRegion = coveredRegion;
708}
709
710void Layer::setVisibleNonTransparentRegion(const Region&
711 setVisibleNonTransparentRegion) {
712 // always called from main thread
713 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
714}
715
716// ----------------------------------------------------------------------------
717// transaction
718// ----------------------------------------------------------------------------
719
720uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800721 ATRACE_CALL();
722
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700723 const Layer::State& s(getDrawingState());
724 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800725
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700726 const bool sizeChanged = (c.requested.w != s.requested.w) ||
727 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700728
729 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700730 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000731 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700732 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700733 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
734 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
735 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
736 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700737 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
738 c.active.w, c.active.h,
739 c.active.crop.left,
740 c.active.crop.top,
741 c.active.crop.right,
742 c.active.crop.bottom,
743 c.active.crop.getWidth(),
744 c.active.crop.getHeight(),
745 c.requested.w, c.requested.h,
746 c.requested.crop.left,
747 c.requested.crop.top,
748 c.requested.crop.right,
749 c.requested.crop.bottom,
750 c.requested.crop.getWidth(),
751 c.requested.crop.getHeight(),
752 s.active.w, s.active.h,
753 s.active.crop.left,
754 s.active.crop.top,
755 s.active.crop.right,
756 s.active.crop.bottom,
757 s.active.crop.getWidth(),
758 s.active.crop.getHeight(),
759 s.requested.w, s.requested.h,
760 s.requested.crop.left,
761 s.requested.crop.top,
762 s.requested.crop.right,
763 s.requested.crop.bottom,
764 s.requested.crop.getWidth(),
765 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800766
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700767 // record the new size, form this point on, when the client request
768 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800769 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700770 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800771 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700772
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700773 if (!isFixedSize()) {
774
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700775 const bool resizePending = (c.requested.w != c.active.w) ||
776 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700777
778 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800779 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700780 // if we have a pending resize, unless we are in fixed-size mode.
781 // the drawing state will be updated only once we receive a buffer
782 // with the correct size.
783 //
784 // in particular, we want to make sure the clip (which is part
785 // of the geometry state) is latched together with the size but is
786 // latched immediately when no resizing is involved.
787
788 flags |= eDontUpdateGeometryState;
789 }
790 }
791
Mathias Agopian13127d82013-03-05 17:47:11 -0800792 // always set active to requested, unless we're asked not to
793 // this is used by Layer, which special cases resizes.
794 if (flags & eDontUpdateGeometryState) {
795 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700796 Layer::State& editCurrentState(getCurrentState());
797 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800798 }
799
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700800 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800801 // invalidate and recompute the visible regions if needed
802 flags |= Layer::eVisibleRegion;
803 }
804
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700805 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800806 // invalidate and recompute the visible regions if needed
807 flags |= eVisibleRegion;
808 this->contentDirty = true;
809
810 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700811 const uint8_t type = c.transform.getType();
812 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800813 (type >= Transform::SCALE));
814 }
815
816 // Commit the transaction
817 commitTransaction();
818 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800819}
820
Mathias Agopian13127d82013-03-05 17:47:11 -0800821void Layer::commitTransaction() {
822 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700823}
824
Mathias Agopian13127d82013-03-05 17:47:11 -0800825uint32_t Layer::getTransactionFlags(uint32_t flags) {
826 return android_atomic_and(~flags, &mTransactionFlags) & flags;
827}
828
829uint32_t Layer::setTransactionFlags(uint32_t flags) {
830 return android_atomic_or(flags, &mTransactionFlags);
831}
832
833bool Layer::setPosition(float x, float y) {
834 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
835 return false;
836 mCurrentState.sequence++;
837 mCurrentState.transform.set(x, y);
838 setTransactionFlags(eTransactionNeeded);
839 return true;
840}
841bool Layer::setLayer(uint32_t z) {
842 if (mCurrentState.z == z)
843 return false;
844 mCurrentState.sequence++;
845 mCurrentState.z = z;
846 setTransactionFlags(eTransactionNeeded);
847 return true;
848}
849bool Layer::setSize(uint32_t w, uint32_t h) {
850 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
851 return false;
852 mCurrentState.requested.w = w;
853 mCurrentState.requested.h = h;
854 setTransactionFlags(eTransactionNeeded);
855 return true;
856}
857bool Layer::setAlpha(uint8_t alpha) {
858 if (mCurrentState.alpha == alpha)
859 return false;
860 mCurrentState.sequence++;
861 mCurrentState.alpha = alpha;
862 setTransactionFlags(eTransactionNeeded);
863 return true;
864}
865bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
866 mCurrentState.sequence++;
867 mCurrentState.transform.set(
868 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
869 setTransactionFlags(eTransactionNeeded);
870 return true;
871}
872bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700873 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800874 setTransactionFlags(eTransactionNeeded);
875 return true;
876}
877bool Layer::setFlags(uint8_t flags, uint8_t mask) {
878 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
879 if (mCurrentState.flags == newFlags)
880 return false;
881 mCurrentState.sequence++;
882 mCurrentState.flags = newFlags;
883 setTransactionFlags(eTransactionNeeded);
884 return true;
885}
886bool Layer::setCrop(const Rect& crop) {
887 if (mCurrentState.requested.crop == crop)
888 return false;
889 mCurrentState.sequence++;
890 mCurrentState.requested.crop = crop;
891 setTransactionFlags(eTransactionNeeded);
892 return true;
893}
894
895bool Layer::setLayerStack(uint32_t layerStack) {
896 if (mCurrentState.layerStack == layerStack)
897 return false;
898 mCurrentState.sequence++;
899 mCurrentState.layerStack = layerStack;
900 setTransactionFlags(eTransactionNeeded);
901 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700902}
903
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800904// ----------------------------------------------------------------------------
905// pageflip handling...
906// ----------------------------------------------------------------------------
907
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800908bool Layer::onPreComposition() {
909 mRefreshPending = false;
910 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800911}
912
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700913void Layer::onPostComposition() {
914 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800915 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800916 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
917
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800918 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800919 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800920 mFrameTracker.setFrameReadyFence(frameReadyFence);
921 } else {
922 // There was no fence for this frame, so assume that it was ready
923 // to be presented at the desired present time.
924 mFrameTracker.setFrameReadyTime(desiredPresentTime);
925 }
926
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700927 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800928 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800929 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800930 mFrameTracker.setActualPresentFence(presentFence);
931 } else {
932 // The HWC doesn't support present fences, so use the refresh
933 // timestamp instead.
934 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
935 mFrameTracker.setActualPresentTime(presentTime);
936 }
937
938 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700939 mFrameLatencyNeeded = false;
940 }
941}
942
Mathias Agopianda27af92012-09-13 18:17:13 -0700943bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800944 const Layer::State& s(mDrawingState);
945 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
946 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700947}
948
Mathias Agopian4fec8732012-06-29 14:12:52 -0700949Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800950{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800951 ATRACE_CALL();
952
Mathias Agopian4fec8732012-06-29 14:12:52 -0700953 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700954 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800955
956 // if we've already called updateTexImage() without going through
957 // a composition step, we have to skip this layer at this point
958 // because we cannot call updateTeximage() without a corresponding
959 // compositionComplete() call.
960 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800961 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700962 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800963 }
964
Jamie Gennis351a5132011-09-14 18:23:37 -0700965 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -0800966 const State& s(getDrawingState());
967 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -0700968 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700969
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800970 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700971 Layer::State& front;
972 Layer::State& current;
973 bool& recomputeVisibleRegions;
974 Reject(Layer::State& front, Layer::State& current,
975 bool& recomputeVisibleRegions)
976 : front(front), current(current),
977 recomputeVisibleRegions(recomputeVisibleRegions) {
978 }
979
980 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700981 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700982 if (buf == NULL) {
983 return false;
984 }
985
986 uint32_t bufWidth = buf->getWidth();
987 uint32_t bufHeight = buf->getHeight();
988
989 // check that we received a buffer of the right size
990 // (Take the buffer's orientation into account)
991 if (item.mTransform & Transform::ROT_90) {
992 swap(bufWidth, bufHeight);
993 }
994
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700995 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
996 if (front.active != front.requested) {
997
998 if (isFixedSize ||
999 (bufWidth == front.requested.w &&
1000 bufHeight == front.requested.h))
1001 {
1002 // Here we pretend the transaction happened by updating the
1003 // current and drawing states. Drawing state is only accessed
1004 // in this thread, no need to have it locked
1005 front.active = front.requested;
1006
1007 // We also need to update the current state so that
1008 // we don't end-up overwriting the drawing state with
1009 // this stale current state during the next transaction
1010 //
1011 // NOTE: We don't need to hold the transaction lock here
1012 // because State::active is only accessed from this thread.
1013 current.active = front.active;
1014
1015 // recompute visible region
1016 recomputeVisibleRegions = true;
1017 }
1018
1019 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001020 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001021 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1022 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001023 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001024 front.active.w, front.active.h,
1025 front.active.crop.left,
1026 front.active.crop.top,
1027 front.active.crop.right,
1028 front.active.crop.bottom,
1029 front.active.crop.getWidth(),
1030 front.active.crop.getHeight(),
1031 front.requested.w, front.requested.h,
1032 front.requested.crop.left,
1033 front.requested.crop.top,
1034 front.requested.crop.right,
1035 front.requested.crop.bottom,
1036 front.requested.crop.getWidth(),
1037 front.requested.crop.getHeight());
1038 }
1039
1040 if (!isFixedSize) {
1041 if (front.active.w != bufWidth ||
1042 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001043 // reject this buffer
Mathias Agopian4ceff3d2013-08-21 15:23:15 -07001044 //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1045 // bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001046 return true;
1047 }
1048 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001049
1050 // if the transparent region has changed (this test is
1051 // conservative, but that's fine, worst case we're doing
1052 // a bit of extra work), we latch the new one and we
1053 // trigger a visible-region recompute.
1054 if (!front.activeTransparentRegion.isTriviallyEqual(
1055 front.requestedTransparentRegion)) {
1056 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001057
1058 // We also need to update the current state so that
1059 // we don't end-up overwriting the drawing state with
1060 // this stale current state during the next transaction
1061 //
1062 // NOTE: We don't need to hold the transaction lock here
1063 // because State::active is only accessed from this thread.
1064 current.activeTransparentRegion = front.activeTransparentRegion;
1065
1066 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001067 recomputeVisibleRegions = true;
1068 }
1069
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001070 return false;
1071 }
1072 };
1073
1074
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001075 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001076
Andy McFadden1585c4d2013-06-28 13:52:40 -07001077 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1078 if (updateResult == BufferQueue::PRESENT_LATER) {
1079 // Producer doesn't want buffer to be displayed yet. Signal a
1080 // layer update so we check again at the next opportunity.
1081 mFlinger->signalLayerUpdate();
1082 return outDirtyRegion;
1083 }
1084
1085 // Decrement the queued-frames count. Signal another event if we
1086 // have more frames pending.
1087 if (android_atomic_dec(&mQueuedFrames) > 1) {
1088 mFlinger->signalLayerUpdate();
1089 }
1090
1091 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001092 // something happened!
1093 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001094 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001095 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001096
Jamie Gennis351a5132011-09-14 18:23:37 -07001097 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001098 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001099 if (mActiveBuffer == NULL) {
1100 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001101 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001102 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001103
Mathias Agopian4824d402012-06-04 18:16:30 -07001104 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001105 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001106 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001107 // the first time we receive a buffer, we need to trigger a
1108 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001109 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001110 }
1111
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001112 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1113 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1114 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001115 if ((crop != mCurrentCrop) ||
1116 (transform != mCurrentTransform) ||
1117 (scalingMode != mCurrentScalingMode))
1118 {
1119 mCurrentCrop = crop;
1120 mCurrentTransform = transform;
1121 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001122 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001123 }
1124
1125 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001126 uint32_t bufWidth = mActiveBuffer->getWidth();
1127 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001128 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1129 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001130 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001131 }
1132 }
1133
1134 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001135 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001136 recomputeVisibleRegions = true;
1137 }
1138
Mathias Agopian4fec8732012-06-29 14:12:52 -07001139 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001140 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001141
1142 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001143 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001144 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001145 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001146}
1147
Mathias Agopiana67932f2011-04-20 14:20:59 -07001148uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001149{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001150 // TODO: should we do something special if mSecure is set?
1151 if (mProtectedByApp) {
1152 // need a hardware-protected path to external video sink
1153 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001154 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001155 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001156 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001157}
1158
Mathias Agopian84300952012-11-21 16:02:13 -08001159void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001160 uint32_t orientation = 0;
1161 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001162 // The transform hint is used to improve performance, but we can
1163 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001164 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001165 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001166 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001167 if (orientation & Transform::ROT_INVALID) {
1168 orientation = 0;
1169 }
1170 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001171 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001172}
1173
Mathias Agopian13127d82013-03-05 17:47:11 -08001174// ----------------------------------------------------------------------------
1175// debugging
1176// ----------------------------------------------------------------------------
1177
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001178void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001179{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001180 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001181
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001182 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001183 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001184 "+ %s %p (%s)\n",
1185 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001186 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001187
Mathias Agopian2ca79392013-04-02 18:30:32 -07001188 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001189 visibleRegion.dump(result, "visibleRegion");
1190 sp<Client> client(mClientRef.promote());
1191
Mathias Agopian74d211a2013-04-22 16:55:35 +02001192 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001193 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1194 "isOpaque=%1d, invalidate=%1d, "
1195 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1196 " client=%p\n",
1197 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1198 s.active.crop.left, s.active.crop.top,
1199 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001200 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001201 s.alpha, s.flags,
1202 s.transform[0][0], s.transform[0][1],
1203 s.transform[1][0], s.transform[1][1],
1204 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001205
1206 sp<const GraphicBuffer> buf0(mActiveBuffer);
1207 uint32_t w0=0, h0=0, s0=0, f0=0;
1208 if (buf0 != 0) {
1209 w0 = buf0->getWidth();
1210 h0 = buf0->getHeight();
1211 s0 = buf0->getStride();
1212 f0 = buf0->format;
1213 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001214 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001215 " "
1216 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1217 " queued-frames=%d, mRefreshPending=%d\n",
1218 mFormat, w0, h0, s0,f0,
1219 mQueuedFrames, mRefreshPending);
1220
Mathias Agopian13127d82013-03-05 17:47:11 -08001221 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001222 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001223 }
1224}
1225
Mathias Agopian74d211a2013-04-22 16:55:35 +02001226void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001227 mFrameTracker.dump(result);
1228}
1229
1230void Layer::clearStats() {
1231 mFrameTracker.clear();
1232}
1233
Jamie Gennis6547ff42013-07-16 20:12:42 -07001234void Layer::logFrameStats() {
1235 mFrameTracker.logAndResetStats(mName);
1236}
1237
Mathias Agopian13127d82013-03-05 17:47:11 -08001238// ---------------------------------------------------------------------------
1239
1240Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1241 const sp<Layer>& layer)
1242 : mFlinger(flinger), mLayer(layer) {
1243}
1244
1245Layer::LayerCleaner::~LayerCleaner() {
1246 // destroy client resources
1247 mFlinger->onLayerDestroyed(mLayer);
1248}
1249
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001250// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001251}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001252
1253#if defined(__gl_h_)
1254#error "don't include gl/gl.h in this file"
1255#endif
1256
1257#if defined(__gl2_h_)
1258#error "don't include gl2/gl2.h in this file"
1259#endif