blob: 52211c22d94f42dfe6106dd9fa755190b18b2fb9 [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 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);
Mathias Agopian8f938a52013-07-12 22:06:26 -0700113 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(bq, mTextureName,
114 GL_TEXTURE_EXTERNAL_OES, false);
Daniel Lamb2675792012-02-23 14:35:13 -0800115
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800116 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700118 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800119
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700120#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
121#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800122 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700123#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800124 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800125#endif
Andy McFadden69052052012-09-14 16:10:11 -0700126
Mathias Agopian84300952012-11-21 16:02:13 -0800127 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
128 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700129}
130
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700131Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800132 sp<Client> c(mClientRef.promote());
133 if (c != 0) {
134 c->detachLayer(this);
135 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700136 mFlinger->deleteTextureAsync(mTextureName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700137}
138
Mathias Agopian13127d82013-03-05 17:47:11 -0800139// ---------------------------------------------------------------------------
140// callbacks
141// ---------------------------------------------------------------------------
142
143void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
144 HWComposer::HWCLayerInterface* layer) {
145 if (layer) {
146 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700147 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800148 }
149}
150
Igor Murashkina4a31492012-10-29 13:36:11 -0700151void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700152 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800153 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700154}
155
Mathias Agopian67106042013-03-14 19:18:13 -0700156// called with SurfaceFlinger::mStateLock from the drawing thread after
157// the layer has been remove from the current state list (and just before
158// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800159void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800160 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700161}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700162
Mathias Agopian13127d82013-03-05 17:47:11 -0800163// ---------------------------------------------------------------------------
164// set-up
165// ---------------------------------------------------------------------------
166
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700167const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800168 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800169}
170
Mathias Agopianf9d93272009-06-19 17:00:27 -0700171status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800172 PixelFormat format, uint32_t flags)
173{
Mathias Agopian401c2572009-09-23 19:16:27 -0700174 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800175 PixelFormatInfo info;
176 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800177 if (err) {
178 ALOGE("unsupported pixelformat %d", format);
179 return err;
180 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800181
Mathias Agopianca99fb82010-04-14 16:43:44 -0700182 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700183 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700184
185 // never allow a surface larger than what our underlying GL implementation
186 // can handle.
187 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800188 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700189 return BAD_VALUE;
190 }
191
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700192 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700193
Mathias Agopian3165cc22012-08-08 19:42:09 -0700194 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
195 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
196 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700197 mCurrentOpacity = getOpacityForFormat(format);
198
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800199 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
200 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
201 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700202
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800203 return NO_ERROR;
204}
205
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700206sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800207 Mutex::Autolock _l(mLock);
208
209 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700210 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800211
212 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700213
214 /*
215 * The layer handle is just a BBinder object passed to the client
216 * (remote process) -- we don't keep any reference on our side such that
217 * the dtor is called when the remote side let go of its reference.
218 *
219 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
220 * this layer when the handle is destroyed.
221 */
222
223 class Handle : public BBinder, public LayerCleaner {
224 wp<const Layer> mOwner;
225 public:
226 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
227 : LayerCleaner(flinger, layer), mOwner(layer) {
228 }
229 };
230
231 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800232}
233
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700234sp<BufferQueue> Layer::getBufferQueue() const {
235 return mSurfaceFlingerConsumer->getBufferQueue();
236}
237
Mathias Agopian13127d82013-03-05 17:47:11 -0800238// ---------------------------------------------------------------------------
239// h/w composer set-up
240// ---------------------------------------------------------------------------
241
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800242Rect Layer::getContentCrop() const {
243 // this is the crop rectangle that applies to the buffer
244 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700245 Rect crop;
246 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800247 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700248 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800249 } else if (mActiveBuffer != NULL) {
250 // otherwise we use the whole buffer
251 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700252 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800253 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700254 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700255 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700256 return crop;
257}
258
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700259static Rect reduce(const Rect& win, const Region& exclude) {
260 if (CC_LIKELY(exclude.isEmpty())) {
261 return win;
262 }
263 if (exclude.isRect()) {
264 return win.reduce(exclude.getBounds());
265 }
266 return Region(win).subtract(exclude).getBounds();
267}
268
Mathias Agopian13127d82013-03-05 17:47:11 -0800269Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700270 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800271 Rect win(s.active.w, s.active.h);
272 if (!s.active.crop.isEmpty()) {
273 win.intersect(s.active.crop, &win);
274 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700275 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700276 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800277}
278
Mathias Agopian6b442672013-07-09 21:24:52 -0700279FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800280 // the content crop is the area of the content that gets scaled to the
281 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700282 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800283
284 // the active.crop is the area of the window that gets cropped, but not
285 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700286 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800287
288 // apply the projection's clipping to the window crop in
289 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700290 // if there are no window scaling involved, this operation will map to full
291 // pixels in the buffer.
292 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
293 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian13127d82013-03-05 17:47:11 -0800294 Rect activeCrop(s.transform.transform(s.active.crop));
295 activeCrop.intersect(hw->getViewport(), &activeCrop);
296 activeCrop = s.transform.inverse().transform(activeCrop);
297
298 // paranoia: make sure the window-crop is constrained in the
299 // window's bounds
300 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
301
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700302 // subtract the transparent region and snap to the bounds
303 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
304
Mathias Agopian13127d82013-03-05 17:47:11 -0800305 if (!activeCrop.isEmpty()) {
306 // Transform the window crop to match the buffer coordinate system,
307 // which means using the inverse of the current transform set on the
308 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700309 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800310 int winWidth = s.active.w;
311 int winHeight = s.active.h;
312 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
313 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
314 NATIVE_WINDOW_TRANSFORM_FLIP_H;
315 winWidth = s.active.h;
316 winHeight = s.active.w;
317 }
318 const Rect winCrop = activeCrop.transform(
319 invTransform, s.active.w, s.active.h);
320
Mathias Agopian6b442672013-07-09 21:24:52 -0700321 // below, crop is intersected with winCrop expressed in crop's coordinate space
322 float xScale = crop.getWidth() / float(winWidth);
323 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800324
Mathias Agopian6b442672013-07-09 21:24:52 -0700325 float insetL = winCrop.left * xScale;
326 float insetT = winCrop.top * yScale;
327 float insetR = (winWidth - winCrop.right ) * xScale;
328 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800329
330 crop.left += insetL;
331 crop.top += insetT;
332 crop.right -= insetR;
333 crop.bottom -= insetB;
334 }
335 return crop;
336}
337
Mathias Agopian4fec8732012-06-29 14:12:52 -0700338void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700339 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700340 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700341{
Mathias Agopian13127d82013-03-05 17:47:11 -0800342 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700343
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700344 // enable this layer
345 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700346
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700347 if (isSecure() && !hw->isSecure()) {
348 layer.setSkip(true);
349 }
350
Mathias Agopian13127d82013-03-05 17:47:11 -0800351 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700352 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800353 if (!isOpaque() || s.alpha != 0xFF) {
354 layer.setBlending(mPremultipliedAlpha ?
355 HWC_BLENDING_PREMULT :
356 HWC_BLENDING_COVERAGE);
357 }
358
359 // apply the layer's transform, followed by the display's global transform
360 // here we're guaranteed that the layer's transform preserves rects
361 Rect frame(s.transform.transform(computeBounds()));
362 frame.intersect(hw->getViewport(), &frame);
363 const Transform& tr(hw->getTransform());
364 layer.setFrame(tr.transform(frame));
365 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800366 layer.setPlaneAlpha(s.alpha);
367
Mathias Agopian29a367b2011-07-12 14:51:45 -0700368 /*
369 * Transformations are applied in this order:
370 * 1) buffer orientation/flip/mirror
371 * 2) state transformation (window manager)
372 * 3) layer orientation (screen orientation)
373 * (NOTE: the matrices are multiplied in reverse order)
374 */
375
376 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800377 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700378
379 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800380 const uint32_t orientation = transform.getOrientation();
381 if (orientation & Transform::ROT_INVALID) {
382 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700383 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700384 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800385 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700386 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700387}
388
Mathias Agopian42977342012-08-05 00:40:46 -0700389void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700390 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800391 // we have to set the visible region on every frame because
392 // we currently free it during onLayerDisplayed(), which is called
393 // after HWComposer::commit() -- every frame.
394 // Apply this display's projection's viewport to the visible region
395 // before giving it to the HWC HAL.
396 const Transform& tr = hw->getTransform();
397 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
398 layer.setVisibleRegionScreen(visible);
399
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700400 // NOTE: buffer can be NULL if the client never drew into this
401 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700402 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700403}
Jesse Halldc5b4852012-06-29 15:21:18 -0700404
Mathias Agopian42977342012-08-05 00:40:46 -0700405void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700406 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700407 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700408
409 // TODO: there is a possible optimization here: we only need to set the
410 // acquire fence the first time a new buffer is acquired on EACH display.
411
412 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800413 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800414 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700415 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700416 if (fenceFd == -1) {
417 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
418 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700419 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700420 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700421 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700422}
423
Mathias Agopian13127d82013-03-05 17:47:11 -0800424// ---------------------------------------------------------------------------
425// drawing...
426// ---------------------------------------------------------------------------
427
428void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
429 onDraw(hw, clip);
430}
431
432void Layer::draw(const sp<const DisplayDevice>& hw) {
433 onDraw( hw, Region(hw->bounds()) );
434}
435
Mathias Agopian42977342012-08-05 00:40:46 -0700436void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800437{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800438 ATRACE_CALL();
439
Mathias Agopiana67932f2011-04-20 14:20:59 -0700440 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800441 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700442 // in fact never been drawn into. This happens frequently with
443 // SurfaceView because the WindowManager can't know when the client
444 // has drawn the first time.
445
446 // If there is nothing under us, we paint the screen in black, otherwise
447 // we just skip this update.
448
449 // figure out if there is something below us
450 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700451 const SurfaceFlinger::LayerVector& drawingLayers(
452 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700453 const size_t count = drawingLayers.size();
454 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800455 const sp<Layer>& layer(drawingLayers[i]);
456 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700457 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700458 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700459 }
460 // if not everything below us is covered, we plug the holes!
461 Region holes(clip.subtract(under));
462 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700463 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700464 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800465 return;
466 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700467
Andy McFadden97eba892012-12-11 15:21:45 -0800468 // Bind the current buffer to the GL texture, and wait for it to be
469 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800470 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
471 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800472 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700473 // Go ahead and draw the buffer anyway; no matter what we do the screen
474 // is probably going to have something visibly wrong.
475 }
476
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700477 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
478
Mathias Agopian875d8e12013-06-07 15:35:48 -0700479 RenderEngine& engine(mFlinger->getRenderEngine());
480
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700481 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700482 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700483 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700484
485 // Query the texture matrix given our current filtering mode.
486 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800487 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
488 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700489
490 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700491 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700492 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700493 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700494 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700495 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700496 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800497}
498
Mathias Agopian13127d82013-03-05 17:47:11 -0800499
500void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
501 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
502{
Mathias Agopian13127d82013-03-05 17:47:11 -0800503 LayerMesh mesh;
504 computeGeometry(hw, &mesh);
505
Mathias Agopian875d8e12013-06-07 15:35:48 -0700506 mFlinger->getRenderEngine().clearWithColor(
507 mesh.getVertices(), mesh.getVertexCount(),
508 red, green, blue, alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800509}
510
511void Layer::clearWithOpenGL(
512 const sp<const DisplayDevice>& hw, const Region& clip) const {
513 clearWithOpenGL(hw, clip, 0,0,0,0);
514}
515
516void Layer::drawWithOpenGL(
517 const sp<const DisplayDevice>& hw, const Region& clip) const {
518 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700519 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800520
Mathias Agopian13127d82013-03-05 17:47:11 -0800521 LayerMesh mesh;
522 computeGeometry(hw, &mesh);
523
Mathias Agopian13127d82013-03-05 17:47:11 -0800524 /*
525 * NOTE: the way we compute the texture coordinates here produces
526 * different results than when we take the HWC path -- in the later case
527 * the "source crop" is rounded to texel boundaries.
528 * This can produce significantly different results when the texture
529 * is scaled by a large amount.
530 *
531 * The GL code below is more logical (imho), and the difference with
532 * HWC is due to a limitation of the HWC API to integers -- a question
533 * is suspend is wether we should ignore this problem or revert to
534 * GL composition when a buffer scaling is applied (maybe with some
535 * minimal value)? Or, we could make GL behave like HWC -- but this feel
536 * like more of a hack.
537 */
538 const Rect win(computeBounds());
539
540 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
541 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
542 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
543 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
544
Mathias Agopian875d8e12013-06-07 15:35:48 -0700545 // TODO: we probably want to generate the texture coords with the mesh
546 // here we assume that we only have 4 vertices
547 float texCoords[4][2];
548 texCoords[0][0] = left;
549 texCoords[0][1] = top;
550 texCoords[1][0] = left;
551 texCoords[1][1] = bottom;
552 texCoords[2][0] = right;
553 texCoords[2][1] = bottom;
554 texCoords[3][0] = right;
555 texCoords[3][1] = top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800556 for (int i = 0; i < 4; i++) {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700557 texCoords[i][1] = 1.0f - texCoords[i][1];
Mathias Agopian13127d82013-03-05 17:47:11 -0800558 }
559
Mathias Agopian875d8e12013-06-07 15:35:48 -0700560 RenderEngine& engine(mFlinger->getRenderEngine());
561 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
562 engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
563 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800564}
565
566void Layer::setFiltering(bool filtering) {
567 mFiltering = filtering;
568}
569
570bool Layer::getFiltering() const {
571 return mFiltering;
572}
573
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800574// As documented in libhardware header, formats in the range
575// 0x100 - 0x1FF are specific to the HAL implementation, and
576// are known to have no alpha channel
577// TODO: move definition for device-specific range into
578// hardware.h, instead of using hard-coded values here.
579#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
580
Mathias Agopiana67932f2011-04-20 14:20:59 -0700581bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800582{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700583 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
584 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800585 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700586 PixelFormatInfo info;
587 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
588 // in case of error (unknown format), we assume no blending
589 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800590}
591
Mathias Agopian13127d82013-03-05 17:47:11 -0800592// ----------------------------------------------------------------------------
593// local state
594// ----------------------------------------------------------------------------
595
596void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
597{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700598 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800599 const Transform tr(hw->getTransform() * s.transform);
600 const uint32_t hw_h = hw->getHeight();
601 Rect win(s.active.w, s.active.h);
602 if (!s.active.crop.isEmpty()) {
603 win.intersect(s.active.crop, &win);
604 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700605 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700606 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800607 if (mesh) {
608 tr.transform(mesh->mVertices[0], win.left, win.top);
609 tr.transform(mesh->mVertices[1], win.left, win.bottom);
610 tr.transform(mesh->mVertices[2], win.right, win.bottom);
611 tr.transform(mesh->mVertices[3], win.right, win.top);
612 for (size_t i=0 ; i<4 ; i++) {
613 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
614 }
615 }
616}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800617
Mathias Agopiana67932f2011-04-20 14:20:59 -0700618bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700619{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700620 // if we don't have a buffer yet, we're translucent regardless of the
621 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700622 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700623 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700624 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700625
626 // if the layer has the opaque flag, then we're always opaque,
627 // otherwise we use the current buffer's format.
628 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700629}
630
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800631bool Layer::isProtected() const
632{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700633 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800634 return (activeBuffer != 0) &&
635 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
636}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700637
Mathias Agopian13127d82013-03-05 17:47:11 -0800638bool Layer::isFixedSize() const {
639 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
640}
641
642bool Layer::isCropped() const {
643 return !mCurrentCrop.isEmpty();
644}
645
646bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
647 return mNeedsFiltering || hw->needsFiltering();
648}
649
650void Layer::setVisibleRegion(const Region& visibleRegion) {
651 // always called from main thread
652 this->visibleRegion = visibleRegion;
653}
654
655void Layer::setCoveredRegion(const Region& coveredRegion) {
656 // always called from main thread
657 this->coveredRegion = coveredRegion;
658}
659
660void Layer::setVisibleNonTransparentRegion(const Region&
661 setVisibleNonTransparentRegion) {
662 // always called from main thread
663 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
664}
665
666// ----------------------------------------------------------------------------
667// transaction
668// ----------------------------------------------------------------------------
669
670uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800671 ATRACE_CALL();
672
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700673 const Layer::State& s(getDrawingState());
674 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800675
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700676 const bool sizeChanged = (c.requested.w != s.requested.w) ||
677 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700678
679 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700680 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000681 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700682 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700683 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
684 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
685 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
686 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700687 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
688 c.active.w, c.active.h,
689 c.active.crop.left,
690 c.active.crop.top,
691 c.active.crop.right,
692 c.active.crop.bottom,
693 c.active.crop.getWidth(),
694 c.active.crop.getHeight(),
695 c.requested.w, c.requested.h,
696 c.requested.crop.left,
697 c.requested.crop.top,
698 c.requested.crop.right,
699 c.requested.crop.bottom,
700 c.requested.crop.getWidth(),
701 c.requested.crop.getHeight(),
702 s.active.w, s.active.h,
703 s.active.crop.left,
704 s.active.crop.top,
705 s.active.crop.right,
706 s.active.crop.bottom,
707 s.active.crop.getWidth(),
708 s.active.crop.getHeight(),
709 s.requested.w, s.requested.h,
710 s.requested.crop.left,
711 s.requested.crop.top,
712 s.requested.crop.right,
713 s.requested.crop.bottom,
714 s.requested.crop.getWidth(),
715 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800716
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700717 // record the new size, form this point on, when the client request
718 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800719 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700720 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800721 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700722
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700723 if (!isFixedSize()) {
724
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700725 const bool resizePending = (c.requested.w != c.active.w) ||
726 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700727
728 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800729 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700730 // if we have a pending resize, unless we are in fixed-size mode.
731 // the drawing state will be updated only once we receive a buffer
732 // with the correct size.
733 //
734 // in particular, we want to make sure the clip (which is part
735 // of the geometry state) is latched together with the size but is
736 // latched immediately when no resizing is involved.
737
738 flags |= eDontUpdateGeometryState;
739 }
740 }
741
Mathias Agopian13127d82013-03-05 17:47:11 -0800742 // always set active to requested, unless we're asked not to
743 // this is used by Layer, which special cases resizes.
744 if (flags & eDontUpdateGeometryState) {
745 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700746 Layer::State& editCurrentState(getCurrentState());
747 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800748 }
749
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700750 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800751 // invalidate and recompute the visible regions if needed
752 flags |= Layer::eVisibleRegion;
753 }
754
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700755 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800756 // invalidate and recompute the visible regions if needed
757 flags |= eVisibleRegion;
758 this->contentDirty = true;
759
760 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700761 const uint8_t type = c.transform.getType();
762 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800763 (type >= Transform::SCALE));
764 }
765
766 // Commit the transaction
767 commitTransaction();
768 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800769}
770
Mathias Agopian13127d82013-03-05 17:47:11 -0800771void Layer::commitTransaction() {
772 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700773}
774
Mathias Agopian13127d82013-03-05 17:47:11 -0800775uint32_t Layer::getTransactionFlags(uint32_t flags) {
776 return android_atomic_and(~flags, &mTransactionFlags) & flags;
777}
778
779uint32_t Layer::setTransactionFlags(uint32_t flags) {
780 return android_atomic_or(flags, &mTransactionFlags);
781}
782
783bool Layer::setPosition(float x, float y) {
784 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
785 return false;
786 mCurrentState.sequence++;
787 mCurrentState.transform.set(x, y);
788 setTransactionFlags(eTransactionNeeded);
789 return true;
790}
791bool Layer::setLayer(uint32_t z) {
792 if (mCurrentState.z == z)
793 return false;
794 mCurrentState.sequence++;
795 mCurrentState.z = z;
796 setTransactionFlags(eTransactionNeeded);
797 return true;
798}
799bool Layer::setSize(uint32_t w, uint32_t h) {
800 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
801 return false;
802 mCurrentState.requested.w = w;
803 mCurrentState.requested.h = h;
804 setTransactionFlags(eTransactionNeeded);
805 return true;
806}
807bool Layer::setAlpha(uint8_t alpha) {
808 if (mCurrentState.alpha == alpha)
809 return false;
810 mCurrentState.sequence++;
811 mCurrentState.alpha = alpha;
812 setTransactionFlags(eTransactionNeeded);
813 return true;
814}
815bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
816 mCurrentState.sequence++;
817 mCurrentState.transform.set(
818 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
819 setTransactionFlags(eTransactionNeeded);
820 return true;
821}
822bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700823 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800824 setTransactionFlags(eTransactionNeeded);
825 return true;
826}
827bool Layer::setFlags(uint8_t flags, uint8_t mask) {
828 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
829 if (mCurrentState.flags == newFlags)
830 return false;
831 mCurrentState.sequence++;
832 mCurrentState.flags = newFlags;
833 setTransactionFlags(eTransactionNeeded);
834 return true;
835}
836bool Layer::setCrop(const Rect& crop) {
837 if (mCurrentState.requested.crop == crop)
838 return false;
839 mCurrentState.sequence++;
840 mCurrentState.requested.crop = crop;
841 setTransactionFlags(eTransactionNeeded);
842 return true;
843}
844
845bool Layer::setLayerStack(uint32_t layerStack) {
846 if (mCurrentState.layerStack == layerStack)
847 return false;
848 mCurrentState.sequence++;
849 mCurrentState.layerStack = layerStack;
850 setTransactionFlags(eTransactionNeeded);
851 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700852}
853
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800854// ----------------------------------------------------------------------------
855// pageflip handling...
856// ----------------------------------------------------------------------------
857
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800858bool Layer::onPreComposition() {
859 mRefreshPending = false;
860 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800861}
862
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700863void Layer::onPostComposition() {
864 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800865 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800866 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
867
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800868 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800869 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800870 mFrameTracker.setFrameReadyFence(frameReadyFence);
871 } else {
872 // There was no fence for this frame, so assume that it was ready
873 // to be presented at the desired present time.
874 mFrameTracker.setFrameReadyTime(desiredPresentTime);
875 }
876
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700877 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800878 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800879 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800880 mFrameTracker.setActualPresentFence(presentFence);
881 } else {
882 // The HWC doesn't support present fences, so use the refresh
883 // timestamp instead.
884 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
885 mFrameTracker.setActualPresentTime(presentTime);
886 }
887
888 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700889 mFrameLatencyNeeded = false;
890 }
891}
892
Mathias Agopianda27af92012-09-13 18:17:13 -0700893bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800894 const Layer::State& s(mDrawingState);
895 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
896 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700897}
898
Mathias Agopian4fec8732012-06-29 14:12:52 -0700899Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800900{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800901 ATRACE_CALL();
902
Mathias Agopian4fec8732012-06-29 14:12:52 -0700903 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700904 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800905
906 // if we've already called updateTexImage() without going through
907 // a composition step, we have to skip this layer at this point
908 // because we cannot call updateTeximage() without a corresponding
909 // compositionComplete() call.
910 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800911 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700912 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800913 }
914
Jamie Gennis351a5132011-09-14 18:23:37 -0700915 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700916 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700917 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700918
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800919 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700920 Layer::State& front;
921 Layer::State& current;
922 bool& recomputeVisibleRegions;
923 Reject(Layer::State& front, Layer::State& current,
924 bool& recomputeVisibleRegions)
925 : front(front), current(current),
926 recomputeVisibleRegions(recomputeVisibleRegions) {
927 }
928
929 virtual bool reject(const sp<GraphicBuffer>& buf,
930 const BufferQueue::BufferItem& item) {
931 if (buf == NULL) {
932 return false;
933 }
934
935 uint32_t bufWidth = buf->getWidth();
936 uint32_t bufHeight = buf->getHeight();
937
938 // check that we received a buffer of the right size
939 // (Take the buffer's orientation into account)
940 if (item.mTransform & Transform::ROT_90) {
941 swap(bufWidth, bufHeight);
942 }
943
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700944 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
945 if (front.active != front.requested) {
946
947 if (isFixedSize ||
948 (bufWidth == front.requested.w &&
949 bufHeight == front.requested.h))
950 {
951 // Here we pretend the transaction happened by updating the
952 // current and drawing states. Drawing state is only accessed
953 // in this thread, no need to have it locked
954 front.active = front.requested;
955
956 // We also need to update the current state so that
957 // we don't end-up overwriting the drawing state with
958 // this stale current state during the next transaction
959 //
960 // NOTE: We don't need to hold the transaction lock here
961 // because State::active is only accessed from this thread.
962 current.active = front.active;
963
964 // recompute visible region
965 recomputeVisibleRegions = true;
966 }
967
968 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700969 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700970 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
971 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700972 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700973 front.active.w, front.active.h,
974 front.active.crop.left,
975 front.active.crop.top,
976 front.active.crop.right,
977 front.active.crop.bottom,
978 front.active.crop.getWidth(),
979 front.active.crop.getHeight(),
980 front.requested.w, front.requested.h,
981 front.requested.crop.left,
982 front.requested.crop.top,
983 front.requested.crop.right,
984 front.requested.crop.bottom,
985 front.requested.crop.getWidth(),
986 front.requested.crop.getHeight());
987 }
988
989 if (!isFixedSize) {
990 if (front.active.w != bufWidth ||
991 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -0700992 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700993 return true;
994 }
995 }
Mathias Agopian2ca79392013-04-02 18:30:32 -0700996
997 // if the transparent region has changed (this test is
998 // conservative, but that's fine, worst case we're doing
999 // a bit of extra work), we latch the new one and we
1000 // trigger a visible-region recompute.
1001 if (!front.activeTransparentRegion.isTriviallyEqual(
1002 front.requestedTransparentRegion)) {
1003 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001004
1005 // We also need to update the current state so that
1006 // we don't end-up overwriting the drawing state with
1007 // this stale current state during the next transaction
1008 //
1009 // NOTE: We don't need to hold the transaction lock here
1010 // because State::active is only accessed from this thread.
1011 current.activeTransparentRegion = front.activeTransparentRegion;
1012
1013 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001014 recomputeVisibleRegions = true;
1015 }
1016
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001017 return false;
1018 }
1019 };
1020
1021
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001022 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001023
Andy McFadden1585c4d2013-06-28 13:52:40 -07001024 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1025 if (updateResult == BufferQueue::PRESENT_LATER) {
1026 // Producer doesn't want buffer to be displayed yet. Signal a
1027 // layer update so we check again at the next opportunity.
1028 mFlinger->signalLayerUpdate();
1029 return outDirtyRegion;
1030 }
1031
1032 // Decrement the queued-frames count. Signal another event if we
1033 // have more frames pending.
1034 if (android_atomic_dec(&mQueuedFrames) > 1) {
1035 mFlinger->signalLayerUpdate();
1036 }
1037
1038 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001039 // something happened!
1040 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001041 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001042 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001043
Jamie Gennis351a5132011-09-14 18:23:37 -07001044 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001045 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001046 if (mActiveBuffer == NULL) {
1047 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001048 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001049 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001050
Mathias Agopian4824d402012-06-04 18:16:30 -07001051 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001052 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001053 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001054 // the first time we receive a buffer, we need to trigger a
1055 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001056 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001057 }
1058
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001059 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1060 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1061 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001062 if ((crop != mCurrentCrop) ||
1063 (transform != mCurrentTransform) ||
1064 (scalingMode != mCurrentScalingMode))
1065 {
1066 mCurrentCrop = crop;
1067 mCurrentTransform = transform;
1068 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001069 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001070 }
1071
1072 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001073 uint32_t bufWidth = mActiveBuffer->getWidth();
1074 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001075 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1076 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001077 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001078 }
1079 }
1080
1081 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1082 if (oldOpacity != isOpaque()) {
1083 recomputeVisibleRegions = true;
1084 }
1085
Mathias Agopian4fec8732012-06-29 14:12:52 -07001086 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001087 const Layer::State& s(getDrawingState());
1088 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001089
1090 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001091 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001092 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001093 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001094}
1095
Mathias Agopiana67932f2011-04-20 14:20:59 -07001096uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001097{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001098 // TODO: should we do something special if mSecure is set?
1099 if (mProtectedByApp) {
1100 // need a hardware-protected path to external video sink
1101 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001102 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001103 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001104 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001105}
1106
Mathias Agopian84300952012-11-21 16:02:13 -08001107void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001108 uint32_t orientation = 0;
1109 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001110 // The transform hint is used to improve performance, but we can
1111 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001112 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001113 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001114 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001115 if (orientation & Transform::ROT_INVALID) {
1116 orientation = 0;
1117 }
1118 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001119 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001120}
1121
Mathias Agopian13127d82013-03-05 17:47:11 -08001122// ----------------------------------------------------------------------------
1123// debugging
1124// ----------------------------------------------------------------------------
1125
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001126void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001127{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001128 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001129
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001130 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001131 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001132 "+ %s %p (%s)\n",
1133 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001134 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001135
Mathias Agopian2ca79392013-04-02 18:30:32 -07001136 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001137 visibleRegion.dump(result, "visibleRegion");
1138 sp<Client> client(mClientRef.promote());
1139
Mathias Agopian74d211a2013-04-22 16:55:35 +02001140 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001141 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1142 "isOpaque=%1d, invalidate=%1d, "
1143 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1144 " client=%p\n",
1145 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1146 s.active.crop.left, s.active.crop.top,
1147 s.active.crop.right, s.active.crop.bottom,
1148 isOpaque(), contentDirty,
1149 s.alpha, s.flags,
1150 s.transform[0][0], s.transform[0][1],
1151 s.transform[1][0], s.transform[1][1],
1152 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001153
1154 sp<const GraphicBuffer> buf0(mActiveBuffer);
1155 uint32_t w0=0, h0=0, s0=0, f0=0;
1156 if (buf0 != 0) {
1157 w0 = buf0->getWidth();
1158 h0 = buf0->getHeight();
1159 s0 = buf0->getStride();
1160 f0 = buf0->format;
1161 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001162 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001163 " "
1164 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1165 " queued-frames=%d, mRefreshPending=%d\n",
1166 mFormat, w0, h0, s0,f0,
1167 mQueuedFrames, mRefreshPending);
1168
Mathias Agopian13127d82013-03-05 17:47:11 -08001169 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001170 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001171 }
1172}
1173
Mathias Agopian74d211a2013-04-22 16:55:35 +02001174void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001175 mFrameTracker.dump(result);
1176}
1177
1178void Layer::clearStats() {
1179 mFrameTracker.clear();
1180}
1181
1182// ---------------------------------------------------------------------------
1183
1184Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1185 const sp<Layer>& layer)
1186 : mFlinger(flinger), mLayer(layer) {
1187}
1188
1189Layer::LayerCleaner::~LayerCleaner() {
1190 // destroy client resources
1191 mFlinger->onLayerDestroyed(mLayer);
1192}
1193
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001194// ---------------------------------------------------------------------------
1195
1196
1197}; // namespace android