blob: 7f2ce2b80dedaeaf64a3fdcd860bac816680f201 [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 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 Gennis6547ff42013-07-16 20:12:42 -0700107
108 nsecs_t displayPeriod =
109 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
110 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800111}
112
Mathias Agopiana67932f2011-04-20 14:20:59 -0700113void Layer::onFirstRef()
Mathias Agopian96f08192010-06-02 23:28:45 -0700114{
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800115 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopian67106042013-03-14 19:18:13 -0700116 sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
Mathias Agopian8f938a52013-07-12 22:06:26 -0700117 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(bq, mTextureName,
118 GL_TEXTURE_EXTERNAL_OES, false);
Daniel Lamb2675792012-02-23 14:35:13 -0800119
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800120 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
121 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700122 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800123
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700124#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
125#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800126 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700127#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800128 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800129#endif
Andy McFadden69052052012-09-14 16:10:11 -0700130
Mathias Agopian84300952012-11-21 16:02:13 -0800131 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
132 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700133}
134
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700135Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800136 sp<Client> c(mClientRef.promote());
137 if (c != 0) {
138 c->detachLayer(this);
139 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700140 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700141 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700142}
143
Mathias Agopian13127d82013-03-05 17:47:11 -0800144// ---------------------------------------------------------------------------
145// callbacks
146// ---------------------------------------------------------------------------
147
148void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
149 HWComposer::HWCLayerInterface* layer) {
150 if (layer) {
151 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700152 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800153 }
154}
155
Igor Murashkina4a31492012-10-29 13:36:11 -0700156void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700157 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800158 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700159}
160
Mathias Agopian67106042013-03-14 19:18:13 -0700161// called with SurfaceFlinger::mStateLock from the drawing thread after
162// the layer has been remove from the current state list (and just before
163// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800164void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800165 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700166}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700167
Mathias Agopian13127d82013-03-05 17:47:11 -0800168// ---------------------------------------------------------------------------
169// set-up
170// ---------------------------------------------------------------------------
171
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700172const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800173 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800174}
175
Mathias Agopianf9d93272009-06-19 17:00:27 -0700176status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800177 PixelFormat format, uint32_t flags)
178{
Mathias Agopian401c2572009-09-23 19:16:27 -0700179 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800180 PixelFormatInfo info;
181 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800182 if (err) {
183 ALOGE("unsupported pixelformat %d", format);
184 return err;
185 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800186
Mathias Agopianca99fb82010-04-14 16:43:44 -0700187 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700188 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700189
190 // never allow a surface larger than what our underlying GL implementation
191 // can handle.
192 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800193 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700194 return BAD_VALUE;
195 }
196
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700197 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700198
Mathias Agopian3165cc22012-08-08 19:42:09 -0700199 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
200 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
201 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700202 mCurrentOpacity = getOpacityForFormat(format);
203
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800204 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
205 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
206 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700207
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800208 return NO_ERROR;
209}
210
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700211sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800212 Mutex::Autolock _l(mLock);
213
214 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700215 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800216
217 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700218
219 /*
220 * The layer handle is just a BBinder object passed to the client
221 * (remote process) -- we don't keep any reference on our side such that
222 * the dtor is called when the remote side let go of its reference.
223 *
224 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
225 * this layer when the handle is destroyed.
226 */
227
228 class Handle : public BBinder, public LayerCleaner {
229 wp<const Layer> mOwner;
230 public:
231 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
232 : LayerCleaner(flinger, layer), mOwner(layer) {
233 }
234 };
235
236 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800237}
238
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700239sp<BufferQueue> Layer::getBufferQueue() const {
240 return mSurfaceFlingerConsumer->getBufferQueue();
241}
242
Mathias Agopian13127d82013-03-05 17:47:11 -0800243// ---------------------------------------------------------------------------
244// h/w composer set-up
245// ---------------------------------------------------------------------------
246
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800247Rect Layer::getContentCrop() const {
248 // this is the crop rectangle that applies to the buffer
249 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700250 Rect crop;
251 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800252 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700253 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800254 } else if (mActiveBuffer != NULL) {
255 // otherwise we use the whole buffer
256 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700257 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800258 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700259 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700260 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700261 return crop;
262}
263
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700264static Rect reduce(const Rect& win, const Region& exclude) {
265 if (CC_LIKELY(exclude.isEmpty())) {
266 return win;
267 }
268 if (exclude.isRect()) {
269 return win.reduce(exclude.getBounds());
270 }
271 return Region(win).subtract(exclude).getBounds();
272}
273
Mathias Agopian13127d82013-03-05 17:47:11 -0800274Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700275 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800276 Rect win(s.active.w, s.active.h);
277 if (!s.active.crop.isEmpty()) {
278 win.intersect(s.active.crop, &win);
279 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700280 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700281 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800282}
283
Mathias Agopian6b442672013-07-09 21:24:52 -0700284FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800285 // the content crop is the area of the content that gets scaled to the
286 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700287 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800288
289 // the active.crop is the area of the window that gets cropped, but not
290 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700291 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800292
293 // apply the projection's clipping to the window crop in
294 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700295 // if there are no window scaling involved, this operation will map to full
296 // pixels in the buffer.
297 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
298 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian13127d82013-03-05 17:47:11 -0800299 Rect activeCrop(s.transform.transform(s.active.crop));
300 activeCrop.intersect(hw->getViewport(), &activeCrop);
301 activeCrop = s.transform.inverse().transform(activeCrop);
302
303 // paranoia: make sure the window-crop is constrained in the
304 // window's bounds
305 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
306
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700307 // subtract the transparent region and snap to the bounds
308 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
309
Mathias Agopian13127d82013-03-05 17:47:11 -0800310 if (!activeCrop.isEmpty()) {
311 // Transform the window crop to match the buffer coordinate system,
312 // which means using the inverse of the current transform set on the
313 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700314 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800315 int winWidth = s.active.w;
316 int winHeight = s.active.h;
317 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
318 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
319 NATIVE_WINDOW_TRANSFORM_FLIP_H;
320 winWidth = s.active.h;
321 winHeight = s.active.w;
322 }
323 const Rect winCrop = activeCrop.transform(
324 invTransform, s.active.w, s.active.h);
325
Mathias Agopian6b442672013-07-09 21:24:52 -0700326 // below, crop is intersected with winCrop expressed in crop's coordinate space
327 float xScale = crop.getWidth() / float(winWidth);
328 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800329
Mathias Agopian6b442672013-07-09 21:24:52 -0700330 float insetL = winCrop.left * xScale;
331 float insetT = winCrop.top * yScale;
332 float insetR = (winWidth - winCrop.right ) * xScale;
333 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800334
335 crop.left += insetL;
336 crop.top += insetT;
337 crop.right -= insetR;
338 crop.bottom -= insetB;
339 }
340 return crop;
341}
342
Mathias Agopian4fec8732012-06-29 14:12:52 -0700343void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700344 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700345 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700346{
Mathias Agopian13127d82013-03-05 17:47:11 -0800347 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700348
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700349 // enable this layer
350 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700351
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700352 if (isSecure() && !hw->isSecure()) {
353 layer.setSkip(true);
354 }
355
Mathias Agopian13127d82013-03-05 17:47:11 -0800356 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700357 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800358 if (!isOpaque() || s.alpha != 0xFF) {
359 layer.setBlending(mPremultipliedAlpha ?
360 HWC_BLENDING_PREMULT :
361 HWC_BLENDING_COVERAGE);
362 }
363
364 // apply the layer's transform, followed by the display's global transform
365 // here we're guaranteed that the layer's transform preserves rects
366 Rect frame(s.transform.transform(computeBounds()));
367 frame.intersect(hw->getViewport(), &frame);
368 const Transform& tr(hw->getTransform());
369 layer.setFrame(tr.transform(frame));
370 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800371 layer.setPlaneAlpha(s.alpha);
372
Mathias Agopian29a367b2011-07-12 14:51:45 -0700373 /*
374 * Transformations are applied in this order:
375 * 1) buffer orientation/flip/mirror
376 * 2) state transformation (window manager)
377 * 3) layer orientation (screen orientation)
378 * (NOTE: the matrices are multiplied in reverse order)
379 */
380
381 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800382 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700383
384 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800385 const uint32_t orientation = transform.getOrientation();
386 if (orientation & Transform::ROT_INVALID) {
387 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700388 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700389 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800390 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700391 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700392}
393
Mathias Agopian42977342012-08-05 00:40:46 -0700394void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700395 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800396 // we have to set the visible region on every frame because
397 // we currently free it during onLayerDisplayed(), which is called
398 // after HWComposer::commit() -- every frame.
399 // Apply this display's projection's viewport to the visible region
400 // before giving it to the HWC HAL.
401 const Transform& tr = hw->getTransform();
402 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
403 layer.setVisibleRegionScreen(visible);
404
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700405 // NOTE: buffer can be NULL if the client never drew into this
406 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700407 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700408}
Jesse Halldc5b4852012-06-29 15:21:18 -0700409
Mathias Agopian42977342012-08-05 00:40:46 -0700410void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700411 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700412 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700413
414 // TODO: there is a possible optimization here: we only need to set the
415 // acquire fence the first time a new buffer is acquired on EACH display.
416
417 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800418 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800419 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700420 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700421 if (fenceFd == -1) {
422 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
423 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700424 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700425 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700426 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700427}
428
Mathias Agopian13127d82013-03-05 17:47:11 -0800429// ---------------------------------------------------------------------------
430// drawing...
431// ---------------------------------------------------------------------------
432
433void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
434 onDraw(hw, clip);
435}
436
437void Layer::draw(const sp<const DisplayDevice>& hw) {
438 onDraw( hw, Region(hw->bounds()) );
439}
440
Mathias Agopian42977342012-08-05 00:40:46 -0700441void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800442{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800443 ATRACE_CALL();
444
Mathias Agopiana67932f2011-04-20 14:20:59 -0700445 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800446 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700447 // in fact never been drawn into. This happens frequently with
448 // SurfaceView because the WindowManager can't know when the client
449 // has drawn the first time.
450
451 // If there is nothing under us, we paint the screen in black, otherwise
452 // we just skip this update.
453
454 // figure out if there is something below us
455 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700456 const SurfaceFlinger::LayerVector& drawingLayers(
457 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700458 const size_t count = drawingLayers.size();
459 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800460 const sp<Layer>& layer(drawingLayers[i]);
461 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700462 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700463 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700464 }
465 // if not everything below us is covered, we plug the holes!
466 Region holes(clip.subtract(under));
467 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700468 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700469 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800470 return;
471 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700472
Andy McFadden97eba892012-12-11 15:21:45 -0800473 // Bind the current buffer to the GL texture, and wait for it to be
474 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800475 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
476 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800477 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700478 // Go ahead and draw the buffer anyway; no matter what we do the screen
479 // is probably going to have something visibly wrong.
480 }
481
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700482 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
483
Mathias Agopian875d8e12013-06-07 15:35:48 -0700484 RenderEngine& engine(mFlinger->getRenderEngine());
485
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700486 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700487 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700488 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700489
490 // Query the texture matrix given our current filtering mode.
491 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800492 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
493 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700494
495 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700496 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700497 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700498 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700499 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700500 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700501 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800502}
503
Mathias Agopian13127d82013-03-05 17:47:11 -0800504
505void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
506 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
507{
Mathias Agopian13127d82013-03-05 17:47:11 -0800508 LayerMesh mesh;
509 computeGeometry(hw, &mesh);
510
Mathias Agopian875d8e12013-06-07 15:35:48 -0700511 mFlinger->getRenderEngine().clearWithColor(
512 mesh.getVertices(), mesh.getVertexCount(),
513 red, green, blue, alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800514}
515
516void Layer::clearWithOpenGL(
517 const sp<const DisplayDevice>& hw, const Region& clip) const {
518 clearWithOpenGL(hw, clip, 0,0,0,0);
519}
520
521void Layer::drawWithOpenGL(
522 const sp<const DisplayDevice>& hw, const Region& clip) const {
523 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700524 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800525
Mathias Agopian13127d82013-03-05 17:47:11 -0800526 LayerMesh mesh;
527 computeGeometry(hw, &mesh);
528
Mathias Agopian13127d82013-03-05 17:47:11 -0800529 /*
530 * NOTE: the way we compute the texture coordinates here produces
531 * different results than when we take the HWC path -- in the later case
532 * the "source crop" is rounded to texel boundaries.
533 * This can produce significantly different results when the texture
534 * is scaled by a large amount.
535 *
536 * The GL code below is more logical (imho), and the difference with
537 * HWC is due to a limitation of the HWC API to integers -- a question
538 * is suspend is wether we should ignore this problem or revert to
539 * GL composition when a buffer scaling is applied (maybe with some
540 * minimal value)? Or, we could make GL behave like HWC -- but this feel
541 * like more of a hack.
542 */
543 const Rect win(computeBounds());
544
545 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
546 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
547 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
548 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
549
Mathias Agopian875d8e12013-06-07 15:35:48 -0700550 // TODO: we probably want to generate the texture coords with the mesh
551 // here we assume that we only have 4 vertices
552 float texCoords[4][2];
553 texCoords[0][0] = left;
554 texCoords[0][1] = top;
555 texCoords[1][0] = left;
556 texCoords[1][1] = bottom;
557 texCoords[2][0] = right;
558 texCoords[2][1] = bottom;
559 texCoords[3][0] = right;
560 texCoords[3][1] = top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800561 for (int i = 0; i < 4; i++) {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700562 texCoords[i][1] = 1.0f - texCoords[i][1];
Mathias Agopian13127d82013-03-05 17:47:11 -0800563 }
564
Mathias Agopian875d8e12013-06-07 15:35:48 -0700565 RenderEngine& engine(mFlinger->getRenderEngine());
566 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
567 engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
568 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800569}
570
571void Layer::setFiltering(bool filtering) {
572 mFiltering = filtering;
573}
574
575bool Layer::getFiltering() const {
576 return mFiltering;
577}
578
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800579// As documented in libhardware header, formats in the range
580// 0x100 - 0x1FF are specific to the HAL implementation, and
581// are known to have no alpha channel
582// TODO: move definition for device-specific range into
583// hardware.h, instead of using hard-coded values here.
584#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
585
Mathias Agopiana67932f2011-04-20 14:20:59 -0700586bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800587{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700588 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
589 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800590 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700591 PixelFormatInfo info;
592 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
593 // in case of error (unknown format), we assume no blending
594 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800595}
596
Mathias Agopian13127d82013-03-05 17:47:11 -0800597// ----------------------------------------------------------------------------
598// local state
599// ----------------------------------------------------------------------------
600
601void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
602{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700603 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800604 const Transform tr(hw->getTransform() * s.transform);
605 const uint32_t hw_h = hw->getHeight();
606 Rect win(s.active.w, s.active.h);
607 if (!s.active.crop.isEmpty()) {
608 win.intersect(s.active.crop, &win);
609 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700610 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700611 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800612 if (mesh) {
613 tr.transform(mesh->mVertices[0], win.left, win.top);
614 tr.transform(mesh->mVertices[1], win.left, win.bottom);
615 tr.transform(mesh->mVertices[2], win.right, win.bottom);
616 tr.transform(mesh->mVertices[3], win.right, win.top);
617 for (size_t i=0 ; i<4 ; i++) {
618 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
619 }
620 }
621}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800622
Mathias Agopiana67932f2011-04-20 14:20:59 -0700623bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700624{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700625 // if we don't have a buffer yet, we're translucent regardless of the
626 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700627 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700628 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700629 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700630
631 // if the layer has the opaque flag, then we're always opaque,
632 // otherwise we use the current buffer's format.
633 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700634}
635
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800636bool Layer::isProtected() const
637{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700638 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800639 return (activeBuffer != 0) &&
640 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
641}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700642
Mathias Agopian13127d82013-03-05 17:47:11 -0800643bool Layer::isFixedSize() const {
644 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
645}
646
647bool Layer::isCropped() const {
648 return !mCurrentCrop.isEmpty();
649}
650
651bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
652 return mNeedsFiltering || hw->needsFiltering();
653}
654
655void Layer::setVisibleRegion(const Region& visibleRegion) {
656 // always called from main thread
657 this->visibleRegion = visibleRegion;
658}
659
660void Layer::setCoveredRegion(const Region& coveredRegion) {
661 // always called from main thread
662 this->coveredRegion = coveredRegion;
663}
664
665void Layer::setVisibleNonTransparentRegion(const Region&
666 setVisibleNonTransparentRegion) {
667 // always called from main thread
668 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
669}
670
671// ----------------------------------------------------------------------------
672// transaction
673// ----------------------------------------------------------------------------
674
675uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800676 ATRACE_CALL();
677
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700678 const Layer::State& s(getDrawingState());
679 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800680
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700681 const bool sizeChanged = (c.requested.w != s.requested.w) ||
682 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700683
684 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700685 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000686 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700687 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700688 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
689 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
690 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
691 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700692 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
693 c.active.w, c.active.h,
694 c.active.crop.left,
695 c.active.crop.top,
696 c.active.crop.right,
697 c.active.crop.bottom,
698 c.active.crop.getWidth(),
699 c.active.crop.getHeight(),
700 c.requested.w, c.requested.h,
701 c.requested.crop.left,
702 c.requested.crop.top,
703 c.requested.crop.right,
704 c.requested.crop.bottom,
705 c.requested.crop.getWidth(),
706 c.requested.crop.getHeight(),
707 s.active.w, s.active.h,
708 s.active.crop.left,
709 s.active.crop.top,
710 s.active.crop.right,
711 s.active.crop.bottom,
712 s.active.crop.getWidth(),
713 s.active.crop.getHeight(),
714 s.requested.w, s.requested.h,
715 s.requested.crop.left,
716 s.requested.crop.top,
717 s.requested.crop.right,
718 s.requested.crop.bottom,
719 s.requested.crop.getWidth(),
720 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800721
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700722 // record the new size, form this point on, when the client request
723 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800724 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700725 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800726 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700727
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700728 if (!isFixedSize()) {
729
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700730 const bool resizePending = (c.requested.w != c.active.w) ||
731 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700732
733 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800734 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700735 // if we have a pending resize, unless we are in fixed-size mode.
736 // the drawing state will be updated only once we receive a buffer
737 // with the correct size.
738 //
739 // in particular, we want to make sure the clip (which is part
740 // of the geometry state) is latched together with the size but is
741 // latched immediately when no resizing is involved.
742
743 flags |= eDontUpdateGeometryState;
744 }
745 }
746
Mathias Agopian13127d82013-03-05 17:47:11 -0800747 // always set active to requested, unless we're asked not to
748 // this is used by Layer, which special cases resizes.
749 if (flags & eDontUpdateGeometryState) {
750 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700751 Layer::State& editCurrentState(getCurrentState());
752 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800753 }
754
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700755 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800756 // invalidate and recompute the visible regions if needed
757 flags |= Layer::eVisibleRegion;
758 }
759
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700760 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800761 // invalidate and recompute the visible regions if needed
762 flags |= eVisibleRegion;
763 this->contentDirty = true;
764
765 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700766 const uint8_t type = c.transform.getType();
767 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800768 (type >= Transform::SCALE));
769 }
770
771 // Commit the transaction
772 commitTransaction();
773 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800774}
775
Mathias Agopian13127d82013-03-05 17:47:11 -0800776void Layer::commitTransaction() {
777 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700778}
779
Mathias Agopian13127d82013-03-05 17:47:11 -0800780uint32_t Layer::getTransactionFlags(uint32_t flags) {
781 return android_atomic_and(~flags, &mTransactionFlags) & flags;
782}
783
784uint32_t Layer::setTransactionFlags(uint32_t flags) {
785 return android_atomic_or(flags, &mTransactionFlags);
786}
787
788bool Layer::setPosition(float x, float y) {
789 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
790 return false;
791 mCurrentState.sequence++;
792 mCurrentState.transform.set(x, y);
793 setTransactionFlags(eTransactionNeeded);
794 return true;
795}
796bool Layer::setLayer(uint32_t z) {
797 if (mCurrentState.z == z)
798 return false;
799 mCurrentState.sequence++;
800 mCurrentState.z = z;
801 setTransactionFlags(eTransactionNeeded);
802 return true;
803}
804bool Layer::setSize(uint32_t w, uint32_t h) {
805 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
806 return false;
807 mCurrentState.requested.w = w;
808 mCurrentState.requested.h = h;
809 setTransactionFlags(eTransactionNeeded);
810 return true;
811}
812bool Layer::setAlpha(uint8_t alpha) {
813 if (mCurrentState.alpha == alpha)
814 return false;
815 mCurrentState.sequence++;
816 mCurrentState.alpha = alpha;
817 setTransactionFlags(eTransactionNeeded);
818 return true;
819}
820bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
821 mCurrentState.sequence++;
822 mCurrentState.transform.set(
823 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
824 setTransactionFlags(eTransactionNeeded);
825 return true;
826}
827bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700828 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800829 setTransactionFlags(eTransactionNeeded);
830 return true;
831}
832bool Layer::setFlags(uint8_t flags, uint8_t mask) {
833 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
834 if (mCurrentState.flags == newFlags)
835 return false;
836 mCurrentState.sequence++;
837 mCurrentState.flags = newFlags;
838 setTransactionFlags(eTransactionNeeded);
839 return true;
840}
841bool Layer::setCrop(const Rect& crop) {
842 if (mCurrentState.requested.crop == crop)
843 return false;
844 mCurrentState.sequence++;
845 mCurrentState.requested.crop = crop;
846 setTransactionFlags(eTransactionNeeded);
847 return true;
848}
849
850bool Layer::setLayerStack(uint32_t layerStack) {
851 if (mCurrentState.layerStack == layerStack)
852 return false;
853 mCurrentState.sequence++;
854 mCurrentState.layerStack = layerStack;
855 setTransactionFlags(eTransactionNeeded);
856 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700857}
858
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800859// ----------------------------------------------------------------------------
860// pageflip handling...
861// ----------------------------------------------------------------------------
862
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800863bool Layer::onPreComposition() {
864 mRefreshPending = false;
865 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800866}
867
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700868void Layer::onPostComposition() {
869 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800870 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800871 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
872
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800873 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800874 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800875 mFrameTracker.setFrameReadyFence(frameReadyFence);
876 } else {
877 // There was no fence for this frame, so assume that it was ready
878 // to be presented at the desired present time.
879 mFrameTracker.setFrameReadyTime(desiredPresentTime);
880 }
881
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700882 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800883 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800884 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800885 mFrameTracker.setActualPresentFence(presentFence);
886 } else {
887 // The HWC doesn't support present fences, so use the refresh
888 // timestamp instead.
889 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
890 mFrameTracker.setActualPresentTime(presentTime);
891 }
892
893 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700894 mFrameLatencyNeeded = false;
895 }
896}
897
Mathias Agopianda27af92012-09-13 18:17:13 -0700898bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800899 const Layer::State& s(mDrawingState);
900 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
901 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700902}
903
Mathias Agopian4fec8732012-06-29 14:12:52 -0700904Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800905{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800906 ATRACE_CALL();
907
Mathias Agopian4fec8732012-06-29 14:12:52 -0700908 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700909 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800910
911 // if we've already called updateTexImage() without going through
912 // a composition step, we have to skip this layer at this point
913 // because we cannot call updateTeximage() without a corresponding
914 // compositionComplete() call.
915 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800916 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700917 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800918 }
919
Jamie Gennis351a5132011-09-14 18:23:37 -0700920 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700921 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700922 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700923
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800924 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700925 Layer::State& front;
926 Layer::State& current;
927 bool& recomputeVisibleRegions;
928 Reject(Layer::State& front, Layer::State& current,
929 bool& recomputeVisibleRegions)
930 : front(front), current(current),
931 recomputeVisibleRegions(recomputeVisibleRegions) {
932 }
933
934 virtual bool reject(const sp<GraphicBuffer>& buf,
935 const BufferQueue::BufferItem& item) {
936 if (buf == NULL) {
937 return false;
938 }
939
940 uint32_t bufWidth = buf->getWidth();
941 uint32_t bufHeight = buf->getHeight();
942
943 // check that we received a buffer of the right size
944 // (Take the buffer's orientation into account)
945 if (item.mTransform & Transform::ROT_90) {
946 swap(bufWidth, bufHeight);
947 }
948
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700949 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
950 if (front.active != front.requested) {
951
952 if (isFixedSize ||
953 (bufWidth == front.requested.w &&
954 bufHeight == front.requested.h))
955 {
956 // Here we pretend the transaction happened by updating the
957 // current and drawing states. Drawing state is only accessed
958 // in this thread, no need to have it locked
959 front.active = front.requested;
960
961 // We also need to update the current state so that
962 // we don't end-up overwriting the drawing state with
963 // this stale current state during the next transaction
964 //
965 // NOTE: We don't need to hold the transaction lock here
966 // because State::active is only accessed from this thread.
967 current.active = front.active;
968
969 // recompute visible region
970 recomputeVisibleRegions = true;
971 }
972
973 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700974 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700975 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
976 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700977 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700978 front.active.w, front.active.h,
979 front.active.crop.left,
980 front.active.crop.top,
981 front.active.crop.right,
982 front.active.crop.bottom,
983 front.active.crop.getWidth(),
984 front.active.crop.getHeight(),
985 front.requested.w, front.requested.h,
986 front.requested.crop.left,
987 front.requested.crop.top,
988 front.requested.crop.right,
989 front.requested.crop.bottom,
990 front.requested.crop.getWidth(),
991 front.requested.crop.getHeight());
992 }
993
994 if (!isFixedSize) {
995 if (front.active.w != bufWidth ||
996 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -0700997 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700998 return true;
999 }
1000 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001001
1002 // if the transparent region has changed (this test is
1003 // conservative, but that's fine, worst case we're doing
1004 // a bit of extra work), we latch the new one and we
1005 // trigger a visible-region recompute.
1006 if (!front.activeTransparentRegion.isTriviallyEqual(
1007 front.requestedTransparentRegion)) {
1008 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001009
1010 // We also need to update the current state so that
1011 // we don't end-up overwriting the drawing state with
1012 // this stale current state during the next transaction
1013 //
1014 // NOTE: We don't need to hold the transaction lock here
1015 // because State::active is only accessed from this thread.
1016 current.activeTransparentRegion = front.activeTransparentRegion;
1017
1018 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001019 recomputeVisibleRegions = true;
1020 }
1021
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001022 return false;
1023 }
1024 };
1025
1026
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001027 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001028
Andy McFadden1585c4d2013-06-28 13:52:40 -07001029 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1030 if (updateResult == BufferQueue::PRESENT_LATER) {
1031 // Producer doesn't want buffer to be displayed yet. Signal a
1032 // layer update so we check again at the next opportunity.
1033 mFlinger->signalLayerUpdate();
1034 return outDirtyRegion;
1035 }
1036
1037 // Decrement the queued-frames count. Signal another event if we
1038 // have more frames pending.
1039 if (android_atomic_dec(&mQueuedFrames) > 1) {
1040 mFlinger->signalLayerUpdate();
1041 }
1042
1043 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001044 // something happened!
1045 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001046 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001047 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001048
Jamie Gennis351a5132011-09-14 18:23:37 -07001049 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001050 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001051 if (mActiveBuffer == NULL) {
1052 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001053 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001054 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001055
Mathias Agopian4824d402012-06-04 18:16:30 -07001056 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001057 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001058 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001059 // the first time we receive a buffer, we need to trigger a
1060 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001061 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001062 }
1063
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001064 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1065 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1066 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001067 if ((crop != mCurrentCrop) ||
1068 (transform != mCurrentTransform) ||
1069 (scalingMode != mCurrentScalingMode))
1070 {
1071 mCurrentCrop = crop;
1072 mCurrentTransform = transform;
1073 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001074 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001075 }
1076
1077 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001078 uint32_t bufWidth = mActiveBuffer->getWidth();
1079 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001080 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1081 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001082 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001083 }
1084 }
1085
1086 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1087 if (oldOpacity != isOpaque()) {
1088 recomputeVisibleRegions = true;
1089 }
1090
Mathias Agopian4fec8732012-06-29 14:12:52 -07001091 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001092 const Layer::State& s(getDrawingState());
1093 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001094
1095 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001096 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001097 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001098 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001099}
1100
Mathias Agopiana67932f2011-04-20 14:20:59 -07001101uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001102{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001103 // TODO: should we do something special if mSecure is set?
1104 if (mProtectedByApp) {
1105 // need a hardware-protected path to external video sink
1106 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001107 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001108 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001109 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001110}
1111
Mathias Agopian84300952012-11-21 16:02:13 -08001112void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001113 uint32_t orientation = 0;
1114 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001115 // The transform hint is used to improve performance, but we can
1116 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001117 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001118 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001119 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001120 if (orientation & Transform::ROT_INVALID) {
1121 orientation = 0;
1122 }
1123 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001124 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001125}
1126
Mathias Agopian13127d82013-03-05 17:47:11 -08001127// ----------------------------------------------------------------------------
1128// debugging
1129// ----------------------------------------------------------------------------
1130
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001131void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001132{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001133 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001134
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001135 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001136 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001137 "+ %s %p (%s)\n",
1138 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001139 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001140
Mathias Agopian2ca79392013-04-02 18:30:32 -07001141 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001142 visibleRegion.dump(result, "visibleRegion");
1143 sp<Client> client(mClientRef.promote());
1144
Mathias Agopian74d211a2013-04-22 16:55:35 +02001145 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001146 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1147 "isOpaque=%1d, invalidate=%1d, "
1148 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1149 " client=%p\n",
1150 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1151 s.active.crop.left, s.active.crop.top,
1152 s.active.crop.right, s.active.crop.bottom,
1153 isOpaque(), contentDirty,
1154 s.alpha, s.flags,
1155 s.transform[0][0], s.transform[0][1],
1156 s.transform[1][0], s.transform[1][1],
1157 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001158
1159 sp<const GraphicBuffer> buf0(mActiveBuffer);
1160 uint32_t w0=0, h0=0, s0=0, f0=0;
1161 if (buf0 != 0) {
1162 w0 = buf0->getWidth();
1163 h0 = buf0->getHeight();
1164 s0 = buf0->getStride();
1165 f0 = buf0->format;
1166 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001167 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001168 " "
1169 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1170 " queued-frames=%d, mRefreshPending=%d\n",
1171 mFormat, w0, h0, s0,f0,
1172 mQueuedFrames, mRefreshPending);
1173
Mathias Agopian13127d82013-03-05 17:47:11 -08001174 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001175 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001176 }
1177}
1178
Mathias Agopian74d211a2013-04-22 16:55:35 +02001179void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001180 mFrameTracker.dump(result);
1181}
1182
1183void Layer::clearStats() {
1184 mFrameTracker.clear();
1185}
1186
Jamie Gennis6547ff42013-07-16 20:12:42 -07001187void Layer::logFrameStats() {
1188 mFrameTracker.logAndResetStats(mName);
1189}
1190
Mathias Agopian13127d82013-03-05 17:47:11 -08001191// ---------------------------------------------------------------------------
1192
1193Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1194 const sp<Layer>& layer)
1195 : mFlinger(flinger), mLayer(layer) {
1196}
1197
1198Layer::LayerCleaner::~LayerCleaner() {
1199 // destroy client resources
1200 mFlinger->onLayerDestroyed(mLayer);
1201}
1202
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001203// ---------------------------------------------------------------------------
1204
1205
1206}; // namespace android