blob: 2defe34db5d42d4ad7091690fee45da39009b223 [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 Agopiandb89edc2013-08-02 01:40:18 -0700116 mBufferQueue = new SurfaceTextureLayer(mFlinger);
117 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName,
Mathias Agopian8f938a52013-07-12 22:06:26 -0700118 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 Agopianca99fb82010-04-14 16:43:44 -0700179 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700180 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700181
182 // never allow a surface larger than what our underlying GL implementation
183 // can handle.
184 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800185 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700186 return BAD_VALUE;
187 }
188
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700189 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700190
Mathias Agopian3165cc22012-08-08 19:42:09 -0700191 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
192 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
193 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700194 mCurrentOpacity = getOpacityForFormat(format);
195
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800196 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
197 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
198 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700199
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800200 return NO_ERROR;
201}
202
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700203sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800204 Mutex::Autolock _l(mLock);
205
206 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700207 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800208
209 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700210
211 /*
212 * The layer handle is just a BBinder object passed to the client
213 * (remote process) -- we don't keep any reference on our side such that
214 * the dtor is called when the remote side let go of its reference.
215 *
216 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
217 * this layer when the handle is destroyed.
218 */
219
220 class Handle : public BBinder, public LayerCleaner {
221 wp<const Layer> mOwner;
222 public:
223 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
224 : LayerCleaner(flinger, layer), mOwner(layer) {
225 }
226 };
227
228 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800229}
230
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700231sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
232 return mBufferQueue;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700233}
234
Mathias Agopian13127d82013-03-05 17:47:11 -0800235// ---------------------------------------------------------------------------
236// h/w composer set-up
237// ---------------------------------------------------------------------------
238
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800239Rect Layer::getContentCrop() const {
240 // this is the crop rectangle that applies to the buffer
241 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700242 Rect crop;
243 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800244 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700245 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800246 } else if (mActiveBuffer != NULL) {
247 // otherwise we use the whole buffer
248 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700249 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800250 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700251 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700252 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700253 return crop;
254}
255
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700256static Rect reduce(const Rect& win, const Region& exclude) {
257 if (CC_LIKELY(exclude.isEmpty())) {
258 return win;
259 }
260 if (exclude.isRect()) {
261 return win.reduce(exclude.getBounds());
262 }
263 return Region(win).subtract(exclude).getBounds();
264}
265
Mathias Agopian13127d82013-03-05 17:47:11 -0800266Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700267 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800268 Rect win(s.active.w, s.active.h);
269 if (!s.active.crop.isEmpty()) {
270 win.intersect(s.active.crop, &win);
271 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700272 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700273 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800274}
275
Mathias Agopian6b442672013-07-09 21:24:52 -0700276FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800277 // the content crop is the area of the content that gets scaled to the
278 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700279 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800280
281 // the active.crop is the area of the window that gets cropped, but not
282 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700283 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800284
285 // apply the projection's clipping to the window crop in
286 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700287 // if there are no window scaling involved, this operation will map to full
288 // pixels in the buffer.
289 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
290 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian13127d82013-03-05 17:47:11 -0800291 Rect activeCrop(s.transform.transform(s.active.crop));
292 activeCrop.intersect(hw->getViewport(), &activeCrop);
293 activeCrop = s.transform.inverse().transform(activeCrop);
294
295 // paranoia: make sure the window-crop is constrained in the
296 // window's bounds
297 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
298
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700299 // subtract the transparent region and snap to the bounds
300 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
301
Mathias Agopian13127d82013-03-05 17:47:11 -0800302 if (!activeCrop.isEmpty()) {
303 // Transform the window crop to match the buffer coordinate system,
304 // which means using the inverse of the current transform set on the
305 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700306 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800307 int winWidth = s.active.w;
308 int winHeight = s.active.h;
309 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
310 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
311 NATIVE_WINDOW_TRANSFORM_FLIP_H;
312 winWidth = s.active.h;
313 winHeight = s.active.w;
314 }
315 const Rect winCrop = activeCrop.transform(
316 invTransform, s.active.w, s.active.h);
317
Mathias Agopian6b442672013-07-09 21:24:52 -0700318 // below, crop is intersected with winCrop expressed in crop's coordinate space
319 float xScale = crop.getWidth() / float(winWidth);
320 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800321
Mathias Agopian6b442672013-07-09 21:24:52 -0700322 float insetL = winCrop.left * xScale;
323 float insetT = winCrop.top * yScale;
324 float insetR = (winWidth - winCrop.right ) * xScale;
325 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800326
327 crop.left += insetL;
328 crop.top += insetT;
329 crop.right -= insetR;
330 crop.bottom -= insetB;
331 }
332 return crop;
333}
334
Mathias Agopian4fec8732012-06-29 14:12:52 -0700335void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700336 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700337 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700338{
Mathias Agopian13127d82013-03-05 17:47:11 -0800339 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700340
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700341 // enable this layer
342 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700343
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700344 if (isSecure() && !hw->isSecure()) {
345 layer.setSkip(true);
346 }
347
Mathias Agopian13127d82013-03-05 17:47:11 -0800348 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700349 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800350 if (!isOpaque() || s.alpha != 0xFF) {
351 layer.setBlending(mPremultipliedAlpha ?
352 HWC_BLENDING_PREMULT :
353 HWC_BLENDING_COVERAGE);
354 }
355
356 // apply the layer's transform, followed by the display's global transform
357 // here we're guaranteed that the layer's transform preserves rects
358 Rect frame(s.transform.transform(computeBounds()));
359 frame.intersect(hw->getViewport(), &frame);
360 const Transform& tr(hw->getTransform());
361 layer.setFrame(tr.transform(frame));
362 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800363 layer.setPlaneAlpha(s.alpha);
364
Mathias Agopian29a367b2011-07-12 14:51:45 -0700365 /*
366 * Transformations are applied in this order:
367 * 1) buffer orientation/flip/mirror
368 * 2) state transformation (window manager)
369 * 3) layer orientation (screen orientation)
370 * (NOTE: the matrices are multiplied in reverse order)
371 */
372
373 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800374 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700375
376 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800377 const uint32_t orientation = transform.getOrientation();
378 if (orientation & Transform::ROT_INVALID) {
379 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700380 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700381 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800382 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700383 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700384}
385
Mathias Agopian42977342012-08-05 00:40:46 -0700386void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700387 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800388 // we have to set the visible region on every frame because
389 // we currently free it during onLayerDisplayed(), which is called
390 // after HWComposer::commit() -- every frame.
391 // Apply this display's projection's viewport to the visible region
392 // before giving it to the HWC HAL.
393 const Transform& tr = hw->getTransform();
394 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
395 layer.setVisibleRegionScreen(visible);
396
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700397 // NOTE: buffer can be NULL if the client never drew into this
398 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700399 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700400}
Jesse Halldc5b4852012-06-29 15:21:18 -0700401
Mathias Agopian42977342012-08-05 00:40:46 -0700402void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700403 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700404 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700405
406 // TODO: there is a possible optimization here: we only need to set the
407 // acquire fence the first time a new buffer is acquired on EACH display.
408
409 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800410 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800411 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700412 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700413 if (fenceFd == -1) {
414 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
415 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700416 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700417 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700418 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700419}
420
Mathias Agopian13127d82013-03-05 17:47:11 -0800421// ---------------------------------------------------------------------------
422// drawing...
423// ---------------------------------------------------------------------------
424
425void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
426 onDraw(hw, clip);
427}
428
429void Layer::draw(const sp<const DisplayDevice>& hw) {
430 onDraw( hw, Region(hw->bounds()) );
431}
432
Mathias Agopian42977342012-08-05 00:40:46 -0700433void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800434{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800435 ATRACE_CALL();
436
Mathias Agopiana67932f2011-04-20 14:20:59 -0700437 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800438 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700439 // in fact never been drawn into. This happens frequently with
440 // SurfaceView because the WindowManager can't know when the client
441 // has drawn the first time.
442
443 // If there is nothing under us, we paint the screen in black, otherwise
444 // we just skip this update.
445
446 // figure out if there is something below us
447 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700448 const SurfaceFlinger::LayerVector& drawingLayers(
449 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700450 const size_t count = drawingLayers.size();
451 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800452 const sp<Layer>& layer(drawingLayers[i]);
453 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700454 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700455 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700456 }
457 // if not everything below us is covered, we plug the holes!
458 Region holes(clip.subtract(under));
459 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700460 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700461 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800462 return;
463 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700464
Andy McFadden97eba892012-12-11 15:21:45 -0800465 // Bind the current buffer to the GL texture, and wait for it to be
466 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800467 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
468 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800469 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700470 // Go ahead and draw the buffer anyway; no matter what we do the screen
471 // is probably going to have something visibly wrong.
472 }
473
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700474 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
475
Mathias Agopian875d8e12013-06-07 15:35:48 -0700476 RenderEngine& engine(mFlinger->getRenderEngine());
477
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700478 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700479 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700480 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700481
482 // Query the texture matrix given our current filtering mode.
483 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800484 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
485 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700486
487 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700488 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700489 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700490 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700491 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700492 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700493 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800494}
495
Mathias Agopian13127d82013-03-05 17:47:11 -0800496
497void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
498 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
499{
Mathias Agopian13127d82013-03-05 17:47:11 -0800500 LayerMesh mesh;
501 computeGeometry(hw, &mesh);
502
Mathias Agopian875d8e12013-06-07 15:35:48 -0700503 mFlinger->getRenderEngine().clearWithColor(
504 mesh.getVertices(), mesh.getVertexCount(),
505 red, green, blue, alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800506}
507
508void Layer::clearWithOpenGL(
509 const sp<const DisplayDevice>& hw, const Region& clip) const {
510 clearWithOpenGL(hw, clip, 0,0,0,0);
511}
512
513void Layer::drawWithOpenGL(
514 const sp<const DisplayDevice>& hw, const Region& clip) const {
515 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700516 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800517
Mathias Agopian13127d82013-03-05 17:47:11 -0800518 LayerMesh mesh;
519 computeGeometry(hw, &mesh);
520
Mathias Agopian13127d82013-03-05 17:47:11 -0800521 /*
522 * NOTE: the way we compute the texture coordinates here produces
523 * different results than when we take the HWC path -- in the later case
524 * the "source crop" is rounded to texel boundaries.
525 * This can produce significantly different results when the texture
526 * is scaled by a large amount.
527 *
528 * The GL code below is more logical (imho), and the difference with
529 * HWC is due to a limitation of the HWC API to integers -- a question
530 * is suspend is wether we should ignore this problem or revert to
531 * GL composition when a buffer scaling is applied (maybe with some
532 * minimal value)? Or, we could make GL behave like HWC -- but this feel
533 * like more of a hack.
534 */
535 const Rect win(computeBounds());
536
537 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
538 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
539 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
540 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
541
Mathias Agopian875d8e12013-06-07 15:35:48 -0700542 // TODO: we probably want to generate the texture coords with the mesh
543 // here we assume that we only have 4 vertices
544 float texCoords[4][2];
545 texCoords[0][0] = left;
546 texCoords[0][1] = top;
547 texCoords[1][0] = left;
548 texCoords[1][1] = bottom;
549 texCoords[2][0] = right;
550 texCoords[2][1] = bottom;
551 texCoords[3][0] = right;
552 texCoords[3][1] = top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800553 for (int i = 0; i < 4; i++) {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700554 texCoords[i][1] = 1.0f - texCoords[i][1];
Mathias Agopian13127d82013-03-05 17:47:11 -0800555 }
556
Mathias Agopian875d8e12013-06-07 15:35:48 -0700557 RenderEngine& engine(mFlinger->getRenderEngine());
558 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
559 engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
560 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800561}
562
563void Layer::setFiltering(bool filtering) {
564 mFiltering = filtering;
565}
566
567bool Layer::getFiltering() const {
568 return mFiltering;
569}
570
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800571// As documented in libhardware header, formats in the range
572// 0x100 - 0x1FF are specific to the HAL implementation, and
573// are known to have no alpha channel
574// TODO: move definition for device-specific range into
575// hardware.h, instead of using hard-coded values here.
576#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
577
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700578bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700579 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
580 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800581 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700582 switch (format) {
583 case HAL_PIXEL_FORMAT_RGBA_8888:
584 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700585 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700586 }
587 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700588 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800589}
590
Mathias Agopian13127d82013-03-05 17:47:11 -0800591// ----------------------------------------------------------------------------
592// local state
593// ----------------------------------------------------------------------------
594
595void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
596{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700597 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800598 const Transform tr(hw->getTransform() * s.transform);
599 const uint32_t hw_h = hw->getHeight();
600 Rect win(s.active.w, s.active.h);
601 if (!s.active.crop.isEmpty()) {
602 win.intersect(s.active.crop, &win);
603 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700604 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700605 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800606 if (mesh) {
607 tr.transform(mesh->mVertices[0], win.left, win.top);
608 tr.transform(mesh->mVertices[1], win.left, win.bottom);
609 tr.transform(mesh->mVertices[2], win.right, win.bottom);
610 tr.transform(mesh->mVertices[3], win.right, win.top);
611 for (size_t i=0 ; i<4 ; i++) {
612 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
613 }
614 }
615}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800616
Mathias Agopiana67932f2011-04-20 14:20:59 -0700617bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700618{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700619 // if we don't have a buffer yet, we're translucent regardless of the
620 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700621 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700622 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700623 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700624
625 // if the layer has the opaque flag, then we're always opaque,
626 // otherwise we use the current buffer's format.
627 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700628}
629
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800630bool Layer::isProtected() const
631{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700632 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800633 return (activeBuffer != 0) &&
634 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
635}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700636
Mathias Agopian13127d82013-03-05 17:47:11 -0800637bool Layer::isFixedSize() const {
638 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
639}
640
641bool Layer::isCropped() const {
642 return !mCurrentCrop.isEmpty();
643}
644
645bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
646 return mNeedsFiltering || hw->needsFiltering();
647}
648
649void Layer::setVisibleRegion(const Region& visibleRegion) {
650 // always called from main thread
651 this->visibleRegion = visibleRegion;
652}
653
654void Layer::setCoveredRegion(const Region& coveredRegion) {
655 // always called from main thread
656 this->coveredRegion = coveredRegion;
657}
658
659void Layer::setVisibleNonTransparentRegion(const Region&
660 setVisibleNonTransparentRegion) {
661 // always called from main thread
662 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
663}
664
665// ----------------------------------------------------------------------------
666// transaction
667// ----------------------------------------------------------------------------
668
669uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800670 ATRACE_CALL();
671
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700672 const Layer::State& s(getDrawingState());
673 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800674
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700675 const bool sizeChanged = (c.requested.w != s.requested.w) ||
676 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700677
678 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700679 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000680 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700681 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700682 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
683 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
684 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
685 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700686 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
687 c.active.w, c.active.h,
688 c.active.crop.left,
689 c.active.crop.top,
690 c.active.crop.right,
691 c.active.crop.bottom,
692 c.active.crop.getWidth(),
693 c.active.crop.getHeight(),
694 c.requested.w, c.requested.h,
695 c.requested.crop.left,
696 c.requested.crop.top,
697 c.requested.crop.right,
698 c.requested.crop.bottom,
699 c.requested.crop.getWidth(),
700 c.requested.crop.getHeight(),
701 s.active.w, s.active.h,
702 s.active.crop.left,
703 s.active.crop.top,
704 s.active.crop.right,
705 s.active.crop.bottom,
706 s.active.crop.getWidth(),
707 s.active.crop.getHeight(),
708 s.requested.w, s.requested.h,
709 s.requested.crop.left,
710 s.requested.crop.top,
711 s.requested.crop.right,
712 s.requested.crop.bottom,
713 s.requested.crop.getWidth(),
714 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800715
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700716 // record the new size, form this point on, when the client request
717 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800718 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700719 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800720 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700721
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700722 if (!isFixedSize()) {
723
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700724 const bool resizePending = (c.requested.w != c.active.w) ||
725 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700726
727 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800728 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700729 // if we have a pending resize, unless we are in fixed-size mode.
730 // the drawing state will be updated only once we receive a buffer
731 // with the correct size.
732 //
733 // in particular, we want to make sure the clip (which is part
734 // of the geometry state) is latched together with the size but is
735 // latched immediately when no resizing is involved.
736
737 flags |= eDontUpdateGeometryState;
738 }
739 }
740
Mathias Agopian13127d82013-03-05 17:47:11 -0800741 // always set active to requested, unless we're asked not to
742 // this is used by Layer, which special cases resizes.
743 if (flags & eDontUpdateGeometryState) {
744 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700745 Layer::State& editCurrentState(getCurrentState());
746 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800747 }
748
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700749 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800750 // invalidate and recompute the visible regions if needed
751 flags |= Layer::eVisibleRegion;
752 }
753
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700754 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800755 // invalidate and recompute the visible regions if needed
756 flags |= eVisibleRegion;
757 this->contentDirty = true;
758
759 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700760 const uint8_t type = c.transform.getType();
761 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800762 (type >= Transform::SCALE));
763 }
764
765 // Commit the transaction
766 commitTransaction();
767 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800768}
769
Mathias Agopian13127d82013-03-05 17:47:11 -0800770void Layer::commitTransaction() {
771 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700772}
773
Mathias Agopian13127d82013-03-05 17:47:11 -0800774uint32_t Layer::getTransactionFlags(uint32_t flags) {
775 return android_atomic_and(~flags, &mTransactionFlags) & flags;
776}
777
778uint32_t Layer::setTransactionFlags(uint32_t flags) {
779 return android_atomic_or(flags, &mTransactionFlags);
780}
781
782bool Layer::setPosition(float x, float y) {
783 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
784 return false;
785 mCurrentState.sequence++;
786 mCurrentState.transform.set(x, y);
787 setTransactionFlags(eTransactionNeeded);
788 return true;
789}
790bool Layer::setLayer(uint32_t z) {
791 if (mCurrentState.z == z)
792 return false;
793 mCurrentState.sequence++;
794 mCurrentState.z = z;
795 setTransactionFlags(eTransactionNeeded);
796 return true;
797}
798bool Layer::setSize(uint32_t w, uint32_t h) {
799 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
800 return false;
801 mCurrentState.requested.w = w;
802 mCurrentState.requested.h = h;
803 setTransactionFlags(eTransactionNeeded);
804 return true;
805}
806bool Layer::setAlpha(uint8_t alpha) {
807 if (mCurrentState.alpha == alpha)
808 return false;
809 mCurrentState.sequence++;
810 mCurrentState.alpha = alpha;
811 setTransactionFlags(eTransactionNeeded);
812 return true;
813}
814bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
815 mCurrentState.sequence++;
816 mCurrentState.transform.set(
817 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
818 setTransactionFlags(eTransactionNeeded);
819 return true;
820}
821bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700822 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800823 setTransactionFlags(eTransactionNeeded);
824 return true;
825}
826bool Layer::setFlags(uint8_t flags, uint8_t mask) {
827 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
828 if (mCurrentState.flags == newFlags)
829 return false;
830 mCurrentState.sequence++;
831 mCurrentState.flags = newFlags;
832 setTransactionFlags(eTransactionNeeded);
833 return true;
834}
835bool Layer::setCrop(const Rect& crop) {
836 if (mCurrentState.requested.crop == crop)
837 return false;
838 mCurrentState.sequence++;
839 mCurrentState.requested.crop = crop;
840 setTransactionFlags(eTransactionNeeded);
841 return true;
842}
843
844bool Layer::setLayerStack(uint32_t layerStack) {
845 if (mCurrentState.layerStack == layerStack)
846 return false;
847 mCurrentState.sequence++;
848 mCurrentState.layerStack = layerStack;
849 setTransactionFlags(eTransactionNeeded);
850 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700851}
852
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800853// ----------------------------------------------------------------------------
854// pageflip handling...
855// ----------------------------------------------------------------------------
856
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800857bool Layer::onPreComposition() {
858 mRefreshPending = false;
859 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800860}
861
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700862void Layer::onPostComposition() {
863 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800864 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800865 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
866
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800867 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800868 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800869 mFrameTracker.setFrameReadyFence(frameReadyFence);
870 } else {
871 // There was no fence for this frame, so assume that it was ready
872 // to be presented at the desired present time.
873 mFrameTracker.setFrameReadyTime(desiredPresentTime);
874 }
875
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700876 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800877 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800878 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800879 mFrameTracker.setActualPresentFence(presentFence);
880 } else {
881 // The HWC doesn't support present fences, so use the refresh
882 // timestamp instead.
883 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
884 mFrameTracker.setActualPresentTime(presentTime);
885 }
886
887 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700888 mFrameLatencyNeeded = false;
889 }
890}
891
Mathias Agopianda27af92012-09-13 18:17:13 -0700892bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800893 const Layer::State& s(mDrawingState);
894 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
895 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700896}
897
Mathias Agopian4fec8732012-06-29 14:12:52 -0700898Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800899{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800900 ATRACE_CALL();
901
Mathias Agopian4fec8732012-06-29 14:12:52 -0700902 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700903 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800904
905 // if we've already called updateTexImage() without going through
906 // a composition step, we have to skip this layer at this point
907 // because we cannot call updateTeximage() without a corresponding
908 // compositionComplete() call.
909 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800910 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700911 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800912 }
913
Jamie Gennis351a5132011-09-14 18:23:37 -0700914 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700915 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700916 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700917
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800918 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700919 Layer::State& front;
920 Layer::State& current;
921 bool& recomputeVisibleRegions;
922 Reject(Layer::State& front, Layer::State& current,
923 bool& recomputeVisibleRegions)
924 : front(front), current(current),
925 recomputeVisibleRegions(recomputeVisibleRegions) {
926 }
927
928 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700929 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700930 if (buf == NULL) {
931 return false;
932 }
933
934 uint32_t bufWidth = buf->getWidth();
935 uint32_t bufHeight = buf->getHeight();
936
937 // check that we received a buffer of the right size
938 // (Take the buffer's orientation into account)
939 if (item.mTransform & Transform::ROT_90) {
940 swap(bufWidth, bufHeight);
941 }
942
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700943 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
944 if (front.active != front.requested) {
945
946 if (isFixedSize ||
947 (bufWidth == front.requested.w &&
948 bufHeight == front.requested.h))
949 {
950 // Here we pretend the transaction happened by updating the
951 // current and drawing states. Drawing state is only accessed
952 // in this thread, no need to have it locked
953 front.active = front.requested;
954
955 // We also need to update the current state so that
956 // we don't end-up overwriting the drawing state with
957 // this stale current state during the next transaction
958 //
959 // NOTE: We don't need to hold the transaction lock here
960 // because State::active is only accessed from this thread.
961 current.active = front.active;
962
963 // recompute visible region
964 recomputeVisibleRegions = true;
965 }
966
967 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700968 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700969 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
970 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700971 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700972 front.active.w, front.active.h,
973 front.active.crop.left,
974 front.active.crop.top,
975 front.active.crop.right,
976 front.active.crop.bottom,
977 front.active.crop.getWidth(),
978 front.active.crop.getHeight(),
979 front.requested.w, front.requested.h,
980 front.requested.crop.left,
981 front.requested.crop.top,
982 front.requested.crop.right,
983 front.requested.crop.bottom,
984 front.requested.crop.getWidth(),
985 front.requested.crop.getHeight());
986 }
987
988 if (!isFixedSize) {
989 if (front.active.w != bufWidth ||
990 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -0700991 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700992 return true;
993 }
994 }
Mathias Agopian2ca79392013-04-02 18:30:32 -0700995
996 // if the transparent region has changed (this test is
997 // conservative, but that's fine, worst case we're doing
998 // a bit of extra work), we latch the new one and we
999 // trigger a visible-region recompute.
1000 if (!front.activeTransparentRegion.isTriviallyEqual(
1001 front.requestedTransparentRegion)) {
1002 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001003
1004 // We also need to update the current state so that
1005 // we don't end-up overwriting the drawing state with
1006 // this stale current state during the next transaction
1007 //
1008 // NOTE: We don't need to hold the transaction lock here
1009 // because State::active is only accessed from this thread.
1010 current.activeTransparentRegion = front.activeTransparentRegion;
1011
1012 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001013 recomputeVisibleRegions = true;
1014 }
1015
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001016 return false;
1017 }
1018 };
1019
1020
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001021 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001022
Andy McFadden1585c4d2013-06-28 13:52:40 -07001023 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1024 if (updateResult == BufferQueue::PRESENT_LATER) {
1025 // Producer doesn't want buffer to be displayed yet. Signal a
1026 // layer update so we check again at the next opportunity.
1027 mFlinger->signalLayerUpdate();
1028 return outDirtyRegion;
1029 }
1030
1031 // Decrement the queued-frames count. Signal another event if we
1032 // have more frames pending.
1033 if (android_atomic_dec(&mQueuedFrames) > 1) {
1034 mFlinger->signalLayerUpdate();
1035 }
1036
1037 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001038 // something happened!
1039 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001040 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001041 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001042
Jamie Gennis351a5132011-09-14 18:23:37 -07001043 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001044 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001045 if (mActiveBuffer == NULL) {
1046 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001047 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001048 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001049
Mathias Agopian4824d402012-06-04 18:16:30 -07001050 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001051 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001052 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001053 // the first time we receive a buffer, we need to trigger a
1054 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001055 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001056 }
1057
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001058 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1059 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1060 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001061 if ((crop != mCurrentCrop) ||
1062 (transform != mCurrentTransform) ||
1063 (scalingMode != mCurrentScalingMode))
1064 {
1065 mCurrentCrop = crop;
1066 mCurrentTransform = transform;
1067 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001068 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001069 }
1070
1071 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001072 uint32_t bufWidth = mActiveBuffer->getWidth();
1073 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001074 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1075 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001076 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001077 }
1078 }
1079
1080 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1081 if (oldOpacity != isOpaque()) {
1082 recomputeVisibleRegions = true;
1083 }
1084
Mathias Agopian4fec8732012-06-29 14:12:52 -07001085 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001086 const Layer::State& s(getDrawingState());
1087 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001088
1089 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001090 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001091 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001092 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001093}
1094
Mathias Agopiana67932f2011-04-20 14:20:59 -07001095uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001096{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001097 // TODO: should we do something special if mSecure is set?
1098 if (mProtectedByApp) {
1099 // need a hardware-protected path to external video sink
1100 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001101 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001102 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001103 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001104}
1105
Mathias Agopian84300952012-11-21 16:02:13 -08001106void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001107 uint32_t orientation = 0;
1108 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001109 // The transform hint is used to improve performance, but we can
1110 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001111 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001112 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001113 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001114 if (orientation & Transform::ROT_INVALID) {
1115 orientation = 0;
1116 }
1117 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001118 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001119}
1120
Mathias Agopian13127d82013-03-05 17:47:11 -08001121// ----------------------------------------------------------------------------
1122// debugging
1123// ----------------------------------------------------------------------------
1124
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001125void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001126{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001127 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001128
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001129 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001130 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001131 "+ %s %p (%s)\n",
1132 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001133 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001134
Mathias Agopian2ca79392013-04-02 18:30:32 -07001135 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001136 visibleRegion.dump(result, "visibleRegion");
1137 sp<Client> client(mClientRef.promote());
1138
Mathias Agopian74d211a2013-04-22 16:55:35 +02001139 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001140 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1141 "isOpaque=%1d, invalidate=%1d, "
1142 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1143 " client=%p\n",
1144 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1145 s.active.crop.left, s.active.crop.top,
1146 s.active.crop.right, s.active.crop.bottom,
1147 isOpaque(), contentDirty,
1148 s.alpha, s.flags,
1149 s.transform[0][0], s.transform[0][1],
1150 s.transform[1][0], s.transform[1][1],
1151 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001152
1153 sp<const GraphicBuffer> buf0(mActiveBuffer);
1154 uint32_t w0=0, h0=0, s0=0, f0=0;
1155 if (buf0 != 0) {
1156 w0 = buf0->getWidth();
1157 h0 = buf0->getHeight();
1158 s0 = buf0->getStride();
1159 f0 = buf0->format;
1160 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001161 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001162 " "
1163 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1164 " queued-frames=%d, mRefreshPending=%d\n",
1165 mFormat, w0, h0, s0,f0,
1166 mQueuedFrames, mRefreshPending);
1167
Mathias Agopian13127d82013-03-05 17:47:11 -08001168 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001169 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001170 }
1171}
1172
Mathias Agopian74d211a2013-04-22 16:55:35 +02001173void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001174 mFrameTracker.dump(result);
1175}
1176
1177void Layer::clearStats() {
1178 mFrameTracker.clear();
1179}
1180
Jamie Gennis6547ff42013-07-16 20:12:42 -07001181void Layer::logFrameStats() {
1182 mFrameTracker.logAndResetStats(mName);
1183}
1184
Mathias Agopian13127d82013-03-05 17:47:11 -08001185// ---------------------------------------------------------------------------
1186
1187Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1188 const sp<Layer>& layer)
1189 : mFlinger(flinger), mLayer(layer) {
1190}
1191
1192Layer::LayerCleaner::~LayerCleaner() {
1193 // destroy client resources
1194 mFlinger->onLayerDestroyed(mLayer);
1195}
1196
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001197// ---------------------------------------------------------------------------
1198
1199
1200}; // namespace android