blob: 61af51faf51e268cd156222a33453506e548a226 [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 mOpaqueLayer(true),
68 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070069 mQueuedFrames(0),
70 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070071 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070072 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080073 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080074 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080075 mFiltering(false),
76 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070077 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070078 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080079 mProtectedByApp(false),
80 mHasSurface(false),
81 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080082{
Mathias Agopiana67932f2011-04-20 14:20:59 -070083 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070084 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070085 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070086
87 uint32_t layerFlags = 0;
88 if (flags & ISurfaceComposerClient::eHidden)
89 layerFlags = layer_state_t::eLayerHidden;
90
91 if (flags & ISurfaceComposerClient::eNonPremultiplied)
92 mPremultipliedAlpha = false;
93
94 mName = name;
95
96 mCurrentState.active.w = w;
97 mCurrentState.active.h = h;
98 mCurrentState.active.crop.makeInvalid();
99 mCurrentState.z = 0;
100 mCurrentState.alpha = 0xFF;
101 mCurrentState.layerStack = 0;
102 mCurrentState.flags = layerFlags;
103 mCurrentState.sequence = 0;
104 mCurrentState.transform.set(0, 0);
105 mCurrentState.requested = mCurrentState.active;
106
107 // drawing state & current state are identical
108 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700109
110 nsecs_t displayPeriod =
111 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
112 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800113}
114
Mathias Agopian3f844832013-08-07 21:24:32 -0700115void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800116 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700117 mBufferQueue = new SurfaceTextureLayer(mFlinger);
Mathias Agopian3f844832013-08-07 21:24:32 -0700118 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800119 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
120 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700121 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800122
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700123#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
124#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700126#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800127 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800128#endif
Andy McFadden69052052012-09-14 16:10:11 -0700129
Mathias Agopian84300952012-11-21 16:02:13 -0800130 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
131 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700132}
133
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700134Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800135 sp<Client> c(mClientRef.promote());
136 if (c != 0) {
137 c->detachLayer(this);
138 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700139 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700140 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700141}
142
Mathias Agopian13127d82013-03-05 17:47:11 -0800143// ---------------------------------------------------------------------------
144// callbacks
145// ---------------------------------------------------------------------------
146
147void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
148 HWComposer::HWCLayerInterface* layer) {
149 if (layer) {
150 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700151 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800152 }
153}
154
Igor Murashkina4a31492012-10-29 13:36:11 -0700155void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700156 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800157 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700158}
159
Mathias Agopian67106042013-03-14 19:18:13 -0700160// called with SurfaceFlinger::mStateLock from the drawing thread after
161// the layer has been remove from the current state list (and just before
162// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800163void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800164 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700165}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700166
Mathias Agopian13127d82013-03-05 17:47:11 -0800167// ---------------------------------------------------------------------------
168// set-up
169// ---------------------------------------------------------------------------
170
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700171const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800172 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800173}
174
Mathias Agopianf9d93272009-06-19 17:00:27 -0700175status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800176 PixelFormat format, uint32_t flags)
177{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700178 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700179 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700180
181 // never allow a surface larger than what our underlying GL implementation
182 // can handle.
183 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800184 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700185 return BAD_VALUE;
186 }
187
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700188 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700189
Mathias Agopian3165cc22012-08-08 19:42:09 -0700190 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
191 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
192 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
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());
Mathias Agopian13127d82013-03-05 17:47:11 -0800355 if (!isOpaque() || s.alpha != 0xFF) {
356 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
Mathias Agopian42977342012-08-05 00:40:46 -0700421void 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 {
445 onDraw(hw, clip);
446}
447
448void Layer::draw(const sp<const DisplayDevice>& hw) {
449 onDraw( hw, Region(hw->bounds()) );
450}
451
Mathias Agopian42977342012-08-05 00:40:46 -0700452void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800453{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800454 ATRACE_CALL();
455
Mathias Agopiana67932f2011-04-20 14:20:59 -0700456 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800457 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700458 // in fact never been drawn into. This happens frequently with
459 // SurfaceView because the WindowManager can't know when the client
460 // has drawn the first time.
461
462 // If there is nothing under us, we paint the screen in black, otherwise
463 // we just skip this update.
464
465 // figure out if there is something below us
466 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700467 const SurfaceFlinger::LayerVector& drawingLayers(
468 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700469 const size_t count = drawingLayers.size();
470 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800471 const sp<Layer>& layer(drawingLayers[i]);
472 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700473 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700474 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700475 }
476 // if not everything below us is covered, we plug the holes!
477 Region holes(clip.subtract(under));
478 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700479 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700480 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800481 return;
482 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700483
Andy McFadden97eba892012-12-11 15:21:45 -0800484 // Bind the current buffer to the GL texture, and wait for it to be
485 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800486 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
487 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800488 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700489 // Go ahead and draw the buffer anyway; no matter what we do the screen
490 // is probably going to have something visibly wrong.
491 }
492
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700493 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
494
Mathias Agopian875d8e12013-06-07 15:35:48 -0700495 RenderEngine& engine(mFlinger->getRenderEngine());
496
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700497 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700498 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700499 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700500
501 // Query the texture matrix given our current filtering mode.
502 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800503 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
504 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700505
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700506 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
507
508 /*
509 * the code below applies the display's inverse transform to the texture transform
510 */
511
512 // create a 4x4 transform matrix from the display transform flags
513 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
514 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
515 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
516
517 mat4 tr;
518 uint32_t transform = hw->getOrientationTransform();
519 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
520 tr = tr * rot90;
521 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
522 tr = tr * flipH;
523 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
524 tr = tr * flipV;
525
526 // calculate the inverse
527 tr = inverse(tr);
528
529 // and finally apply it to the original texture matrix
530 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
531 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
532 }
533
Jamie Genniscbb1a952012-05-08 17:05:52 -0700534 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700535 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
536 mTexture.setFiltering(useFiltering);
537 mTexture.setMatrix(textureMatrix);
538
539 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700540 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700541 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700542 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700543 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700544 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800545}
546
Mathias Agopian13127d82013-03-05 17:47:11 -0800547
548void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
Mathias Agopian3f844832013-08-07 21:24:32 -0700549 float red, float green, float blue, float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800550{
Mathias Agopian19733a32013-08-28 18:13:56 -0700551 RenderEngine& engine(mFlinger->getRenderEngine());
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700552 computeGeometry(hw, mMesh);
Mathias Agopian19733a32013-08-28 18:13:56 -0700553 engine.setupFillWithColor(red, green, blue, alpha);
554 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800555}
556
557void Layer::clearWithOpenGL(
558 const sp<const DisplayDevice>& hw, const Region& clip) const {
559 clearWithOpenGL(hw, clip, 0,0,0,0);
560}
561
562void Layer::drawWithOpenGL(
563 const sp<const DisplayDevice>& hw, const Region& clip) const {
564 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700565 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800566
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700567 computeGeometry(hw, mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800568
Mathias Agopian13127d82013-03-05 17:47:11 -0800569 /*
570 * NOTE: the way we compute the texture coordinates here produces
571 * different results than when we take the HWC path -- in the later case
572 * the "source crop" is rounded to texel boundaries.
573 * This can produce significantly different results when the texture
574 * is scaled by a large amount.
575 *
576 * The GL code below is more logical (imho), and the difference with
577 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700578 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800579 * GL composition when a buffer scaling is applied (maybe with some
580 * minimal value)? Or, we could make GL behave like HWC -- but this feel
581 * like more of a hack.
582 */
583 const Rect win(computeBounds());
584
Mathias Agopian3f844832013-08-07 21:24:32 -0700585 float left = float(win.left) / float(s.active.w);
586 float top = float(win.top) / float(s.active.h);
587 float right = float(win.right) / float(s.active.w);
588 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800589
Mathias Agopian875d8e12013-06-07 15:35:48 -0700590 // TODO: we probably want to generate the texture coords with the mesh
591 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700592 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
593 texCoords[0] = vec2(left, 1.0f - top);
594 texCoords[1] = vec2(left, 1.0f - bottom);
595 texCoords[2] = vec2(right, 1.0f - bottom);
596 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800597
Mathias Agopian875d8e12013-06-07 15:35:48 -0700598 RenderEngine& engine(mFlinger->getRenderEngine());
599 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700600 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700601 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800602}
603
604void Layer::setFiltering(bool filtering) {
605 mFiltering = filtering;
606}
607
608bool Layer::getFiltering() const {
609 return mFiltering;
610}
611
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800612// As documented in libhardware header, formats in the range
613// 0x100 - 0x1FF are specific to the HAL implementation, and
614// are known to have no alpha channel
615// TODO: move definition for device-specific range into
616// hardware.h, instead of using hard-coded values here.
617#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
618
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700619bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700620 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
621 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800622 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700623 switch (format) {
624 case HAL_PIXEL_FORMAT_RGBA_8888:
625 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700626 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700627 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700628 }
629 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700630 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800631}
632
Mathias Agopian13127d82013-03-05 17:47:11 -0800633// ----------------------------------------------------------------------------
634// local state
635// ----------------------------------------------------------------------------
636
Mathias Agopian3f844832013-08-07 21:24:32 -0700637void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800638{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700639 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800640 const Transform tr(hw->getTransform() * s.transform);
641 const uint32_t hw_h = hw->getHeight();
642 Rect win(s.active.w, s.active.h);
643 if (!s.active.crop.isEmpty()) {
644 win.intersect(s.active.crop, &win);
645 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700646 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700647 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700648
Mathias Agopianff2ed702013-09-01 21:36:12 -0700649 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
650 position[0] = tr.transform(win.left, win.top);
651 position[1] = tr.transform(win.left, win.bottom);
652 position[2] = tr.transform(win.right, win.bottom);
653 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700654 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700655 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800656 }
657}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800658
Mathias Agopiana67932f2011-04-20 14:20:59 -0700659bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700660{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700661 // if we don't have a buffer yet, we're translucent regardless of the
662 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700663 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700664 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700665 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700666
667 // if the layer has the opaque flag, then we're always opaque,
668 // otherwise we use the current buffer's format.
669 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700670}
671
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800672bool Layer::isProtected() const
673{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700674 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800675 return (activeBuffer != 0) &&
676 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
677}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700678
Mathias Agopian13127d82013-03-05 17:47:11 -0800679bool Layer::isFixedSize() const {
680 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
681}
682
683bool Layer::isCropped() const {
684 return !mCurrentCrop.isEmpty();
685}
686
687bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
688 return mNeedsFiltering || hw->needsFiltering();
689}
690
691void Layer::setVisibleRegion(const Region& visibleRegion) {
692 // always called from main thread
693 this->visibleRegion = visibleRegion;
694}
695
696void Layer::setCoveredRegion(const Region& coveredRegion) {
697 // always called from main thread
698 this->coveredRegion = coveredRegion;
699}
700
701void Layer::setVisibleNonTransparentRegion(const Region&
702 setVisibleNonTransparentRegion) {
703 // always called from main thread
704 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
705}
706
707// ----------------------------------------------------------------------------
708// transaction
709// ----------------------------------------------------------------------------
710
711uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800712 ATRACE_CALL();
713
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700714 const Layer::State& s(getDrawingState());
715 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800716
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700717 const bool sizeChanged = (c.requested.w != s.requested.w) ||
718 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700719
720 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700721 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000722 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700723 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700724 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
725 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
726 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
727 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700728 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
729 c.active.w, c.active.h,
730 c.active.crop.left,
731 c.active.crop.top,
732 c.active.crop.right,
733 c.active.crop.bottom,
734 c.active.crop.getWidth(),
735 c.active.crop.getHeight(),
736 c.requested.w, c.requested.h,
737 c.requested.crop.left,
738 c.requested.crop.top,
739 c.requested.crop.right,
740 c.requested.crop.bottom,
741 c.requested.crop.getWidth(),
742 c.requested.crop.getHeight(),
743 s.active.w, s.active.h,
744 s.active.crop.left,
745 s.active.crop.top,
746 s.active.crop.right,
747 s.active.crop.bottom,
748 s.active.crop.getWidth(),
749 s.active.crop.getHeight(),
750 s.requested.w, s.requested.h,
751 s.requested.crop.left,
752 s.requested.crop.top,
753 s.requested.crop.right,
754 s.requested.crop.bottom,
755 s.requested.crop.getWidth(),
756 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800757
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700758 // record the new size, form this point on, when the client request
759 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800760 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700761 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800762 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700763
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700764 if (!isFixedSize()) {
765
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700766 const bool resizePending = (c.requested.w != c.active.w) ||
767 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700768
769 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800770 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700771 // if we have a pending resize, unless we are in fixed-size mode.
772 // the drawing state will be updated only once we receive a buffer
773 // with the correct size.
774 //
775 // in particular, we want to make sure the clip (which is part
776 // of the geometry state) is latched together with the size but is
777 // latched immediately when no resizing is involved.
778
779 flags |= eDontUpdateGeometryState;
780 }
781 }
782
Mathias Agopian13127d82013-03-05 17:47:11 -0800783 // always set active to requested, unless we're asked not to
784 // this is used by Layer, which special cases resizes.
785 if (flags & eDontUpdateGeometryState) {
786 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700787 Layer::State& editCurrentState(getCurrentState());
788 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800789 }
790
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700791 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800792 // invalidate and recompute the visible regions if needed
793 flags |= Layer::eVisibleRegion;
794 }
795
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700796 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800797 // invalidate and recompute the visible regions if needed
798 flags |= eVisibleRegion;
799 this->contentDirty = true;
800
801 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700802 const uint8_t type = c.transform.getType();
803 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800804 (type >= Transform::SCALE));
805 }
806
807 // Commit the transaction
808 commitTransaction();
809 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800810}
811
Mathias Agopian13127d82013-03-05 17:47:11 -0800812void Layer::commitTransaction() {
813 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700814}
815
Mathias Agopian13127d82013-03-05 17:47:11 -0800816uint32_t Layer::getTransactionFlags(uint32_t flags) {
817 return android_atomic_and(~flags, &mTransactionFlags) & flags;
818}
819
820uint32_t Layer::setTransactionFlags(uint32_t flags) {
821 return android_atomic_or(flags, &mTransactionFlags);
822}
823
824bool Layer::setPosition(float x, float y) {
825 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
826 return false;
827 mCurrentState.sequence++;
828 mCurrentState.transform.set(x, y);
829 setTransactionFlags(eTransactionNeeded);
830 return true;
831}
832bool Layer::setLayer(uint32_t z) {
833 if (mCurrentState.z == z)
834 return false;
835 mCurrentState.sequence++;
836 mCurrentState.z = z;
837 setTransactionFlags(eTransactionNeeded);
838 return true;
839}
840bool Layer::setSize(uint32_t w, uint32_t h) {
841 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
842 return false;
843 mCurrentState.requested.w = w;
844 mCurrentState.requested.h = h;
845 setTransactionFlags(eTransactionNeeded);
846 return true;
847}
848bool Layer::setAlpha(uint8_t alpha) {
849 if (mCurrentState.alpha == alpha)
850 return false;
851 mCurrentState.sequence++;
852 mCurrentState.alpha = alpha;
853 setTransactionFlags(eTransactionNeeded);
854 return true;
855}
856bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
857 mCurrentState.sequence++;
858 mCurrentState.transform.set(
859 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
860 setTransactionFlags(eTransactionNeeded);
861 return true;
862}
863bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700864 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800865 setTransactionFlags(eTransactionNeeded);
866 return true;
867}
868bool Layer::setFlags(uint8_t flags, uint8_t mask) {
869 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
870 if (mCurrentState.flags == newFlags)
871 return false;
872 mCurrentState.sequence++;
873 mCurrentState.flags = newFlags;
874 setTransactionFlags(eTransactionNeeded);
875 return true;
876}
877bool Layer::setCrop(const Rect& crop) {
878 if (mCurrentState.requested.crop == crop)
879 return false;
880 mCurrentState.sequence++;
881 mCurrentState.requested.crop = crop;
882 setTransactionFlags(eTransactionNeeded);
883 return true;
884}
885
886bool Layer::setLayerStack(uint32_t layerStack) {
887 if (mCurrentState.layerStack == layerStack)
888 return false;
889 mCurrentState.sequence++;
890 mCurrentState.layerStack = layerStack;
891 setTransactionFlags(eTransactionNeeded);
892 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700893}
894
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800895// ----------------------------------------------------------------------------
896// pageflip handling...
897// ----------------------------------------------------------------------------
898
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800899bool Layer::onPreComposition() {
900 mRefreshPending = false;
901 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800902}
903
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700904void Layer::onPostComposition() {
905 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800906 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800907 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
908
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800909 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800910 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800911 mFrameTracker.setFrameReadyFence(frameReadyFence);
912 } else {
913 // There was no fence for this frame, so assume that it was ready
914 // to be presented at the desired present time.
915 mFrameTracker.setFrameReadyTime(desiredPresentTime);
916 }
917
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700918 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800919 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800920 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800921 mFrameTracker.setActualPresentFence(presentFence);
922 } else {
923 // The HWC doesn't support present fences, so use the refresh
924 // timestamp instead.
925 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
926 mFrameTracker.setActualPresentTime(presentTime);
927 }
928
929 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700930 mFrameLatencyNeeded = false;
931 }
932}
933
Mathias Agopianda27af92012-09-13 18:17:13 -0700934bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800935 const Layer::State& s(mDrawingState);
936 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
937 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700938}
939
Mathias Agopian4fec8732012-06-29 14:12:52 -0700940Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800941{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800942 ATRACE_CALL();
943
Mathias Agopian4fec8732012-06-29 14:12:52 -0700944 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700945 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800946
947 // if we've already called updateTexImage() without going through
948 // a composition step, we have to skip this layer at this point
949 // because we cannot call updateTeximage() without a corresponding
950 // compositionComplete() call.
951 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800952 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700953 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800954 }
955
Jamie Gennis351a5132011-09-14 18:23:37 -0700956 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700957 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700958 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700959
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800960 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700961 Layer::State& front;
962 Layer::State& current;
963 bool& recomputeVisibleRegions;
964 Reject(Layer::State& front, Layer::State& current,
965 bool& recomputeVisibleRegions)
966 : front(front), current(current),
967 recomputeVisibleRegions(recomputeVisibleRegions) {
968 }
969
970 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700971 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700972 if (buf == NULL) {
973 return false;
974 }
975
976 uint32_t bufWidth = buf->getWidth();
977 uint32_t bufHeight = buf->getHeight();
978
979 // check that we received a buffer of the right size
980 // (Take the buffer's orientation into account)
981 if (item.mTransform & Transform::ROT_90) {
982 swap(bufWidth, bufHeight);
983 }
984
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700985 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
986 if (front.active != front.requested) {
987
988 if (isFixedSize ||
989 (bufWidth == front.requested.w &&
990 bufHeight == front.requested.h))
991 {
992 // Here we pretend the transaction happened by updating the
993 // current and drawing states. Drawing state is only accessed
994 // in this thread, no need to have it locked
995 front.active = front.requested;
996
997 // We also need to update the current state so that
998 // we don't end-up overwriting the drawing state with
999 // this stale current state during the next transaction
1000 //
1001 // NOTE: We don't need to hold the transaction lock here
1002 // because State::active is only accessed from this thread.
1003 current.active = front.active;
1004
1005 // recompute visible region
1006 recomputeVisibleRegions = true;
1007 }
1008
1009 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001010 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001011 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1012 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001013 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001014 front.active.w, front.active.h,
1015 front.active.crop.left,
1016 front.active.crop.top,
1017 front.active.crop.right,
1018 front.active.crop.bottom,
1019 front.active.crop.getWidth(),
1020 front.active.crop.getHeight(),
1021 front.requested.w, front.requested.h,
1022 front.requested.crop.left,
1023 front.requested.crop.top,
1024 front.requested.crop.right,
1025 front.requested.crop.bottom,
1026 front.requested.crop.getWidth(),
1027 front.requested.crop.getHeight());
1028 }
1029
1030 if (!isFixedSize) {
1031 if (front.active.w != bufWidth ||
1032 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001033 // reject this buffer
Mathias Agopian4ceff3d2013-08-21 15:23:15 -07001034 //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1035 // bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001036 return true;
1037 }
1038 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001039
1040 // if the transparent region has changed (this test is
1041 // conservative, but that's fine, worst case we're doing
1042 // a bit of extra work), we latch the new one and we
1043 // trigger a visible-region recompute.
1044 if (!front.activeTransparentRegion.isTriviallyEqual(
1045 front.requestedTransparentRegion)) {
1046 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001047
1048 // We also need to update the current state so that
1049 // we don't end-up overwriting the drawing state with
1050 // this stale current state during the next transaction
1051 //
1052 // NOTE: We don't need to hold the transaction lock here
1053 // because State::active is only accessed from this thread.
1054 current.activeTransparentRegion = front.activeTransparentRegion;
1055
1056 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001057 recomputeVisibleRegions = true;
1058 }
1059
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001060 return false;
1061 }
1062 };
1063
1064
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001065 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001066
Andy McFadden1585c4d2013-06-28 13:52:40 -07001067 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1068 if (updateResult == BufferQueue::PRESENT_LATER) {
1069 // Producer doesn't want buffer to be displayed yet. Signal a
1070 // layer update so we check again at the next opportunity.
1071 mFlinger->signalLayerUpdate();
1072 return outDirtyRegion;
1073 }
1074
1075 // Decrement the queued-frames count. Signal another event if we
1076 // have more frames pending.
1077 if (android_atomic_dec(&mQueuedFrames) > 1) {
1078 mFlinger->signalLayerUpdate();
1079 }
1080
1081 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001082 // something happened!
1083 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001084 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001085 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001086
Jamie Gennis351a5132011-09-14 18:23:37 -07001087 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001088 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001089 if (mActiveBuffer == NULL) {
1090 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001091 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001092 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001093
Mathias Agopian4824d402012-06-04 18:16:30 -07001094 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001095 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001096 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001097 // the first time we receive a buffer, we need to trigger a
1098 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001099 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001100 }
1101
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001102 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1103 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1104 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001105 if ((crop != mCurrentCrop) ||
1106 (transform != mCurrentTransform) ||
1107 (scalingMode != mCurrentScalingMode))
1108 {
1109 mCurrentCrop = crop;
1110 mCurrentTransform = transform;
1111 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001112 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001113 }
1114
1115 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001116 uint32_t bufWidth = mActiveBuffer->getWidth();
1117 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001118 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1119 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001120 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001121 }
1122 }
1123
1124 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1125 if (oldOpacity != isOpaque()) {
1126 recomputeVisibleRegions = true;
1127 }
1128
Mathias Agopian4fec8732012-06-29 14:12:52 -07001129 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001130 const Layer::State& s(getDrawingState());
1131 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001132
1133 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001134 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001135 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001136 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001137}
1138
Mathias Agopiana67932f2011-04-20 14:20:59 -07001139uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001140{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001141 // TODO: should we do something special if mSecure is set?
1142 if (mProtectedByApp) {
1143 // need a hardware-protected path to external video sink
1144 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001145 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001146 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001147 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001148}
1149
Mathias Agopian84300952012-11-21 16:02:13 -08001150void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001151 uint32_t orientation = 0;
1152 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001153 // The transform hint is used to improve performance, but we can
1154 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001155 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001156 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001157 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001158 if (orientation & Transform::ROT_INVALID) {
1159 orientation = 0;
1160 }
1161 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001162 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001163}
1164
Mathias Agopian13127d82013-03-05 17:47:11 -08001165// ----------------------------------------------------------------------------
1166// debugging
1167// ----------------------------------------------------------------------------
1168
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001169void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001170{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001171 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001172
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001173 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001174 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001175 "+ %s %p (%s)\n",
1176 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001177 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001178
Mathias Agopian2ca79392013-04-02 18:30:32 -07001179 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001180 visibleRegion.dump(result, "visibleRegion");
1181 sp<Client> client(mClientRef.promote());
1182
Mathias Agopian74d211a2013-04-22 16:55:35 +02001183 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001184 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1185 "isOpaque=%1d, invalidate=%1d, "
1186 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1187 " client=%p\n",
1188 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1189 s.active.crop.left, s.active.crop.top,
1190 s.active.crop.right, s.active.crop.bottom,
1191 isOpaque(), contentDirty,
1192 s.alpha, s.flags,
1193 s.transform[0][0], s.transform[0][1],
1194 s.transform[1][0], s.transform[1][1],
1195 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001196
1197 sp<const GraphicBuffer> buf0(mActiveBuffer);
1198 uint32_t w0=0, h0=0, s0=0, f0=0;
1199 if (buf0 != 0) {
1200 w0 = buf0->getWidth();
1201 h0 = buf0->getHeight();
1202 s0 = buf0->getStride();
1203 f0 = buf0->format;
1204 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001205 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001206 " "
1207 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1208 " queued-frames=%d, mRefreshPending=%d\n",
1209 mFormat, w0, h0, s0,f0,
1210 mQueuedFrames, mRefreshPending);
1211
Mathias Agopian13127d82013-03-05 17:47:11 -08001212 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001213 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001214 }
1215}
1216
Mathias Agopian74d211a2013-04-22 16:55:35 +02001217void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001218 mFrameTracker.dump(result);
1219}
1220
1221void Layer::clearStats() {
1222 mFrameTracker.clear();
1223}
1224
Jamie Gennis6547ff42013-07-16 20:12:42 -07001225void Layer::logFrameStats() {
1226 mFrameTracker.logAndResetStats(mName);
1227}
1228
Mathias Agopian13127d82013-03-05 17:47:11 -08001229// ---------------------------------------------------------------------------
1230
1231Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1232 const sp<Layer>& layer)
1233 : mFlinger(flinger), mLayer(layer) {
1234}
1235
1236Layer::LayerCleaner::~LayerCleaner() {
1237 // destroy client resources
1238 mFlinger->onLayerDestroyed(mLayer);
1239}
1240
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001241// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001242}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001243
1244#if defined(__gl_h_)
1245#error "don't include gl/gl.h in this file"
1246#endif
1247
1248#if defined(__gl2_h_)
1249#error "don't include gl2/gl2.h in this file"
1250#endif