blob: 3605dd4518b263f57a1d4aa4d713c471b0cc8326 [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);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800113 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
Mathias Agopiana0db3082012-04-23 13:59:36 -0700114 GL_TEXTURE_EXTERNAL_OES, false, bq);
Daniel Lamb2675792012-02-23 14:35:13 -0800115
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800116 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
118 mSurfaceFlingerConsumer->setSynchronousMode(true);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700119 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800120
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700121#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
122#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800123 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700124#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800126#endif
Andy McFadden69052052012-09-14 16:10:11 -0700127
Mathias Agopian84300952012-11-21 16:02:13 -0800128 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
129 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700130}
131
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700132Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800133 sp<Client> c(mClientRef.promote());
134 if (c != 0) {
135 c->detachLayer(this);
136 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700137 mFlinger->deleteTextureAsync(mTextureName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700138}
139
Mathias Agopian13127d82013-03-05 17:47:11 -0800140// ---------------------------------------------------------------------------
141// callbacks
142// ---------------------------------------------------------------------------
143
144void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
145 HWComposer::HWCLayerInterface* layer) {
146 if (layer) {
147 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700148 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800149 }
150}
151
Igor Murashkina4a31492012-10-29 13:36:11 -0700152void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700153 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800154 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700155}
156
Mathias Agopian67106042013-03-14 19:18:13 -0700157// called with SurfaceFlinger::mStateLock from the drawing thread after
158// the layer has been remove from the current state list (and just before
159// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800160void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800161 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700162}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700163
Mathias Agopian13127d82013-03-05 17:47:11 -0800164// ---------------------------------------------------------------------------
165// set-up
166// ---------------------------------------------------------------------------
167
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700168const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800169 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800170}
171
Mathias Agopianf9d93272009-06-19 17:00:27 -0700172status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800173 PixelFormat format, uint32_t flags)
174{
Mathias Agopian401c2572009-09-23 19:16:27 -0700175 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800176 PixelFormatInfo info;
177 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800178 if (err) {
179 ALOGE("unsupported pixelformat %d", format);
180 return err;
181 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800182
Mathias Agopianca99fb82010-04-14 16:43:44 -0700183 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700184 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700185
186 // never allow a surface larger than what our underlying GL implementation
187 // can handle.
188 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800189 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700190 return BAD_VALUE;
191 }
192
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700193 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700194
Mathias Agopian3165cc22012-08-08 19:42:09 -0700195 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
196 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
197 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700198 mCurrentOpacity = getOpacityForFormat(format);
199
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800200 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
201 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
202 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700203
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800204 return NO_ERROR;
205}
206
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700207sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800208 Mutex::Autolock _l(mLock);
209
210 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700211 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800212
213 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700214
215 /*
216 * The layer handle is just a BBinder object passed to the client
217 * (remote process) -- we don't keep any reference on our side such that
218 * the dtor is called when the remote side let go of its reference.
219 *
220 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
221 * this layer when the handle is destroyed.
222 */
223
224 class Handle : public BBinder, public LayerCleaner {
225 wp<const Layer> mOwner;
226 public:
227 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
228 : LayerCleaner(flinger, layer), mOwner(layer) {
229 }
230 };
231
232 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800233}
234
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700235sp<BufferQueue> Layer::getBufferQueue() const {
236 return mSurfaceFlingerConsumer->getBufferQueue();
237}
238
Mathias Agopian13127d82013-03-05 17:47:11 -0800239// ---------------------------------------------------------------------------
240// h/w composer set-up
241// ---------------------------------------------------------------------------
242
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800243Rect Layer::getContentCrop() const {
244 // this is the crop rectangle that applies to the buffer
245 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700246 Rect crop;
247 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800248 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700249 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800250 } else if (mActiveBuffer != NULL) {
251 // otherwise we use the whole buffer
252 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700253 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800254 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700255 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700256 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700257 return crop;
258}
259
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800260uint32_t Layer::getContentTransform() const {
261 return mCurrentTransform;
262}
263
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700264static Rect reduce(const Rect& win, const Region& exclude) {
265 if (CC_LIKELY(exclude.isEmpty())) {
266 return win;
267 }
268 if (exclude.isRect()) {
269 return win.reduce(exclude.getBounds());
270 }
271 return Region(win).subtract(exclude).getBounds();
272}
273
Mathias Agopian13127d82013-03-05 17:47:11 -0800274Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700275 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800276 Rect win(s.active.w, s.active.h);
277 if (!s.active.crop.isEmpty()) {
278 win.intersect(s.active.crop, &win);
279 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700280 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700281 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800282}
283
284Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
285 /*
286 * The way we compute the crop (aka. texture coordinates when we have a
287 * Layer) produces a different output from the GL code in
288 * drawWithOpenGL() due to HWC being limited to integers. The difference
289 * can be large if getContentTransform() contains a large scale factor.
290 * See comments in drawWithOpenGL() for more details.
291 */
292
293 // the content crop is the area of the content that gets scaled to the
294 // layer's size.
295 Rect crop(getContentCrop());
296
297 // the active.crop is the area of the window that gets cropped, but not
298 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700299 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800300
301 // apply the projection's clipping to the window crop in
302 // layerstack space, and convert-back to layer space.
303 // if there are no window scaling (or content scaling) involved,
304 // this operation will map to full pixels in the buffer.
305 // NOTE: should we revert to GL composition if a scaling is involved
306 // since it cannot be represented in the HWC API?
307 Rect activeCrop(s.transform.transform(s.active.crop));
308 activeCrop.intersect(hw->getViewport(), &activeCrop);
309 activeCrop = s.transform.inverse().transform(activeCrop);
310
311 // paranoia: make sure the window-crop is constrained in the
312 // window's bounds
313 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
314
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700315 // subtract the transparent region and snap to the bounds
316 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
317
Mathias Agopian13127d82013-03-05 17:47:11 -0800318 if (!activeCrop.isEmpty()) {
319 // Transform the window crop to match the buffer coordinate system,
320 // which means using the inverse of the current transform set on the
321 // SurfaceFlingerConsumer.
322 uint32_t invTransform = getContentTransform();
323 int winWidth = s.active.w;
324 int winHeight = s.active.h;
325 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
326 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
327 NATIVE_WINDOW_TRANSFORM_FLIP_H;
328 winWidth = s.active.h;
329 winHeight = s.active.w;
330 }
331 const Rect winCrop = activeCrop.transform(
332 invTransform, s.active.w, s.active.h);
333
334 // the code below essentially performs a scaled intersection
335 // of crop and winCrop
336 float xScale = float(crop.width()) / float(winWidth);
337 float yScale = float(crop.height()) / float(winHeight);
338
339 int insetL = int(ceilf( winCrop.left * xScale));
340 int insetT = int(ceilf( winCrop.top * yScale));
341 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
342 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
343
344 crop.left += insetL;
345 crop.top += insetT;
346 crop.right -= insetR;
347 crop.bottom -= insetB;
348 }
349 return crop;
350}
351
Mathias Agopian4fec8732012-06-29 14:12:52 -0700352void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700353 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700354 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700355{
Mathias Agopian13127d82013-03-05 17:47:11 -0800356 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700357
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700358 // enable this layer
359 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700360
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700361 if (isSecure() && !hw->isSecure()) {
362 layer.setSkip(true);
363 }
364
Mathias Agopian13127d82013-03-05 17:47:11 -0800365 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700366 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800367 if (!isOpaque() || s.alpha != 0xFF) {
368 layer.setBlending(mPremultipliedAlpha ?
369 HWC_BLENDING_PREMULT :
370 HWC_BLENDING_COVERAGE);
371 }
372
373 // apply the layer's transform, followed by the display's global transform
374 // here we're guaranteed that the layer's transform preserves rects
375 Rect frame(s.transform.transform(computeBounds()));
376 frame.intersect(hw->getViewport(), &frame);
377 const Transform& tr(hw->getTransform());
378 layer.setFrame(tr.transform(frame));
379 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800380 layer.setPlaneAlpha(s.alpha);
381
Mathias Agopian29a367b2011-07-12 14:51:45 -0700382 /*
383 * Transformations are applied in this order:
384 * 1) buffer orientation/flip/mirror
385 * 2) state transformation (window manager)
386 * 3) layer orientation (screen orientation)
387 * (NOTE: the matrices are multiplied in reverse order)
388 */
389
390 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800391 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700392
393 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800394 const uint32_t orientation = transform.getOrientation();
395 if (orientation & Transform::ROT_INVALID) {
396 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700397 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700398 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800399 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700400 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700401}
402
Mathias Agopian42977342012-08-05 00:40:46 -0700403void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700404 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800405 // we have to set the visible region on every frame because
406 // we currently free it during onLayerDisplayed(), which is called
407 // after HWComposer::commit() -- every frame.
408 // Apply this display's projection's viewport to the visible region
409 // before giving it to the HWC HAL.
410 const Transform& tr = hw->getTransform();
411 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
412 layer.setVisibleRegionScreen(visible);
413
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700414 // NOTE: buffer can be NULL if the client never drew into this
415 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700416 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700417}
Jesse Halldc5b4852012-06-29 15:21:18 -0700418
Mathias Agopian42977342012-08-05 00:40:46 -0700419void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700420 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700421 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700422
423 // TODO: there is a possible optimization here: we only need to set the
424 // acquire fence the first time a new buffer is acquired on EACH display.
425
426 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800427 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800428 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700429 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700430 if (fenceFd == -1) {
431 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
432 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700433 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700434 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700435 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700436}
437
Mathias Agopian13127d82013-03-05 17:47:11 -0800438// ---------------------------------------------------------------------------
439// drawing...
440// ---------------------------------------------------------------------------
441
442void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
443 onDraw(hw, clip);
444}
445
446void Layer::draw(const sp<const DisplayDevice>& hw) {
447 onDraw( hw, Region(hw->bounds()) );
448}
449
Mathias Agopian42977342012-08-05 00:40:46 -0700450void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800451{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800452 ATRACE_CALL();
453
Mathias Agopiana67932f2011-04-20 14:20:59 -0700454 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800455 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700456 // in fact never been drawn into. This happens frequently with
457 // SurfaceView because the WindowManager can't know when the client
458 // has drawn the first time.
459
460 // If there is nothing under us, we paint the screen in black, otherwise
461 // we just skip this update.
462
463 // figure out if there is something below us
464 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700465 const SurfaceFlinger::LayerVector& drawingLayers(
466 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700467 const size_t count = drawingLayers.size();
468 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800469 const sp<Layer>& layer(drawingLayers[i]);
470 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700471 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700472 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700473 }
474 // if not everything below us is covered, we plug the holes!
475 Region holes(clip.subtract(under));
476 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700477 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700478 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800479 return;
480 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700481
Andy McFadden97eba892012-12-11 15:21:45 -0800482 // Bind the current buffer to the GL texture, and wait for it to be
483 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800484 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
485 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800486 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700487 // Go ahead and draw the buffer anyway; no matter what we do the screen
488 // is probably going to have something visibly wrong.
489 }
490
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700491 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
492
Mathias Agopian875d8e12013-06-07 15:35:48 -0700493 RenderEngine& engine(mFlinger->getRenderEngine());
494
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700495 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700496 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700497 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700498
499 // Query the texture matrix given our current filtering mode.
500 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800501 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
502 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700503
504 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700505 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700506 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700507 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700508 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700509 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700510 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800511}
512
Mathias Agopian13127d82013-03-05 17:47:11 -0800513
514void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
515 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
516{
Mathias Agopian13127d82013-03-05 17:47:11 -0800517 LayerMesh mesh;
518 computeGeometry(hw, &mesh);
519
Mathias Agopian875d8e12013-06-07 15:35:48 -0700520 mFlinger->getRenderEngine().clearWithColor(
521 mesh.getVertices(), mesh.getVertexCount(),
522 red, green, blue, alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800523}
524
525void Layer::clearWithOpenGL(
526 const sp<const DisplayDevice>& hw, const Region& clip) const {
527 clearWithOpenGL(hw, clip, 0,0,0,0);
528}
529
530void Layer::drawWithOpenGL(
531 const sp<const DisplayDevice>& hw, const Region& clip) const {
532 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700533 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800534
Mathias Agopian13127d82013-03-05 17:47:11 -0800535 LayerMesh mesh;
536 computeGeometry(hw, &mesh);
537
Mathias Agopian13127d82013-03-05 17:47:11 -0800538 /*
539 * NOTE: the way we compute the texture coordinates here produces
540 * different results than when we take the HWC path -- in the later case
541 * the "source crop" is rounded to texel boundaries.
542 * This can produce significantly different results when the texture
543 * is scaled by a large amount.
544 *
545 * The GL code below is more logical (imho), and the difference with
546 * HWC is due to a limitation of the HWC API to integers -- a question
547 * is suspend is wether we should ignore this problem or revert to
548 * GL composition when a buffer scaling is applied (maybe with some
549 * minimal value)? Or, we could make GL behave like HWC -- but this feel
550 * like more of a hack.
551 */
552 const Rect win(computeBounds());
553
554 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
555 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
556 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
557 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
558
Mathias Agopian875d8e12013-06-07 15:35:48 -0700559 // TODO: we probably want to generate the texture coords with the mesh
560 // here we assume that we only have 4 vertices
561 float texCoords[4][2];
562 texCoords[0][0] = left;
563 texCoords[0][1] = top;
564 texCoords[1][0] = left;
565 texCoords[1][1] = bottom;
566 texCoords[2][0] = right;
567 texCoords[2][1] = bottom;
568 texCoords[3][0] = right;
569 texCoords[3][1] = top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800570 for (int i = 0; i < 4; i++) {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700571 texCoords[i][1] = 1.0f - texCoords[i][1];
Mathias Agopian13127d82013-03-05 17:47:11 -0800572 }
573
Mathias Agopian875d8e12013-06-07 15:35:48 -0700574 RenderEngine& engine(mFlinger->getRenderEngine());
575 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
576 engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
577 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800578}
579
580void Layer::setFiltering(bool filtering) {
581 mFiltering = filtering;
582}
583
584bool Layer::getFiltering() const {
585 return mFiltering;
586}
587
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800588// As documented in libhardware header, formats in the range
589// 0x100 - 0x1FF are specific to the HAL implementation, and
590// are known to have no alpha channel
591// TODO: move definition for device-specific range into
592// hardware.h, instead of using hard-coded values here.
593#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
594
Mathias Agopiana67932f2011-04-20 14:20:59 -0700595bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800596{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700597 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
598 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800599 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700600 PixelFormatInfo info;
601 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
602 // in case of error (unknown format), we assume no blending
603 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800604}
605
Mathias Agopian13127d82013-03-05 17:47:11 -0800606// ----------------------------------------------------------------------------
607// local state
608// ----------------------------------------------------------------------------
609
610void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
611{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700612 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800613 const Transform tr(hw->getTransform() * s.transform);
614 const uint32_t hw_h = hw->getHeight();
615 Rect win(s.active.w, s.active.h);
616 if (!s.active.crop.isEmpty()) {
617 win.intersect(s.active.crop, &win);
618 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700619 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700620 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800621 if (mesh) {
622 tr.transform(mesh->mVertices[0], win.left, win.top);
623 tr.transform(mesh->mVertices[1], win.left, win.bottom);
624 tr.transform(mesh->mVertices[2], win.right, win.bottom);
625 tr.transform(mesh->mVertices[3], win.right, win.top);
626 for (size_t i=0 ; i<4 ; i++) {
627 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
628 }
629 }
630}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800631
Mathias Agopiana67932f2011-04-20 14:20:59 -0700632bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700633{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700634 // if we don't have a buffer yet, we're translucent regardless of the
635 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700636 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700637 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700638 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700639
640 // if the layer has the opaque flag, then we're always opaque,
641 // otherwise we use the current buffer's format.
642 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700643}
644
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800645bool Layer::isProtected() const
646{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700647 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800648 return (activeBuffer != 0) &&
649 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
650}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700651
Mathias Agopian13127d82013-03-05 17:47:11 -0800652bool Layer::isFixedSize() const {
653 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
654}
655
656bool Layer::isCropped() const {
657 return !mCurrentCrop.isEmpty();
658}
659
660bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
661 return mNeedsFiltering || hw->needsFiltering();
662}
663
664void Layer::setVisibleRegion(const Region& visibleRegion) {
665 // always called from main thread
666 this->visibleRegion = visibleRegion;
667}
668
669void Layer::setCoveredRegion(const Region& coveredRegion) {
670 // always called from main thread
671 this->coveredRegion = coveredRegion;
672}
673
674void Layer::setVisibleNonTransparentRegion(const Region&
675 setVisibleNonTransparentRegion) {
676 // always called from main thread
677 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
678}
679
680// ----------------------------------------------------------------------------
681// transaction
682// ----------------------------------------------------------------------------
683
684uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800685 ATRACE_CALL();
686
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700687 const Layer::State& s(getDrawingState());
688 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800689
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700690 const bool sizeChanged = (c.requested.w != s.requested.w) ||
691 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700692
693 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700694 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000695 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700696 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700697 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
698 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
699 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
700 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700701 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
702 c.active.w, c.active.h,
703 c.active.crop.left,
704 c.active.crop.top,
705 c.active.crop.right,
706 c.active.crop.bottom,
707 c.active.crop.getWidth(),
708 c.active.crop.getHeight(),
709 c.requested.w, c.requested.h,
710 c.requested.crop.left,
711 c.requested.crop.top,
712 c.requested.crop.right,
713 c.requested.crop.bottom,
714 c.requested.crop.getWidth(),
715 c.requested.crop.getHeight(),
716 s.active.w, s.active.h,
717 s.active.crop.left,
718 s.active.crop.top,
719 s.active.crop.right,
720 s.active.crop.bottom,
721 s.active.crop.getWidth(),
722 s.active.crop.getHeight(),
723 s.requested.w, s.requested.h,
724 s.requested.crop.left,
725 s.requested.crop.top,
726 s.requested.crop.right,
727 s.requested.crop.bottom,
728 s.requested.crop.getWidth(),
729 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800730
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700731 // record the new size, form this point on, when the client request
732 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800733 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700734 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800735 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700736
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700737 if (!isFixedSize()) {
738
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700739 const bool resizePending = (c.requested.w != c.active.w) ||
740 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700741
742 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800743 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700744 // if we have a pending resize, unless we are in fixed-size mode.
745 // the drawing state will be updated only once we receive a buffer
746 // with the correct size.
747 //
748 // in particular, we want to make sure the clip (which is part
749 // of the geometry state) is latched together with the size but is
750 // latched immediately when no resizing is involved.
751
752 flags |= eDontUpdateGeometryState;
753 }
754 }
755
Mathias Agopian13127d82013-03-05 17:47:11 -0800756 // always set active to requested, unless we're asked not to
757 // this is used by Layer, which special cases resizes.
758 if (flags & eDontUpdateGeometryState) {
759 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700760 Layer::State& editCurrentState(getCurrentState());
761 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800762 }
763
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700764 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800765 // invalidate and recompute the visible regions if needed
766 flags |= Layer::eVisibleRegion;
767 }
768
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700769 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800770 // invalidate and recompute the visible regions if needed
771 flags |= eVisibleRegion;
772 this->contentDirty = true;
773
774 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700775 const uint8_t type = c.transform.getType();
776 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800777 (type >= Transform::SCALE));
778 }
779
780 // Commit the transaction
781 commitTransaction();
782 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800783}
784
Mathias Agopian13127d82013-03-05 17:47:11 -0800785void Layer::commitTransaction() {
786 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700787}
788
Mathias Agopian13127d82013-03-05 17:47:11 -0800789uint32_t Layer::getTransactionFlags(uint32_t flags) {
790 return android_atomic_and(~flags, &mTransactionFlags) & flags;
791}
792
793uint32_t Layer::setTransactionFlags(uint32_t flags) {
794 return android_atomic_or(flags, &mTransactionFlags);
795}
796
797bool Layer::setPosition(float x, float y) {
798 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
799 return false;
800 mCurrentState.sequence++;
801 mCurrentState.transform.set(x, y);
802 setTransactionFlags(eTransactionNeeded);
803 return true;
804}
805bool Layer::setLayer(uint32_t z) {
806 if (mCurrentState.z == z)
807 return false;
808 mCurrentState.sequence++;
809 mCurrentState.z = z;
810 setTransactionFlags(eTransactionNeeded);
811 return true;
812}
813bool Layer::setSize(uint32_t w, uint32_t h) {
814 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
815 return false;
816 mCurrentState.requested.w = w;
817 mCurrentState.requested.h = h;
818 setTransactionFlags(eTransactionNeeded);
819 return true;
820}
821bool Layer::setAlpha(uint8_t alpha) {
822 if (mCurrentState.alpha == alpha)
823 return false;
824 mCurrentState.sequence++;
825 mCurrentState.alpha = alpha;
826 setTransactionFlags(eTransactionNeeded);
827 return true;
828}
829bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
830 mCurrentState.sequence++;
831 mCurrentState.transform.set(
832 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
833 setTransactionFlags(eTransactionNeeded);
834 return true;
835}
836bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700837 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800838 setTransactionFlags(eTransactionNeeded);
839 return true;
840}
841bool Layer::setFlags(uint8_t flags, uint8_t mask) {
842 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
843 if (mCurrentState.flags == newFlags)
844 return false;
845 mCurrentState.sequence++;
846 mCurrentState.flags = newFlags;
847 setTransactionFlags(eTransactionNeeded);
848 return true;
849}
850bool Layer::setCrop(const Rect& crop) {
851 if (mCurrentState.requested.crop == crop)
852 return false;
853 mCurrentState.sequence++;
854 mCurrentState.requested.crop = crop;
855 setTransactionFlags(eTransactionNeeded);
856 return true;
857}
858
859bool Layer::setLayerStack(uint32_t layerStack) {
860 if (mCurrentState.layerStack == layerStack)
861 return false;
862 mCurrentState.sequence++;
863 mCurrentState.layerStack = layerStack;
864 setTransactionFlags(eTransactionNeeded);
865 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700866}
867
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800868// ----------------------------------------------------------------------------
869// pageflip handling...
870// ----------------------------------------------------------------------------
871
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800872bool Layer::onPreComposition() {
873 mRefreshPending = false;
874 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800875}
876
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700877void Layer::onPostComposition() {
878 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800879 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800880 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
881
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800882 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800883 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800884 mFrameTracker.setFrameReadyFence(frameReadyFence);
885 } else {
886 // There was no fence for this frame, so assume that it was ready
887 // to be presented at the desired present time.
888 mFrameTracker.setFrameReadyTime(desiredPresentTime);
889 }
890
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700891 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800892 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800893 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800894 mFrameTracker.setActualPresentFence(presentFence);
895 } else {
896 // The HWC doesn't support present fences, so use the refresh
897 // timestamp instead.
898 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
899 mFrameTracker.setActualPresentTime(presentTime);
900 }
901
902 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700903 mFrameLatencyNeeded = false;
904 }
905}
906
Mathias Agopianda27af92012-09-13 18:17:13 -0700907bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800908 const Layer::State& s(mDrawingState);
909 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
910 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700911}
912
Mathias Agopian4fec8732012-06-29 14:12:52 -0700913Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800914{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800915 ATRACE_CALL();
916
Mathias Agopian4fec8732012-06-29 14:12:52 -0700917 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700918 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800919
920 // if we've already called updateTexImage() without going through
921 // a composition step, we have to skip this layer at this point
922 // because we cannot call updateTeximage() without a corresponding
923 // compositionComplete() call.
924 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800925 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700926 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800927 }
928
Jamie Gennis351a5132011-09-14 18:23:37 -0700929 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700930 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700931 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700932
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700933 // signal another event if we have more frames pending
934 if (android_atomic_dec(&mQueuedFrames) > 1) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800935 mFlinger->signalLayerUpdate();
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700936 }
937
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800938 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700939 Layer::State& front;
940 Layer::State& current;
941 bool& recomputeVisibleRegions;
942 Reject(Layer::State& front, Layer::State& current,
943 bool& recomputeVisibleRegions)
944 : front(front), current(current),
945 recomputeVisibleRegions(recomputeVisibleRegions) {
946 }
947
948 virtual bool reject(const sp<GraphicBuffer>& buf,
949 const BufferQueue::BufferItem& item) {
950 if (buf == NULL) {
951 return false;
952 }
953
954 uint32_t bufWidth = buf->getWidth();
955 uint32_t bufHeight = buf->getHeight();
956
957 // check that we received a buffer of the right size
958 // (Take the buffer's orientation into account)
959 if (item.mTransform & Transform::ROT_90) {
960 swap(bufWidth, bufHeight);
961 }
962
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700963 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
964 if (front.active != front.requested) {
965
966 if (isFixedSize ||
967 (bufWidth == front.requested.w &&
968 bufHeight == front.requested.h))
969 {
970 // Here we pretend the transaction happened by updating the
971 // current and drawing states. Drawing state is only accessed
972 // in this thread, no need to have it locked
973 front.active = front.requested;
974
975 // We also need to update the current state so that
976 // we don't end-up overwriting the drawing state with
977 // this stale current state during the next transaction
978 //
979 // NOTE: We don't need to hold the transaction lock here
980 // because State::active is only accessed from this thread.
981 current.active = front.active;
982
983 // recompute visible region
984 recomputeVisibleRegions = true;
985 }
986
987 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700988 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700989 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
990 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700991 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700992 front.active.w, front.active.h,
993 front.active.crop.left,
994 front.active.crop.top,
995 front.active.crop.right,
996 front.active.crop.bottom,
997 front.active.crop.getWidth(),
998 front.active.crop.getHeight(),
999 front.requested.w, front.requested.h,
1000 front.requested.crop.left,
1001 front.requested.crop.top,
1002 front.requested.crop.right,
1003 front.requested.crop.bottom,
1004 front.requested.crop.getWidth(),
1005 front.requested.crop.getHeight());
1006 }
1007
1008 if (!isFixedSize) {
1009 if (front.active.w != bufWidth ||
1010 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001011 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001012 return true;
1013 }
1014 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001015
1016 // if the transparent region has changed (this test is
1017 // conservative, but that's fine, worst case we're doing
1018 // a bit of extra work), we latch the new one and we
1019 // trigger a visible-region recompute.
1020 if (!front.activeTransparentRegion.isTriviallyEqual(
1021 front.requestedTransparentRegion)) {
1022 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001023
1024 // We also need to update the current state so that
1025 // we don't end-up overwriting the drawing state with
1026 // this stale current state during the next transaction
1027 //
1028 // NOTE: We don't need to hold the transaction lock here
1029 // because State::active is only accessed from this thread.
1030 current.activeTransparentRegion = front.activeTransparentRegion;
1031
1032 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001033 recomputeVisibleRegions = true;
1034 }
1035
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001036 return false;
1037 }
1038 };
1039
1040
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001041 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001042
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001043 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001044 // something happened!
1045 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001046 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001047 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001048
Jamie Gennis351a5132011-09-14 18:23:37 -07001049 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001050 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001051 if (mActiveBuffer == NULL) {
1052 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001053 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001054 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001055
Mathias Agopian4824d402012-06-04 18:16:30 -07001056 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001057 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001058 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001059 // the first time we receive a buffer, we need to trigger a
1060 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001061 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001062 }
1063
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001064 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1065 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1066 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001067 if ((crop != mCurrentCrop) ||
1068 (transform != mCurrentTransform) ||
1069 (scalingMode != mCurrentScalingMode))
1070 {
1071 mCurrentCrop = crop;
1072 mCurrentTransform = transform;
1073 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001074 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001075 }
1076
1077 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001078 uint32_t bufWidth = mActiveBuffer->getWidth();
1079 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001080 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1081 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001082 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001083 }
1084 }
1085
1086 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1087 if (oldOpacity != isOpaque()) {
1088 recomputeVisibleRegions = true;
1089 }
1090
Mathias Agopian4fec8732012-06-29 14:12:52 -07001091 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001092 const Layer::State& s(getDrawingState());
1093 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001094
1095 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001096 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001097 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001098 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001099}
1100
Mathias Agopiana67932f2011-04-20 14:20:59 -07001101uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001102{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001103 // TODO: should we do something special if mSecure is set?
1104 if (mProtectedByApp) {
1105 // need a hardware-protected path to external video sink
1106 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001107 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001108 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001109 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001110}
1111
Mathias Agopian84300952012-11-21 16:02:13 -08001112void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001113 uint32_t orientation = 0;
1114 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001115 // The transform hint is used to improve performance, but we can
1116 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001117 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001118 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001119 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001120 if (orientation & Transform::ROT_INVALID) {
1121 orientation = 0;
1122 }
1123 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001124 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001125}
1126
Mathias Agopian13127d82013-03-05 17:47:11 -08001127// ----------------------------------------------------------------------------
1128// debugging
1129// ----------------------------------------------------------------------------
1130
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001131void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001132{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001133 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001134
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001135 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001136 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001137 "+ %s %p (%s)\n",
1138 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001139 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001140
Mathias Agopian2ca79392013-04-02 18:30:32 -07001141 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001142 visibleRegion.dump(result, "visibleRegion");
1143 sp<Client> client(mClientRef.promote());
1144
Mathias Agopian74d211a2013-04-22 16:55:35 +02001145 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001146 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1147 "isOpaque=%1d, invalidate=%1d, "
1148 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1149 " client=%p\n",
1150 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1151 s.active.crop.left, s.active.crop.top,
1152 s.active.crop.right, s.active.crop.bottom,
1153 isOpaque(), contentDirty,
1154 s.alpha, s.flags,
1155 s.transform[0][0], s.transform[0][1],
1156 s.transform[1][0], s.transform[1][1],
1157 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001158
1159 sp<const GraphicBuffer> buf0(mActiveBuffer);
1160 uint32_t w0=0, h0=0, s0=0, f0=0;
1161 if (buf0 != 0) {
1162 w0 = buf0->getWidth();
1163 h0 = buf0->getHeight();
1164 s0 = buf0->getStride();
1165 f0 = buf0->format;
1166 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001167 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001168 " "
1169 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1170 " queued-frames=%d, mRefreshPending=%d\n",
1171 mFormat, w0, h0, s0,f0,
1172 mQueuedFrames, mRefreshPending);
1173
Mathias Agopian13127d82013-03-05 17:47:11 -08001174 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001175 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001176 }
1177}
1178
Mathias Agopian74d211a2013-04-22 16:55:35 +02001179void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001180 mFrameTracker.dump(result);
1181}
1182
1183void Layer::clearStats() {
1184 mFrameTracker.clear();
1185}
1186
1187// ---------------------------------------------------------------------------
1188
1189Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1190 const sp<Layer>& layer)
1191 : mFlinger(flinger), mLayer(layer) {
1192}
1193
1194Layer::LayerCleaner::~LayerCleaner() {
1195 // destroy client resources
1196 mFlinger->onLayerDestroyed(mLayer);
1197}
1198
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001199// ---------------------------------------------------------------------------
1200
1201
1202}; // namespace android