blob: b08b8d104a44bf8841bd44013c684238ac4d83e2 [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"
Mathias Agopian1f7bec62010-06-25 18:02:21 -070041#include "GLExtensions.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043#include "SurfaceFlinger.h"
Mathias Agopiana67932f2011-04-20 14:20:59 -070044#include "SurfaceTextureLayer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045
Mathias Agopian1b031492012-06-20 17:51:20 -070046#include "DisplayHardware/HWComposer.h"
47
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#define DEBUG_RESIZE 0
49
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050namespace android {
51
52// ---------------------------------------------------------------------------
53
Mathias Agopian13127d82013-03-05 17:47:11 -080054int32_t Layer::sSequence = 1;
55
Mathias Agopian4d9b8222013-03-12 17:11:48 -070056Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
57 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080058 : contentDirty(false),
59 sequence(uint32_t(android_atomic_inc(&sSequence))),
60 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070061 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080062 mPremultipliedAlpha(true),
63 mName("unnamed"),
64 mDebug(false),
65 mFormat(PIXEL_FORMAT_NONE),
66 mGLExtensions(GLExtensions::getInstance()),
67 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 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();
83 glGenTextures(1, &mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070084
85 uint32_t layerFlags = 0;
86 if (flags & ISurfaceComposerClient::eHidden)
87 layerFlags = layer_state_t::eLayerHidden;
88
89 if (flags & ISurfaceComposerClient::eNonPremultiplied)
90 mPremultipliedAlpha = false;
91
92 mName = name;
93
94 mCurrentState.active.w = w;
95 mCurrentState.active.h = h;
96 mCurrentState.active.crop.makeInvalid();
97 mCurrentState.z = 0;
98 mCurrentState.alpha = 0xFF;
99 mCurrentState.layerStack = 0;
100 mCurrentState.flags = layerFlags;
101 mCurrentState.sequence = 0;
102 mCurrentState.transform.set(0, 0);
103 mCurrentState.requested = mCurrentState.active;
104
105 // drawing state & current state are identical
106 mDrawingState = mCurrentState;
Jamie Gennise8696a42012-01-15 18:54:57 -0800107}
108
Mathias Agopiana67932f2011-04-20 14:20:59 -0700109void Layer::onFirstRef()
Mathias Agopian96f08192010-06-02 23:28:45 -0700110{
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800111 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopian67106042013-03-14 19:18:13 -0700112 sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800113 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
Mathias Agopiana0db3082012-04-23 13:59:36 -0700114 GL_TEXTURE_EXTERNAL_OES, false, bq);
Daniel Lamb2675792012-02-23 14:35:13 -0800115
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800116 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
118 mSurfaceFlingerConsumer->setSynchronousMode(true);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700119 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800120
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700121#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
122#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800123 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700124#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800126#endif
Andy McFadden69052052012-09-14 16:10:11 -0700127
Mathias Agopian84300952012-11-21 16:02:13 -0800128 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
129 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700130}
131
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700132Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800133 sp<Client> c(mClientRef.promote());
134 if (c != 0) {
135 c->detachLayer(this);
136 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700137 mFlinger->deleteTextureAsync(mTextureName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700138}
139
Mathias Agopian13127d82013-03-05 17:47:11 -0800140// ---------------------------------------------------------------------------
141// callbacks
142// ---------------------------------------------------------------------------
143
144void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
145 HWComposer::HWCLayerInterface* layer) {
146 if (layer) {
147 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700148 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800149 }
150}
151
Igor Murashkina4a31492012-10-29 13:36:11 -0700152void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700153 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800154 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700155}
156
Mathias Agopian67106042013-03-14 19:18:13 -0700157// called with SurfaceFlinger::mStateLock from the drawing thread after
158// the layer has been remove from the current state list (and just before
159// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800160void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800161 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700162}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700163
Mathias Agopian13127d82013-03-05 17:47:11 -0800164// ---------------------------------------------------------------------------
165// set-up
166// ---------------------------------------------------------------------------
167
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700168const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800169 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800170}
171
Mathias Agopianf9d93272009-06-19 17:00:27 -0700172status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800173 PixelFormat format, uint32_t flags)
174{
Mathias Agopian401c2572009-09-23 19:16:27 -0700175 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800176 PixelFormatInfo info;
177 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800178 if (err) {
179 ALOGE("unsupported pixelformat %d", format);
180 return err;
181 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800182
Mathias Agopianca99fb82010-04-14 16:43:44 -0700183 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700184 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700185
186 // never allow a surface larger than what our underlying GL implementation
187 // can handle.
188 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800189 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700190 return BAD_VALUE;
191 }
192
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700193 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700194
Mathias Agopian3165cc22012-08-08 19:42:09 -0700195 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
196 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
197 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700198 mCurrentOpacity = getOpacityForFormat(format);
199
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800200 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
201 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
202 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700203
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800204 return NO_ERROR;
205}
206
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700207sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800208 Mutex::Autolock _l(mLock);
209
210 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700211 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800212
213 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700214
215 /*
216 * The layer handle is just a BBinder object passed to the client
217 * (remote process) -- we don't keep any reference on our side such that
218 * the dtor is called when the remote side let go of its reference.
219 *
220 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
221 * this layer when the handle is destroyed.
222 */
223
224 class Handle : public BBinder, public LayerCleaner {
225 wp<const Layer> mOwner;
226 public:
227 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
228 : LayerCleaner(flinger, layer), mOwner(layer) {
229 }
230 };
231
232 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800233}
234
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700235sp<BufferQueue> Layer::getBufferQueue() const {
236 return mSurfaceFlingerConsumer->getBufferQueue();
237}
238
239//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
240// sp<IGraphicBufferProducer> res;
241// sp<const Layer> that( mOwner.promote() );
242// if (that != NULL) {
243// res = that->mSurfaceFlingerConsumer->getBufferQueue();
244// }
245// return res;
246//}
247
Mathias Agopian13127d82013-03-05 17:47:11 -0800248// ---------------------------------------------------------------------------
249// h/w composer set-up
250// ---------------------------------------------------------------------------
251
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800252Rect Layer::getContentCrop() const {
253 // this is the crop rectangle that applies to the buffer
254 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700255 Rect crop;
256 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800257 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700258 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800259 } else if (mActiveBuffer != NULL) {
260 // otherwise we use the whole buffer
261 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700262 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800263 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700264 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700265 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700266 return crop;
267}
268
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800269uint32_t Layer::getContentTransform() const {
270 return mCurrentTransform;
271}
272
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700273static Rect reduce(const Rect& win, const Region& exclude) {
274 if (CC_LIKELY(exclude.isEmpty())) {
275 return win;
276 }
277 if (exclude.isRect()) {
278 return win.reduce(exclude.getBounds());
279 }
280 return Region(win).subtract(exclude).getBounds();
281}
282
Mathias Agopian13127d82013-03-05 17:47:11 -0800283Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700284 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800285 Rect win(s.active.w, s.active.h);
286 if (!s.active.crop.isEmpty()) {
287 win.intersect(s.active.crop, &win);
288 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700289 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700290 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800291}
292
293Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
294 /*
295 * The way we compute the crop (aka. texture coordinates when we have a
296 * Layer) produces a different output from the GL code in
297 * drawWithOpenGL() due to HWC being limited to integers. The difference
298 * can be large if getContentTransform() contains a large scale factor.
299 * See comments in drawWithOpenGL() for more details.
300 */
301
302 // the content crop is the area of the content that gets scaled to the
303 // layer's size.
304 Rect crop(getContentCrop());
305
306 // the active.crop is the area of the window that gets cropped, but not
307 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700308 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800309
310 // apply the projection's clipping to the window crop in
311 // layerstack space, and convert-back to layer space.
312 // if there are no window scaling (or content scaling) involved,
313 // this operation will map to full pixels in the buffer.
314 // NOTE: should we revert to GL composition if a scaling is involved
315 // since it cannot be represented in the HWC API?
316 Rect activeCrop(s.transform.transform(s.active.crop));
317 activeCrop.intersect(hw->getViewport(), &activeCrop);
318 activeCrop = s.transform.inverse().transform(activeCrop);
319
320 // paranoia: make sure the window-crop is constrained in the
321 // window's bounds
322 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
323
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700324 // subtract the transparent region and snap to the bounds
325 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
326
Mathias Agopian13127d82013-03-05 17:47:11 -0800327 if (!activeCrop.isEmpty()) {
328 // Transform the window crop to match the buffer coordinate system,
329 // which means using the inverse of the current transform set on the
330 // SurfaceFlingerConsumer.
331 uint32_t invTransform = getContentTransform();
332 int winWidth = s.active.w;
333 int winHeight = s.active.h;
334 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
335 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
336 NATIVE_WINDOW_TRANSFORM_FLIP_H;
337 winWidth = s.active.h;
338 winHeight = s.active.w;
339 }
340 const Rect winCrop = activeCrop.transform(
341 invTransform, s.active.w, s.active.h);
342
343 // the code below essentially performs a scaled intersection
344 // of crop and winCrop
345 float xScale = float(crop.width()) / float(winWidth);
346 float yScale = float(crop.height()) / float(winHeight);
347
348 int insetL = int(ceilf( winCrop.left * xScale));
349 int insetT = int(ceilf( winCrop.top * yScale));
350 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
351 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
352
353 crop.left += insetL;
354 crop.top += insetT;
355 crop.right -= insetR;
356 crop.bottom -= insetB;
357 }
358 return crop;
359}
360
Mathias Agopian4fec8732012-06-29 14:12:52 -0700361void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700362 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700363 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700364{
Mathias Agopian13127d82013-03-05 17:47:11 -0800365 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700366
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700367 // enable this layer
368 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700369
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700370 if (isSecure() && !hw->isSecure()) {
371 layer.setSkip(true);
372 }
373
Mathias Agopian13127d82013-03-05 17:47:11 -0800374 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700375 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800376 if (!isOpaque() || s.alpha != 0xFF) {
377 layer.setBlending(mPremultipliedAlpha ?
378 HWC_BLENDING_PREMULT :
379 HWC_BLENDING_COVERAGE);
380 }
381
382 // apply the layer's transform, followed by the display's global transform
383 // here we're guaranteed that the layer's transform preserves rects
384 Rect frame(s.transform.transform(computeBounds()));
385 frame.intersect(hw->getViewport(), &frame);
386 const Transform& tr(hw->getTransform());
387 layer.setFrame(tr.transform(frame));
388 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800389 layer.setPlaneAlpha(s.alpha);
390
Mathias Agopian29a367b2011-07-12 14:51:45 -0700391 /*
392 * Transformations are applied in this order:
393 * 1) buffer orientation/flip/mirror
394 * 2) state transformation (window manager)
395 * 3) layer orientation (screen orientation)
396 * (NOTE: the matrices are multiplied in reverse order)
397 */
398
399 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800400 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700401
402 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800403 const uint32_t orientation = transform.getOrientation();
404 if (orientation & Transform::ROT_INVALID) {
405 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700406 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700407 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800408 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700409 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700410}
411
Mathias Agopian42977342012-08-05 00:40:46 -0700412void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700413 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800414 // we have to set the visible region on every frame because
415 // we currently free it during onLayerDisplayed(), which is called
416 // after HWComposer::commit() -- every frame.
417 // Apply this display's projection's viewport to the visible region
418 // before giving it to the HWC HAL.
419 const Transform& tr = hw->getTransform();
420 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
421 layer.setVisibleRegionScreen(visible);
422
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700423 // NOTE: buffer can be NULL if the client never drew into this
424 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700425 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700426}
Jesse Halldc5b4852012-06-29 15:21:18 -0700427
Mathias Agopian42977342012-08-05 00:40:46 -0700428void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700429 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700430 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700431
432 // TODO: there is a possible optimization here: we only need to set the
433 // acquire fence the first time a new buffer is acquired on EACH display.
434
435 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800436 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800437 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700438 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700439 if (fenceFd == -1) {
440 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
441 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700442 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700443 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700444 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700445}
446
Mathias Agopian13127d82013-03-05 17:47:11 -0800447// ---------------------------------------------------------------------------
448// drawing...
449// ---------------------------------------------------------------------------
450
451void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
452 onDraw(hw, clip);
453}
454
455void Layer::draw(const sp<const DisplayDevice>& hw) {
456 onDraw( hw, Region(hw->bounds()) );
457}
458
Mathias Agopian42977342012-08-05 00:40:46 -0700459void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800460{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800461 ATRACE_CALL();
462
Mathias Agopiana67932f2011-04-20 14:20:59 -0700463 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800464 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700465 // in fact never been drawn into. This happens frequently with
466 // SurfaceView because the WindowManager can't know when the client
467 // has drawn the first time.
468
469 // If there is nothing under us, we paint the screen in black, otherwise
470 // we just skip this update.
471
472 // figure out if there is something below us
473 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700474 const SurfaceFlinger::LayerVector& drawingLayers(
475 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700476 const size_t count = drawingLayers.size();
477 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800478 const sp<Layer>& layer(drawingLayers[i]);
479 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700480 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700481 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700482 }
483 // if not everything below us is covered, we plug the holes!
484 Region holes(clip.subtract(under));
485 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700486 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700487 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800488 return;
489 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700490
Andy McFadden97eba892012-12-11 15:21:45 -0800491 // Bind the current buffer to the GL texture, and wait for it to be
492 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800493 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
494 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800495 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700496 // Go ahead and draw the buffer anyway; no matter what we do the screen
497 // is probably going to have something visibly wrong.
498 }
499
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700500 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
501
502 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700503 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700504 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700505
506 // Query the texture matrix given our current filtering mode.
507 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800508 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
509 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700510
511 // Set things up for texturing.
Mathias Agopianc492e672011-10-18 14:49:27 -0700512 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
513 GLenum filter = GL_NEAREST;
Jamie Genniscbb1a952012-05-08 17:05:52 -0700514 if (useFiltering) {
Mathias Agopianc492e672011-10-18 14:49:27 -0700515 filter = GL_LINEAR;
Jamie Gennis9575f602011-10-07 14:51:16 -0700516 }
Mathias Agopianc492e672011-10-18 14:49:27 -0700517 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
518 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
Jamie Gennis9575f602011-10-07 14:51:16 -0700519 glMatrixMode(GL_TEXTURE);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700520 glLoadMatrixf(textureMatrix);
Jamie Gennis9575f602011-10-07 14:51:16 -0700521 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700522 glDisable(GL_TEXTURE_2D);
Xavier Ducrohet4c4163b2011-10-21 16:18:48 -0700523 glEnable(GL_TEXTURE_EXTERNAL_OES);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700524 } else {
Mathias Agopianc492e672011-10-18 14:49:27 -0700525 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
Jamie Gennis9575f602011-10-07 14:51:16 -0700526 glMatrixMode(GL_TEXTURE);
527 glLoadIdentity();
528 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700529 glDisable(GL_TEXTURE_EXTERNAL_OES);
530 glEnable(GL_TEXTURE_2D);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700531 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700532
Mathias Agopian1b031492012-06-20 17:51:20 -0700533 drawWithOpenGL(hw, clip);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700534
Mathias Agopianc492e672011-10-18 14:49:27 -0700535 glDisable(GL_TEXTURE_EXTERNAL_OES);
536 glDisable(GL_TEXTURE_2D);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800537}
538
Mathias Agopian13127d82013-03-05 17:47:11 -0800539
540void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
541 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
542{
543 const uint32_t fbHeight = hw->getHeight();
544 glColor4f(red,green,blue,alpha);
545
546 glDisable(GL_TEXTURE_EXTERNAL_OES);
547 glDisable(GL_TEXTURE_2D);
548 glDisable(GL_BLEND);
549
550 LayerMesh mesh;
551 computeGeometry(hw, &mesh);
552
553 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
554 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
555}
556
557void Layer::clearWithOpenGL(
558 const sp<const DisplayDevice>& hw, const Region& clip) const {
559 clearWithOpenGL(hw, clip, 0,0,0,0);
560}
561
Jesse Hall29c3f352013-05-21 15:36:55 -0700562static void setupOpenGL10(bool premultipliedAlpha, bool opaque, int alpha) {
563 // OpenGL ES 1.0 doesn't support texture combiners.
564 // This path doesn't properly handle opaque layers that have non-opaque
565 // alpha values. The alpha channel will be copied into the framebuffer or
566 // screenshot, so if the framebuffer or screenshot is blended on top of
567 // something else, whatever is below the window will incorrectly show
568 // through.
569 if (CC_UNLIKELY(alpha < 0xFF)) {
570 GLfloat floatAlpha = alpha * (1.0f / 255.0f);
571 if (premultipliedAlpha) {
572 glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
573 } else {
574 glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
575 }
576 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
577 } else {
578 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
579 }
580}
581
582static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) {
583 GLenum combineRGB;
584 GLenum combineAlpha;
585 GLenum src0Alpha;
586 GLfloat envColor[4];
587
588 if (CC_UNLIKELY(alpha < 0xFF)) {
589 // Cv = premultiplied ? Cs*alpha : Cs
590 // Av = !opaque ? alpha*As : 1.0
591 combineRGB = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
592 combineAlpha = !opaque ? GL_MODULATE : GL_REPLACE;
593 src0Alpha = GL_CONSTANT;
594 envColor[0] = alpha * (1.0f / 255.0f);
595 } else {
596 // Cv = Cs
597 // Av = opaque ? 1.0 : As
598 combineRGB = GL_REPLACE;
599 combineAlpha = GL_REPLACE;
600 src0Alpha = opaque ? GL_CONSTANT : GL_TEXTURE;
601 envColor[0] = 1.0f;
602 }
603
604 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
605 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB);
606 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
607 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
608 if (combineRGB == GL_MODULATE) {
609 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
610 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
611 }
612 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha);
613 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha);
614 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
615 if (combineAlpha == GL_MODULATE) {
616 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
617 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
618 }
619 if (combineRGB == GL_MODULATE || src0Alpha == GL_CONSTANT) {
620 envColor[1] = envColor[0];
621 envColor[2] = envColor[0];
622 envColor[3] = envColor[0];
623 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
624 }
625}
626
Mathias Agopian13127d82013-03-05 17:47:11 -0800627void Layer::drawWithOpenGL(
628 const sp<const DisplayDevice>& hw, const Region& clip) const {
629 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700630 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800631
Jesse Hall29c3f352013-05-21 15:36:55 -0700632 if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) {
633 setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800634 } else {
Jesse Hall29c3f352013-05-21 15:36:55 -0700635 setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha);
636 }
637
638 if (s.alpha < 0xFF || !isOpaque()) {
639 glEnable(GL_BLEND);
640 glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
641 GL_ONE_MINUS_SRC_ALPHA);
642 } else {
643 glDisable(GL_BLEND);
Mathias Agopian13127d82013-03-05 17:47:11 -0800644 }
645
646 LayerMesh mesh;
647 computeGeometry(hw, &mesh);
648
649 // TODO: we probably want to generate the texture coords with the mesh
650 // here we assume that we only have 4 vertices
651
652 struct TexCoords {
653 GLfloat u;
654 GLfloat v;
655 };
656
657
658 /*
659 * NOTE: the way we compute the texture coordinates here produces
660 * different results than when we take the HWC path -- in the later case
661 * the "source crop" is rounded to texel boundaries.
662 * This can produce significantly different results when the texture
663 * is scaled by a large amount.
664 *
665 * The GL code below is more logical (imho), and the difference with
666 * HWC is due to a limitation of the HWC API to integers -- a question
667 * is suspend is wether we should ignore this problem or revert to
668 * GL composition when a buffer scaling is applied (maybe with some
669 * minimal value)? Or, we could make GL behave like HWC -- but this feel
670 * like more of a hack.
671 */
672 const Rect win(computeBounds());
673
674 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
675 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
676 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
677 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
678
679 TexCoords texCoords[4];
680 texCoords[0].u = left;
681 texCoords[0].v = top;
682 texCoords[1].u = left;
683 texCoords[1].v = bottom;
684 texCoords[2].u = right;
685 texCoords[2].v = bottom;
686 texCoords[3].u = right;
687 texCoords[3].v = top;
688 for (int i = 0; i < 4; i++) {
689 texCoords[i].v = 1.0f - texCoords[i].v;
690 }
691
692 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
693 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
694 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
695 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
696
697 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
698 glDisable(GL_BLEND);
699}
700
701void Layer::setFiltering(bool filtering) {
702 mFiltering = filtering;
703}
704
705bool Layer::getFiltering() const {
706 return mFiltering;
707}
708
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800709// As documented in libhardware header, formats in the range
710// 0x100 - 0x1FF are specific to the HAL implementation, and
711// are known to have no alpha channel
712// TODO: move definition for device-specific range into
713// hardware.h, instead of using hard-coded values here.
714#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
715
Mathias Agopiana67932f2011-04-20 14:20:59 -0700716bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800717{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700718 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
719 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800720 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700721 PixelFormatInfo info;
722 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
723 // in case of error (unknown format), we assume no blending
724 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800725}
726
Mathias Agopian13127d82013-03-05 17:47:11 -0800727// ----------------------------------------------------------------------------
728// local state
729// ----------------------------------------------------------------------------
730
731void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
732{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700733 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800734 const Transform tr(hw->getTransform() * s.transform);
735 const uint32_t hw_h = hw->getHeight();
736 Rect win(s.active.w, s.active.h);
737 if (!s.active.crop.isEmpty()) {
738 win.intersect(s.active.crop, &win);
739 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700740 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700741 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800742 if (mesh) {
743 tr.transform(mesh->mVertices[0], win.left, win.top);
744 tr.transform(mesh->mVertices[1], win.left, win.bottom);
745 tr.transform(mesh->mVertices[2], win.right, win.bottom);
746 tr.transform(mesh->mVertices[3], win.right, win.top);
747 for (size_t i=0 ; i<4 ; i++) {
748 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
749 }
750 }
751}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800752
Mathias Agopiana67932f2011-04-20 14:20:59 -0700753bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700754{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700755 // if we don't have a buffer yet, we're translucent regardless of the
756 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700757 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700758 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700759 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700760
761 // if the layer has the opaque flag, then we're always opaque,
762 // otherwise we use the current buffer's format.
763 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700764}
765
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800766bool Layer::isProtected() const
767{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700768 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800769 return (activeBuffer != 0) &&
770 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
771}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700772
Mathias Agopian13127d82013-03-05 17:47:11 -0800773bool Layer::isFixedSize() const {
774 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
775}
776
777bool Layer::isCropped() const {
778 return !mCurrentCrop.isEmpty();
779}
780
781bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
782 return mNeedsFiltering || hw->needsFiltering();
783}
784
785void Layer::setVisibleRegion(const Region& visibleRegion) {
786 // always called from main thread
787 this->visibleRegion = visibleRegion;
788}
789
790void Layer::setCoveredRegion(const Region& coveredRegion) {
791 // always called from main thread
792 this->coveredRegion = coveredRegion;
793}
794
795void Layer::setVisibleNonTransparentRegion(const Region&
796 setVisibleNonTransparentRegion) {
797 // always called from main thread
798 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
799}
800
801// ----------------------------------------------------------------------------
802// transaction
803// ----------------------------------------------------------------------------
804
805uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800806 ATRACE_CALL();
807
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700808 const Layer::State& s(getDrawingState());
809 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800810
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700811 const bool sizeChanged = (c.requested.w != s.requested.w) ||
812 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700813
814 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700815 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000816 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700817 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700818 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
819 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
820 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
821 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700822 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
823 c.active.w, c.active.h,
824 c.active.crop.left,
825 c.active.crop.top,
826 c.active.crop.right,
827 c.active.crop.bottom,
828 c.active.crop.getWidth(),
829 c.active.crop.getHeight(),
830 c.requested.w, c.requested.h,
831 c.requested.crop.left,
832 c.requested.crop.top,
833 c.requested.crop.right,
834 c.requested.crop.bottom,
835 c.requested.crop.getWidth(),
836 c.requested.crop.getHeight(),
837 s.active.w, s.active.h,
838 s.active.crop.left,
839 s.active.crop.top,
840 s.active.crop.right,
841 s.active.crop.bottom,
842 s.active.crop.getWidth(),
843 s.active.crop.getHeight(),
844 s.requested.w, s.requested.h,
845 s.requested.crop.left,
846 s.requested.crop.top,
847 s.requested.crop.right,
848 s.requested.crop.bottom,
849 s.requested.crop.getWidth(),
850 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800851
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700852 // record the new size, form this point on, when the client request
853 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800854 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700855 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800856 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700857
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700858 if (!isFixedSize()) {
859
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700860 const bool resizePending = (c.requested.w != c.active.w) ||
861 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700862
863 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800864 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700865 // if we have a pending resize, unless we are in fixed-size mode.
866 // the drawing state will be updated only once we receive a buffer
867 // with the correct size.
868 //
869 // in particular, we want to make sure the clip (which is part
870 // of the geometry state) is latched together with the size but is
871 // latched immediately when no resizing is involved.
872
873 flags |= eDontUpdateGeometryState;
874 }
875 }
876
Mathias Agopian13127d82013-03-05 17:47:11 -0800877 // always set active to requested, unless we're asked not to
878 // this is used by Layer, which special cases resizes.
879 if (flags & eDontUpdateGeometryState) {
880 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700881 Layer::State& editCurrentState(getCurrentState());
882 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800883 }
884
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700885 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800886 // invalidate and recompute the visible regions if needed
887 flags |= Layer::eVisibleRegion;
888 }
889
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700890 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800891 // invalidate and recompute the visible regions if needed
892 flags |= eVisibleRegion;
893 this->contentDirty = true;
894
895 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700896 const uint8_t type = c.transform.getType();
897 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800898 (type >= Transform::SCALE));
899 }
900
901 // Commit the transaction
902 commitTransaction();
903 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800904}
905
Mathias Agopian13127d82013-03-05 17:47:11 -0800906void Layer::commitTransaction() {
907 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700908}
909
Mathias Agopian13127d82013-03-05 17:47:11 -0800910uint32_t Layer::getTransactionFlags(uint32_t flags) {
911 return android_atomic_and(~flags, &mTransactionFlags) & flags;
912}
913
914uint32_t Layer::setTransactionFlags(uint32_t flags) {
915 return android_atomic_or(flags, &mTransactionFlags);
916}
917
918bool Layer::setPosition(float x, float y) {
919 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
920 return false;
921 mCurrentState.sequence++;
922 mCurrentState.transform.set(x, y);
923 setTransactionFlags(eTransactionNeeded);
924 return true;
925}
926bool Layer::setLayer(uint32_t z) {
927 if (mCurrentState.z == z)
928 return false;
929 mCurrentState.sequence++;
930 mCurrentState.z = z;
931 setTransactionFlags(eTransactionNeeded);
932 return true;
933}
934bool Layer::setSize(uint32_t w, uint32_t h) {
935 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
936 return false;
937 mCurrentState.requested.w = w;
938 mCurrentState.requested.h = h;
939 setTransactionFlags(eTransactionNeeded);
940 return true;
941}
942bool Layer::setAlpha(uint8_t alpha) {
943 if (mCurrentState.alpha == alpha)
944 return false;
945 mCurrentState.sequence++;
946 mCurrentState.alpha = alpha;
947 setTransactionFlags(eTransactionNeeded);
948 return true;
949}
950bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
951 mCurrentState.sequence++;
952 mCurrentState.transform.set(
953 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
954 setTransactionFlags(eTransactionNeeded);
955 return true;
956}
957bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700958 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800959 setTransactionFlags(eTransactionNeeded);
960 return true;
961}
962bool Layer::setFlags(uint8_t flags, uint8_t mask) {
963 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
964 if (mCurrentState.flags == newFlags)
965 return false;
966 mCurrentState.sequence++;
967 mCurrentState.flags = newFlags;
968 setTransactionFlags(eTransactionNeeded);
969 return true;
970}
971bool Layer::setCrop(const Rect& crop) {
972 if (mCurrentState.requested.crop == crop)
973 return false;
974 mCurrentState.sequence++;
975 mCurrentState.requested.crop = crop;
976 setTransactionFlags(eTransactionNeeded);
977 return true;
978}
979
980bool Layer::setLayerStack(uint32_t layerStack) {
981 if (mCurrentState.layerStack == layerStack)
982 return false;
983 mCurrentState.sequence++;
984 mCurrentState.layerStack = layerStack;
985 setTransactionFlags(eTransactionNeeded);
986 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700987}
988
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800989// ----------------------------------------------------------------------------
990// pageflip handling...
991// ----------------------------------------------------------------------------
992
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800993bool Layer::onPreComposition() {
994 mRefreshPending = false;
995 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800996}
997
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700998void Layer::onPostComposition() {
999 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001000 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001001 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1002
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001003 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001004 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001005 mFrameTracker.setFrameReadyFence(frameReadyFence);
1006 } else {
1007 // There was no fence for this frame, so assume that it was ready
1008 // to be presented at the desired present time.
1009 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1010 }
1011
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001012 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001013 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001014 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001015 mFrameTracker.setActualPresentFence(presentFence);
1016 } else {
1017 // The HWC doesn't support present fences, so use the refresh
1018 // timestamp instead.
1019 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1020 mFrameTracker.setActualPresentTime(presentTime);
1021 }
1022
1023 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001024 mFrameLatencyNeeded = false;
1025 }
1026}
1027
Mathias Agopianda27af92012-09-13 18:17:13 -07001028bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001029 const Layer::State& s(mDrawingState);
1030 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1031 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001032}
1033
Mathias Agopian4fec8732012-06-29 14:12:52 -07001034Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001035{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001036 ATRACE_CALL();
1037
Mathias Agopian4fec8732012-06-29 14:12:52 -07001038 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001039 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001040
1041 // if we've already called updateTexImage() without going through
1042 // a composition step, we have to skip this layer at this point
1043 // because we cannot call updateTeximage() without a corresponding
1044 // compositionComplete() call.
1045 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001046 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001047 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001048 }
1049
Jamie Gennis351a5132011-09-14 18:23:37 -07001050 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001051 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -07001052 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001053
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001054 // signal another event if we have more frames pending
1055 if (android_atomic_dec(&mQueuedFrames) > 1) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001056 mFlinger->signalLayerUpdate();
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001057 }
1058
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001059 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001060 Layer::State& front;
1061 Layer::State& current;
1062 bool& recomputeVisibleRegions;
1063 Reject(Layer::State& front, Layer::State& current,
1064 bool& recomputeVisibleRegions)
1065 : front(front), current(current),
1066 recomputeVisibleRegions(recomputeVisibleRegions) {
1067 }
1068
1069 virtual bool reject(const sp<GraphicBuffer>& buf,
1070 const BufferQueue::BufferItem& item) {
1071 if (buf == NULL) {
1072 return false;
1073 }
1074
1075 uint32_t bufWidth = buf->getWidth();
1076 uint32_t bufHeight = buf->getHeight();
1077
1078 // check that we received a buffer of the right size
1079 // (Take the buffer's orientation into account)
1080 if (item.mTransform & Transform::ROT_90) {
1081 swap(bufWidth, bufHeight);
1082 }
1083
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001084 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1085 if (front.active != front.requested) {
1086
1087 if (isFixedSize ||
1088 (bufWidth == front.requested.w &&
1089 bufHeight == front.requested.h))
1090 {
1091 // Here we pretend the transaction happened by updating the
1092 // current and drawing states. Drawing state is only accessed
1093 // in this thread, no need to have it locked
1094 front.active = front.requested;
1095
1096 // We also need to update the current state so that
1097 // we don't end-up overwriting the drawing state with
1098 // this stale current state during the next transaction
1099 //
1100 // NOTE: We don't need to hold the transaction lock here
1101 // because State::active is only accessed from this thread.
1102 current.active = front.active;
1103
1104 // recompute visible region
1105 recomputeVisibleRegions = true;
1106 }
1107
1108 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001109 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001110 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1111 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001112 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001113 front.active.w, front.active.h,
1114 front.active.crop.left,
1115 front.active.crop.top,
1116 front.active.crop.right,
1117 front.active.crop.bottom,
1118 front.active.crop.getWidth(),
1119 front.active.crop.getHeight(),
1120 front.requested.w, front.requested.h,
1121 front.requested.crop.left,
1122 front.requested.crop.top,
1123 front.requested.crop.right,
1124 front.requested.crop.bottom,
1125 front.requested.crop.getWidth(),
1126 front.requested.crop.getHeight());
1127 }
1128
1129 if (!isFixedSize) {
1130 if (front.active.w != bufWidth ||
1131 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001132 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001133 return true;
1134 }
1135 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001136
1137 // if the transparent region has changed (this test is
1138 // conservative, but that's fine, worst case we're doing
1139 // a bit of extra work), we latch the new one and we
1140 // trigger a visible-region recompute.
1141 if (!front.activeTransparentRegion.isTriviallyEqual(
1142 front.requestedTransparentRegion)) {
1143 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001144
1145 // We also need to update the current state so that
1146 // we don't end-up overwriting the drawing state with
1147 // this stale current state during the next transaction
1148 //
1149 // NOTE: We don't need to hold the transaction lock here
1150 // because State::active is only accessed from this thread.
1151 current.activeTransparentRegion = front.activeTransparentRegion;
1152
1153 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001154 recomputeVisibleRegions = true;
1155 }
1156
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001157 return false;
1158 }
1159 };
1160
1161
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001162 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001163
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001164 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001165 // something happened!
1166 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001167 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001168 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001169
Jamie Gennis351a5132011-09-14 18:23:37 -07001170 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001171 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001172 if (mActiveBuffer == NULL) {
1173 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001174 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001175 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001176
Mathias Agopian4824d402012-06-04 18:16:30 -07001177 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001178 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001179 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001180 // the first time we receive a buffer, we need to trigger a
1181 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001182 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001183 }
1184
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001185 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1186 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1187 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001188 if ((crop != mCurrentCrop) ||
1189 (transform != mCurrentTransform) ||
1190 (scalingMode != mCurrentScalingMode))
1191 {
1192 mCurrentCrop = crop;
1193 mCurrentTransform = transform;
1194 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001195 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001196 }
1197
1198 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001199 uint32_t bufWidth = mActiveBuffer->getWidth();
1200 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001201 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1202 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001203 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001204 }
1205 }
1206
1207 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1208 if (oldOpacity != isOpaque()) {
1209 recomputeVisibleRegions = true;
1210 }
1211
Mathias Agopian702634a2012-05-23 17:50:31 -07001212 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1213 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Mathias Agopian4fec8732012-06-29 14:12:52 -07001214
1215 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001216 const Layer::State& s(getDrawingState());
1217 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001218
1219 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001220 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001221 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001222 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001223}
1224
Mathias Agopiana67932f2011-04-20 14:20:59 -07001225uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001226{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001227 // TODO: should we do something special if mSecure is set?
1228 if (mProtectedByApp) {
1229 // need a hardware-protected path to external video sink
1230 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001231 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001232 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001233 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001234}
1235
Mathias Agopian84300952012-11-21 16:02:13 -08001236void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001237 uint32_t orientation = 0;
1238 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001239 // The transform hint is used to improve performance, but we can
1240 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001241 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001242 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001243 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001244 if (orientation & Transform::ROT_INVALID) {
1245 orientation = 0;
1246 }
1247 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001248 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001249}
1250
Mathias Agopian13127d82013-03-05 17:47:11 -08001251// ----------------------------------------------------------------------------
1252// debugging
1253// ----------------------------------------------------------------------------
1254
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001255void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001256{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001257 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001258
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001259 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001260 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001261 "+ %s %p (%s)\n",
1262 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001263 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001264
Mathias Agopian2ca79392013-04-02 18:30:32 -07001265 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001266 visibleRegion.dump(result, "visibleRegion");
1267 sp<Client> client(mClientRef.promote());
1268
Mathias Agopian74d211a2013-04-22 16:55:35 +02001269 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001270 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1271 "isOpaque=%1d, invalidate=%1d, "
1272 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1273 " client=%p\n",
1274 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1275 s.active.crop.left, s.active.crop.top,
1276 s.active.crop.right, s.active.crop.bottom,
1277 isOpaque(), contentDirty,
1278 s.alpha, s.flags,
1279 s.transform[0][0], s.transform[0][1],
1280 s.transform[1][0], s.transform[1][1],
1281 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001282
1283 sp<const GraphicBuffer> buf0(mActiveBuffer);
1284 uint32_t w0=0, h0=0, s0=0, f0=0;
1285 if (buf0 != 0) {
1286 w0 = buf0->getWidth();
1287 h0 = buf0->getHeight();
1288 s0 = buf0->getStride();
1289 f0 = buf0->format;
1290 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001291 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001292 " "
1293 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1294 " queued-frames=%d, mRefreshPending=%d\n",
1295 mFormat, w0, h0, s0,f0,
1296 mQueuedFrames, mRefreshPending);
1297
Mathias Agopian13127d82013-03-05 17:47:11 -08001298 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001299 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001300 }
1301}
1302
Mathias Agopian74d211a2013-04-22 16:55:35 +02001303void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001304 mFrameTracker.dump(result);
1305}
1306
1307void Layer::clearStats() {
1308 mFrameTracker.clear();
1309}
1310
1311// ---------------------------------------------------------------------------
1312
1313Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1314 const sp<Layer>& layer)
1315 : mFlinger(flinger), mLayer(layer) {
1316}
1317
1318Layer::LayerCleaner::~LayerCleaner() {
1319 // destroy client resources
1320 mFlinger->onLayerDestroyed(mLayer);
1321}
1322
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001323// ---------------------------------------------------------------------------
1324
1325
1326}; // namespace android