blob: 2962115bdb8cb287e195ccf844fc911b16eaa5f4 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080019#include <stdlib.h>
20#include <stdint.h>
21#include <sys/types.h>
Mathias Agopian13127d82013-03-05 17:47:11 -080022#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080023
Mathias Agopiana67932f2011-04-20 14:20:59 -070024#include <cutils/compiler.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070025#include <cutils/native_handle.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070026#include <cutils/properties.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080027
28#include <utils/Errors.h>
29#include <utils/Log.h>
30#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080031#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080032
Mathias Agopian3330b202009-10-05 17:07:12 -070033#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080035
Mathias Agopian90ac7992012-02-25 18:48:35 -080036#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080037
38#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020039#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070040#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080041#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "SurfaceFlinger.h"
Mathias Agopiana67932f2011-04-20 14:20:59 -070043#include "SurfaceTextureLayer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080044
Mathias Agopian1b031492012-06-20 17:51:20 -070045#include "DisplayHardware/HWComposer.h"
46
Mathias Agopian875d8e12013-06-07 15:35:48 -070047#include "RenderEngine/RenderEngine.h"
48
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049#define DEBUG_RESIZE 0
50
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051namespace android {
52
53// ---------------------------------------------------------------------------
54
Mathias Agopian13127d82013-03-05 17:47:11 -080055int32_t Layer::sSequence = 1;
56
Mathias Agopian4d9b8222013-03-12 17:11:48 -070057Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
58 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080059 : contentDirty(false),
60 sequence(uint32_t(android_atomic_inc(&sSequence))),
61 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070062 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080063 mPremultipliedAlpha(true),
64 mName("unnamed"),
65 mDebug(false),
66 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 mOpaqueLayer(true),
68 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070069 mQueuedFrames(0),
70 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070071 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070072 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080073 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080074 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080075 mFiltering(false),
76 mNeedsFiltering(false),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070077 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080078 mProtectedByApp(false),
79 mHasSurface(false),
80 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080081{
Mathias Agopiana67932f2011-04-20 14:20:59 -070082 mCurrentCrop.makeInvalid();
83 glGenTextures(1, &mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070084
85 uint32_t layerFlags = 0;
86 if (flags & ISurfaceComposerClient::eHidden)
87 layerFlags = layer_state_t::eLayerHidden;
88
89 if (flags & ISurfaceComposerClient::eNonPremultiplied)
90 mPremultipliedAlpha = false;
91
92 mName = name;
93
94 mCurrentState.active.w = w;
95 mCurrentState.active.h = h;
96 mCurrentState.active.crop.makeInvalid();
97 mCurrentState.z = 0;
98 mCurrentState.alpha = 0xFF;
99 mCurrentState.layerStack = 0;
100 mCurrentState.flags = layerFlags;
101 mCurrentState.sequence = 0;
102 mCurrentState.transform.set(0, 0);
103 mCurrentState.requested = mCurrentState.active;
104
105 // drawing state & current state are identical
106 mDrawingState = mCurrentState;
Jamie Gennise8696a42012-01-15 18:54:57 -0800107}
108
Mathias Agopiana67932f2011-04-20 14:20:59 -0700109void Layer::onFirstRef()
Mathias Agopian96f08192010-06-02 23:28:45 -0700110{
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800111 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopian67106042013-03-14 19:18:13 -0700112 sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
Mathias Agopian8f938a52013-07-12 22:06:26 -0700113 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(bq, mTextureName,
114 GL_TEXTURE_EXTERNAL_OES, false);
Daniel Lamb2675792012-02-23 14:35:13 -0800115
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800116 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
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 Agopianf3e85d42013-05-10 18:01:12 -0700260static Rect reduce(const Rect& win, const Region& exclude) {
261 if (CC_LIKELY(exclude.isEmpty())) {
262 return win;
263 }
264 if (exclude.isRect()) {
265 return win.reduce(exclude.getBounds());
266 }
267 return Region(win).subtract(exclude).getBounds();
268}
269
Mathias Agopian13127d82013-03-05 17:47:11 -0800270Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700271 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800272 Rect win(s.active.w, s.active.h);
273 if (!s.active.crop.isEmpty()) {
274 win.intersect(s.active.crop, &win);
275 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700276 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700277 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800278}
279
Mathias Agopian6b442672013-07-09 21:24:52 -0700280FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800281 // the content crop is the area of the content that gets scaled to the
282 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700283 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800284
285 // the active.crop is the area of the window that gets cropped, but not
286 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700287 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800288
289 // apply the projection's clipping to the window crop in
290 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700291 // if there are no window scaling involved, this operation will map to full
292 // pixels in the buffer.
293 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
294 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian13127d82013-03-05 17:47:11 -0800295 Rect activeCrop(s.transform.transform(s.active.crop));
296 activeCrop.intersect(hw->getViewport(), &activeCrop);
297 activeCrop = s.transform.inverse().transform(activeCrop);
298
299 // paranoia: make sure the window-crop is constrained in the
300 // window's bounds
301 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
302
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700303 // subtract the transparent region and snap to the bounds
304 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
305
Mathias Agopian13127d82013-03-05 17:47:11 -0800306 if (!activeCrop.isEmpty()) {
307 // Transform the window crop to match the buffer coordinate system,
308 // which means using the inverse of the current transform set on the
309 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700310 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800311 int winWidth = s.active.w;
312 int winHeight = s.active.h;
313 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
314 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
315 NATIVE_WINDOW_TRANSFORM_FLIP_H;
316 winWidth = s.active.h;
317 winHeight = s.active.w;
318 }
319 const Rect winCrop = activeCrop.transform(
320 invTransform, s.active.w, s.active.h);
321
Mathias Agopian6b442672013-07-09 21:24:52 -0700322 // below, crop is intersected with winCrop expressed in crop's coordinate space
323 float xScale = crop.getWidth() / float(winWidth);
324 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800325
Mathias Agopian6b442672013-07-09 21:24:52 -0700326 float insetL = winCrop.left * xScale;
327 float insetT = winCrop.top * yScale;
328 float insetR = (winWidth - winCrop.right ) * xScale;
329 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800330
331 crop.left += insetL;
332 crop.top += insetT;
333 crop.right -= insetR;
334 crop.bottom -= insetB;
335 }
336 return crop;
337}
338
Mathias Agopian4fec8732012-06-29 14:12:52 -0700339void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700340 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700341 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700342{
Mathias Agopian13127d82013-03-05 17:47:11 -0800343 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700344
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700345 // enable this layer
346 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700347
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700348 if (isSecure() && !hw->isSecure()) {
349 layer.setSkip(true);
350 }
351
Mathias Agopian13127d82013-03-05 17:47:11 -0800352 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700353 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800354 if (!isOpaque() || s.alpha != 0xFF) {
355 layer.setBlending(mPremultipliedAlpha ?
356 HWC_BLENDING_PREMULT :
357 HWC_BLENDING_COVERAGE);
358 }
359
360 // apply the layer's transform, followed by the display's global transform
361 // here we're guaranteed that the layer's transform preserves rects
362 Rect frame(s.transform.transform(computeBounds()));
363 frame.intersect(hw->getViewport(), &frame);
364 const Transform& tr(hw->getTransform());
365 layer.setFrame(tr.transform(frame));
366 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800367 layer.setPlaneAlpha(s.alpha);
368
Mathias Agopian29a367b2011-07-12 14:51:45 -0700369 /*
370 * Transformations are applied in this order:
371 * 1) buffer orientation/flip/mirror
372 * 2) state transformation (window manager)
373 * 3) layer orientation (screen orientation)
374 * (NOTE: the matrices are multiplied in reverse order)
375 */
376
377 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800378 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700379
380 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800381 const uint32_t orientation = transform.getOrientation();
382 if (orientation & Transform::ROT_INVALID) {
383 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700384 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700385 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800386 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700387 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700388}
389
Mathias Agopian42977342012-08-05 00:40:46 -0700390void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700391 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800392 // we have to set the visible region on every frame because
393 // we currently free it during onLayerDisplayed(), which is called
394 // after HWComposer::commit() -- every frame.
395 // Apply this display's projection's viewport to the visible region
396 // before giving it to the HWC HAL.
397 const Transform& tr = hw->getTransform();
398 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
399 layer.setVisibleRegionScreen(visible);
400
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700401 // NOTE: buffer can be NULL if the client never drew into this
402 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700403 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700404}
Jesse Halldc5b4852012-06-29 15:21:18 -0700405
Mathias Agopian42977342012-08-05 00:40:46 -0700406void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700407 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700408 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700409
410 // TODO: there is a possible optimization here: we only need to set the
411 // acquire fence the first time a new buffer is acquired on EACH display.
412
413 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800414 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800415 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700416 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700417 if (fenceFd == -1) {
418 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
419 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700420 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700421 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700422 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700423}
424
Mathias Agopian13127d82013-03-05 17:47:11 -0800425// ---------------------------------------------------------------------------
426// drawing...
427// ---------------------------------------------------------------------------
428
429void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
430 onDraw(hw, clip);
431}
432
433void Layer::draw(const sp<const DisplayDevice>& hw) {
434 onDraw( hw, Region(hw->bounds()) );
435}
436
Mathias Agopian42977342012-08-05 00:40:46 -0700437void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800438{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800439 ATRACE_CALL();
440
Mathias Agopiana67932f2011-04-20 14:20:59 -0700441 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800442 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700443 // in fact never been drawn into. This happens frequently with
444 // SurfaceView because the WindowManager can't know when the client
445 // has drawn the first time.
446
447 // If there is nothing under us, we paint the screen in black, otherwise
448 // we just skip this update.
449
450 // figure out if there is something below us
451 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700452 const SurfaceFlinger::LayerVector& drawingLayers(
453 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700454 const size_t count = drawingLayers.size();
455 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800456 const sp<Layer>& layer(drawingLayers[i]);
457 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700458 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700459 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700460 }
461 // if not everything below us is covered, we plug the holes!
462 Region holes(clip.subtract(under));
463 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700464 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700465 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800466 return;
467 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700468
Andy McFadden97eba892012-12-11 15:21:45 -0800469 // Bind the current buffer to the GL texture, and wait for it to be
470 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800471 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
472 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800473 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700474 // Go ahead and draw the buffer anyway; no matter what we do the screen
475 // is probably going to have something visibly wrong.
476 }
477
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700478 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
479
Mathias Agopian875d8e12013-06-07 15:35:48 -0700480 RenderEngine& engine(mFlinger->getRenderEngine());
481
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700482 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700483 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700484 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700485
486 // Query the texture matrix given our current filtering mode.
487 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800488 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
489 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700490
491 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700492 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700493 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700494 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700495 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700496 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700497 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800498}
499
Mathias Agopian13127d82013-03-05 17:47:11 -0800500
501void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
502 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
503{
Mathias Agopian13127d82013-03-05 17:47:11 -0800504 LayerMesh mesh;
505 computeGeometry(hw, &mesh);
506
Mathias Agopian875d8e12013-06-07 15:35:48 -0700507 mFlinger->getRenderEngine().clearWithColor(
508 mesh.getVertices(), mesh.getVertexCount(),
509 red, green, blue, alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800510}
511
512void Layer::clearWithOpenGL(
513 const sp<const DisplayDevice>& hw, const Region& clip) const {
514 clearWithOpenGL(hw, clip, 0,0,0,0);
515}
516
517void Layer::drawWithOpenGL(
518 const sp<const DisplayDevice>& hw, const Region& clip) const {
519 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700520 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800521
Mathias Agopian13127d82013-03-05 17:47:11 -0800522 LayerMesh mesh;
523 computeGeometry(hw, &mesh);
524
Mathias Agopian13127d82013-03-05 17:47:11 -0800525 /*
526 * NOTE: the way we compute the texture coordinates here produces
527 * different results than when we take the HWC path -- in the later case
528 * the "source crop" is rounded to texel boundaries.
529 * This can produce significantly different results when the texture
530 * is scaled by a large amount.
531 *
532 * The GL code below is more logical (imho), and the difference with
533 * HWC is due to a limitation of the HWC API to integers -- a question
534 * is suspend is wether we should ignore this problem or revert to
535 * GL composition when a buffer scaling is applied (maybe with some
536 * minimal value)? Or, we could make GL behave like HWC -- but this feel
537 * like more of a hack.
538 */
539 const Rect win(computeBounds());
540
541 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
542 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
543 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
544 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
545
Mathias Agopian875d8e12013-06-07 15:35:48 -0700546 // TODO: we probably want to generate the texture coords with the mesh
547 // here we assume that we only have 4 vertices
548 float texCoords[4][2];
549 texCoords[0][0] = left;
550 texCoords[0][1] = top;
551 texCoords[1][0] = left;
552 texCoords[1][1] = bottom;
553 texCoords[2][0] = right;
554 texCoords[2][1] = bottom;
555 texCoords[3][0] = right;
556 texCoords[3][1] = top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800557 for (int i = 0; i < 4; i++) {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700558 texCoords[i][1] = 1.0f - texCoords[i][1];
Mathias Agopian13127d82013-03-05 17:47:11 -0800559 }
560
Mathias Agopian875d8e12013-06-07 15:35:48 -0700561 RenderEngine& engine(mFlinger->getRenderEngine());
562 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
563 engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
564 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800565}
566
567void Layer::setFiltering(bool filtering) {
568 mFiltering = filtering;
569}
570
571bool Layer::getFiltering() const {
572 return mFiltering;
573}
574
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800575// As documented in libhardware header, formats in the range
576// 0x100 - 0x1FF are specific to the HAL implementation, and
577// are known to have no alpha channel
578// TODO: move definition for device-specific range into
579// hardware.h, instead of using hard-coded values here.
580#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
581
Mathias Agopiana67932f2011-04-20 14:20:59 -0700582bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800583{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700584 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
585 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800586 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700587 PixelFormatInfo info;
588 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
589 // in case of error (unknown format), we assume no blending
590 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800591}
592
Mathias Agopian13127d82013-03-05 17:47:11 -0800593// ----------------------------------------------------------------------------
594// local state
595// ----------------------------------------------------------------------------
596
597void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
598{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700599 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800600 const Transform tr(hw->getTransform() * s.transform);
601 const uint32_t hw_h = hw->getHeight();
602 Rect win(s.active.w, s.active.h);
603 if (!s.active.crop.isEmpty()) {
604 win.intersect(s.active.crop, &win);
605 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700606 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700607 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800608 if (mesh) {
609 tr.transform(mesh->mVertices[0], win.left, win.top);
610 tr.transform(mesh->mVertices[1], win.left, win.bottom);
611 tr.transform(mesh->mVertices[2], win.right, win.bottom);
612 tr.transform(mesh->mVertices[3], win.right, win.top);
613 for (size_t i=0 ; i<4 ; i++) {
614 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
615 }
616 }
617}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800618
Mathias Agopiana67932f2011-04-20 14:20:59 -0700619bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700620{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700621 // if we don't have a buffer yet, we're translucent regardless of the
622 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700623 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700624 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700625 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700626
627 // if the layer has the opaque flag, then we're always opaque,
628 // otherwise we use the current buffer's format.
629 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700630}
631
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800632bool Layer::isProtected() const
633{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700634 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800635 return (activeBuffer != 0) &&
636 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
637}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700638
Mathias Agopian13127d82013-03-05 17:47:11 -0800639bool Layer::isFixedSize() const {
640 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
641}
642
643bool Layer::isCropped() const {
644 return !mCurrentCrop.isEmpty();
645}
646
647bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
648 return mNeedsFiltering || hw->needsFiltering();
649}
650
651void Layer::setVisibleRegion(const Region& visibleRegion) {
652 // always called from main thread
653 this->visibleRegion = visibleRegion;
654}
655
656void Layer::setCoveredRegion(const Region& coveredRegion) {
657 // always called from main thread
658 this->coveredRegion = coveredRegion;
659}
660
661void Layer::setVisibleNonTransparentRegion(const Region&
662 setVisibleNonTransparentRegion) {
663 // always called from main thread
664 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
665}
666
667// ----------------------------------------------------------------------------
668// transaction
669// ----------------------------------------------------------------------------
670
671uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800672 ATRACE_CALL();
673
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700674 const Layer::State& s(getDrawingState());
675 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800676
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700677 const bool sizeChanged = (c.requested.w != s.requested.w) ||
678 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700679
680 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700681 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000682 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700683 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700684 " current={ 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"
686 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
687 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700688 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
689 c.active.w, c.active.h,
690 c.active.crop.left,
691 c.active.crop.top,
692 c.active.crop.right,
693 c.active.crop.bottom,
694 c.active.crop.getWidth(),
695 c.active.crop.getHeight(),
696 c.requested.w, c.requested.h,
697 c.requested.crop.left,
698 c.requested.crop.top,
699 c.requested.crop.right,
700 c.requested.crop.bottom,
701 c.requested.crop.getWidth(),
702 c.requested.crop.getHeight(),
703 s.active.w, s.active.h,
704 s.active.crop.left,
705 s.active.crop.top,
706 s.active.crop.right,
707 s.active.crop.bottom,
708 s.active.crop.getWidth(),
709 s.active.crop.getHeight(),
710 s.requested.w, s.requested.h,
711 s.requested.crop.left,
712 s.requested.crop.top,
713 s.requested.crop.right,
714 s.requested.crop.bottom,
715 s.requested.crop.getWidth(),
716 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800717
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700718 // record the new size, form this point on, when the client request
719 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800720 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700721 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800722 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700723
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700724 if (!isFixedSize()) {
725
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700726 const bool resizePending = (c.requested.w != c.active.w) ||
727 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700728
729 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800730 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700731 // if we have a pending resize, unless we are in fixed-size mode.
732 // the drawing state will be updated only once we receive a buffer
733 // with the correct size.
734 //
735 // in particular, we want to make sure the clip (which is part
736 // of the geometry state) is latched together with the size but is
737 // latched immediately when no resizing is involved.
738
739 flags |= eDontUpdateGeometryState;
740 }
741 }
742
Mathias Agopian13127d82013-03-05 17:47:11 -0800743 // always set active to requested, unless we're asked not to
744 // this is used by Layer, which special cases resizes.
745 if (flags & eDontUpdateGeometryState) {
746 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700747 Layer::State& editCurrentState(getCurrentState());
748 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800749 }
750
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700751 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800752 // invalidate and recompute the visible regions if needed
753 flags |= Layer::eVisibleRegion;
754 }
755
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700756 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800757 // invalidate and recompute the visible regions if needed
758 flags |= eVisibleRegion;
759 this->contentDirty = true;
760
761 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700762 const uint8_t type = c.transform.getType();
763 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800764 (type >= Transform::SCALE));
765 }
766
767 // Commit the transaction
768 commitTransaction();
769 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800770}
771
Mathias Agopian13127d82013-03-05 17:47:11 -0800772void Layer::commitTransaction() {
773 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700774}
775
Mathias Agopian13127d82013-03-05 17:47:11 -0800776uint32_t Layer::getTransactionFlags(uint32_t flags) {
777 return android_atomic_and(~flags, &mTransactionFlags) & flags;
778}
779
780uint32_t Layer::setTransactionFlags(uint32_t flags) {
781 return android_atomic_or(flags, &mTransactionFlags);
782}
783
784bool Layer::setPosition(float x, float y) {
785 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
786 return false;
787 mCurrentState.sequence++;
788 mCurrentState.transform.set(x, y);
789 setTransactionFlags(eTransactionNeeded);
790 return true;
791}
792bool Layer::setLayer(uint32_t z) {
793 if (mCurrentState.z == z)
794 return false;
795 mCurrentState.sequence++;
796 mCurrentState.z = z;
797 setTransactionFlags(eTransactionNeeded);
798 return true;
799}
800bool Layer::setSize(uint32_t w, uint32_t h) {
801 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
802 return false;
803 mCurrentState.requested.w = w;
804 mCurrentState.requested.h = h;
805 setTransactionFlags(eTransactionNeeded);
806 return true;
807}
808bool Layer::setAlpha(uint8_t alpha) {
809 if (mCurrentState.alpha == alpha)
810 return false;
811 mCurrentState.sequence++;
812 mCurrentState.alpha = alpha;
813 setTransactionFlags(eTransactionNeeded);
814 return true;
815}
816bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
817 mCurrentState.sequence++;
818 mCurrentState.transform.set(
819 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
820 setTransactionFlags(eTransactionNeeded);
821 return true;
822}
823bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700824 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800825 setTransactionFlags(eTransactionNeeded);
826 return true;
827}
828bool Layer::setFlags(uint8_t flags, uint8_t mask) {
829 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
830 if (mCurrentState.flags == newFlags)
831 return false;
832 mCurrentState.sequence++;
833 mCurrentState.flags = newFlags;
834 setTransactionFlags(eTransactionNeeded);
835 return true;
836}
837bool Layer::setCrop(const Rect& crop) {
838 if (mCurrentState.requested.crop == crop)
839 return false;
840 mCurrentState.sequence++;
841 mCurrentState.requested.crop = crop;
842 setTransactionFlags(eTransactionNeeded);
843 return true;
844}
845
846bool Layer::setLayerStack(uint32_t layerStack) {
847 if (mCurrentState.layerStack == layerStack)
848 return false;
849 mCurrentState.sequence++;
850 mCurrentState.layerStack = layerStack;
851 setTransactionFlags(eTransactionNeeded);
852 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700853}
854
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800855// ----------------------------------------------------------------------------
856// pageflip handling...
857// ----------------------------------------------------------------------------
858
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800859bool Layer::onPreComposition() {
860 mRefreshPending = false;
861 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800862}
863
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700864void Layer::onPostComposition() {
865 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800866 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800867 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
868
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800869 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800870 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800871 mFrameTracker.setFrameReadyFence(frameReadyFence);
872 } else {
873 // There was no fence for this frame, so assume that it was ready
874 // to be presented at the desired present time.
875 mFrameTracker.setFrameReadyTime(desiredPresentTime);
876 }
877
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700878 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800879 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800880 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800881 mFrameTracker.setActualPresentFence(presentFence);
882 } else {
883 // The HWC doesn't support present fences, so use the refresh
884 // timestamp instead.
885 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
886 mFrameTracker.setActualPresentTime(presentTime);
887 }
888
889 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700890 mFrameLatencyNeeded = false;
891 }
892}
893
Mathias Agopianda27af92012-09-13 18:17:13 -0700894bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800895 const Layer::State& s(mDrawingState);
896 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
897 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700898}
899
Mathias Agopian4fec8732012-06-29 14:12:52 -0700900Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800901{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800902 ATRACE_CALL();
903
Mathias Agopian4fec8732012-06-29 14:12:52 -0700904 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700905 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800906
907 // if we've already called updateTexImage() without going through
908 // a composition step, we have to skip this layer at this point
909 // because we cannot call updateTeximage() without a corresponding
910 // compositionComplete() call.
911 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800912 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700913 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800914 }
915
Jamie Gennis351a5132011-09-14 18:23:37 -0700916 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700917 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700918 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700919
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800920 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700921 Layer::State& front;
922 Layer::State& current;
923 bool& recomputeVisibleRegions;
924 Reject(Layer::State& front, Layer::State& current,
925 bool& recomputeVisibleRegions)
926 : front(front), current(current),
927 recomputeVisibleRegions(recomputeVisibleRegions) {
928 }
929
930 virtual bool reject(const sp<GraphicBuffer>& buf,
931 const BufferQueue::BufferItem& item) {
932 if (buf == NULL) {
933 return false;
934 }
935
936 uint32_t bufWidth = buf->getWidth();
937 uint32_t bufHeight = buf->getHeight();
938
939 // check that we received a buffer of the right size
940 // (Take the buffer's orientation into account)
941 if (item.mTransform & Transform::ROT_90) {
942 swap(bufWidth, bufHeight);
943 }
944
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700945 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
946 if (front.active != front.requested) {
947
948 if (isFixedSize ||
949 (bufWidth == front.requested.w &&
950 bufHeight == front.requested.h))
951 {
952 // Here we pretend the transaction happened by updating the
953 // current and drawing states. Drawing state is only accessed
954 // in this thread, no need to have it locked
955 front.active = front.requested;
956
957 // We also need to update the current state so that
958 // we don't end-up overwriting the drawing state with
959 // this stale current state during the next transaction
960 //
961 // NOTE: We don't need to hold the transaction lock here
962 // because State::active is only accessed from this thread.
963 current.active = front.active;
964
965 // recompute visible region
966 recomputeVisibleRegions = true;
967 }
968
969 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700970 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700971 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
972 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700973 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700974 front.active.w, front.active.h,
975 front.active.crop.left,
976 front.active.crop.top,
977 front.active.crop.right,
978 front.active.crop.bottom,
979 front.active.crop.getWidth(),
980 front.active.crop.getHeight(),
981 front.requested.w, front.requested.h,
982 front.requested.crop.left,
983 front.requested.crop.top,
984 front.requested.crop.right,
985 front.requested.crop.bottom,
986 front.requested.crop.getWidth(),
987 front.requested.crop.getHeight());
988 }
989
990 if (!isFixedSize) {
991 if (front.active.w != bufWidth ||
992 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -0700993 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700994 return true;
995 }
996 }
Mathias Agopian2ca79392013-04-02 18:30:32 -0700997
998 // if the transparent region has changed (this test is
999 // conservative, but that's fine, worst case we're doing
1000 // a bit of extra work), we latch the new one and we
1001 // trigger a visible-region recompute.
1002 if (!front.activeTransparentRegion.isTriviallyEqual(
1003 front.requestedTransparentRegion)) {
1004 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001005
1006 // We also need to update the current state so that
1007 // we don't end-up overwriting the drawing state with
1008 // this stale current state during the next transaction
1009 //
1010 // NOTE: We don't need to hold the transaction lock here
1011 // because State::active is only accessed from this thread.
1012 current.activeTransparentRegion = front.activeTransparentRegion;
1013
1014 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001015 recomputeVisibleRegions = true;
1016 }
1017
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001018 return false;
1019 }
1020 };
1021
1022
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001023 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001024
Andy McFadden1585c4d2013-06-28 13:52:40 -07001025 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1026 if (updateResult == BufferQueue::PRESENT_LATER) {
1027 // Producer doesn't want buffer to be displayed yet. Signal a
1028 // layer update so we check again at the next opportunity.
1029 mFlinger->signalLayerUpdate();
1030 return outDirtyRegion;
1031 }
1032
1033 // Decrement the queued-frames count. Signal another event if we
1034 // have more frames pending.
1035 if (android_atomic_dec(&mQueuedFrames) > 1) {
1036 mFlinger->signalLayerUpdate();
1037 }
1038
1039 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001040 // something happened!
1041 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001042 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001043 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001044
Jamie Gennis351a5132011-09-14 18:23:37 -07001045 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001046 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001047 if (mActiveBuffer == NULL) {
1048 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001049 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001050 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001051
Mathias Agopian4824d402012-06-04 18:16:30 -07001052 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001053 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001054 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001055 // the first time we receive a buffer, we need to trigger a
1056 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001057 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001058 }
1059
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001060 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1061 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1062 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001063 if ((crop != mCurrentCrop) ||
1064 (transform != mCurrentTransform) ||
1065 (scalingMode != mCurrentScalingMode))
1066 {
1067 mCurrentCrop = crop;
1068 mCurrentTransform = transform;
1069 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001070 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001071 }
1072
1073 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001074 uint32_t bufWidth = mActiveBuffer->getWidth();
1075 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001076 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1077 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001078 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001079 }
1080 }
1081
1082 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1083 if (oldOpacity != isOpaque()) {
1084 recomputeVisibleRegions = true;
1085 }
1086
Mathias Agopian4fec8732012-06-29 14:12:52 -07001087 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001088 const Layer::State& s(getDrawingState());
1089 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001090
1091 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001092 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001093 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001094 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001095}
1096
Mathias Agopiana67932f2011-04-20 14:20:59 -07001097uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001098{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001099 // TODO: should we do something special if mSecure is set?
1100 if (mProtectedByApp) {
1101 // need a hardware-protected path to external video sink
1102 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001103 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001104 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001105 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001106}
1107
Mathias Agopian84300952012-11-21 16:02:13 -08001108void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001109 uint32_t orientation = 0;
1110 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001111 // The transform hint is used to improve performance, but we can
1112 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001113 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001114 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001115 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001116 if (orientation & Transform::ROT_INVALID) {
1117 orientation = 0;
1118 }
1119 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001120 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001121}
1122
Mathias Agopian13127d82013-03-05 17:47:11 -08001123// ----------------------------------------------------------------------------
1124// debugging
1125// ----------------------------------------------------------------------------
1126
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001127void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001128{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001129 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001130
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001131 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001132 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001133 "+ %s %p (%s)\n",
1134 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001135 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001136
Mathias Agopian2ca79392013-04-02 18:30:32 -07001137 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001138 visibleRegion.dump(result, "visibleRegion");
1139 sp<Client> client(mClientRef.promote());
1140
Mathias Agopian74d211a2013-04-22 16:55:35 +02001141 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001142 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1143 "isOpaque=%1d, invalidate=%1d, "
1144 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1145 " client=%p\n",
1146 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1147 s.active.crop.left, s.active.crop.top,
1148 s.active.crop.right, s.active.crop.bottom,
1149 isOpaque(), contentDirty,
1150 s.alpha, s.flags,
1151 s.transform[0][0], s.transform[0][1],
1152 s.transform[1][0], s.transform[1][1],
1153 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001154
1155 sp<const GraphicBuffer> buf0(mActiveBuffer);
1156 uint32_t w0=0, h0=0, s0=0, f0=0;
1157 if (buf0 != 0) {
1158 w0 = buf0->getWidth();
1159 h0 = buf0->getHeight();
1160 s0 = buf0->getStride();
1161 f0 = buf0->format;
1162 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001163 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001164 " "
1165 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1166 " queued-frames=%d, mRefreshPending=%d\n",
1167 mFormat, w0, h0, s0,f0,
1168 mQueuedFrames, mRefreshPending);
1169
Mathias Agopian13127d82013-03-05 17:47:11 -08001170 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001171 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001172 }
1173}
1174
Mathias Agopian74d211a2013-04-22 16:55:35 +02001175void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001176 mFrameTracker.dump(result);
1177}
1178
1179void Layer::clearStats() {
1180 mFrameTracker.clear();
1181}
1182
1183// ---------------------------------------------------------------------------
1184
1185Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1186 const sp<Layer>& layer)
1187 : mFlinger(flinger), mLayer(layer) {
1188}
1189
1190Layer::LayerCleaner::~LayerCleaner() {
1191 // destroy client resources
1192 mFlinger->onLayerDestroyed(mLayer);
1193}
1194
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001195// ---------------------------------------------------------------------------
1196
1197
1198}; // namespace android