blob: 4861e34026530e5e90ab9eac0abd1e60bf70bf9e [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>
Jesse Hall399184a2014-03-03 15:42:54 -080030#include <utils/NativeHandle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080031#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080032#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080033
Mathias Agopian3330b202009-10-05 17:07:12 -070034#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080035#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080036
Mathias Agopian90ac7992012-02-25 18:48:35 -080037#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038
39#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020040#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070041#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070043#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080044#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045
Mathias Agopian1b031492012-06-20 17:51:20 -070046#include "DisplayHardware/HWComposer.h"
47
Mathias Agopian875d8e12013-06-07 15:35:48 -070048#include "RenderEngine/RenderEngine.h"
49
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050#define DEBUG_RESIZE 0
51
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080052namespace android {
53
54// ---------------------------------------------------------------------------
55
Mathias Agopian13127d82013-03-05 17:47:11 -080056int32_t Layer::sSequence = 1;
57
Mathias Agopian4d9b8222013-03-12 17:11:48 -070058Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
59 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080060 : contentDirty(false),
61 sequence(uint32_t(android_atomic_inc(&sSequence))),
62 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070063 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080064 mPremultipliedAlpha(true),
65 mName("unnamed"),
66 mDebug(false),
67 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080068 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070069 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080070 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070072 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070073 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080074 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080075 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080076 mFiltering(false),
77 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070078 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070079 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080080 mProtectedByApp(false),
81 mHasSurface(false),
82 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080083{
Mathias Agopiana67932f2011-04-20 14:20:59 -070084 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070085 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070086 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070087
88 uint32_t layerFlags = 0;
89 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080090 layerFlags |= layer_state_t::eLayerHidden;
91 if (flags & ISurfaceComposerClient::eOpaque)
92 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070093
94 if (flags & ISurfaceComposerClient::eNonPremultiplied)
95 mPremultipliedAlpha = false;
96
97 mName = name;
98
99 mCurrentState.active.w = w;
100 mCurrentState.active.h = h;
101 mCurrentState.active.crop.makeInvalid();
102 mCurrentState.z = 0;
103 mCurrentState.alpha = 0xFF;
104 mCurrentState.layerStack = 0;
105 mCurrentState.flags = layerFlags;
106 mCurrentState.sequence = 0;
107 mCurrentState.transform.set(0, 0);
108 mCurrentState.requested = mCurrentState.active;
109
110 // drawing state & current state are identical
111 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700112
113 nsecs_t displayPeriod =
114 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
115 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800116}
117
Mathias Agopian3f844832013-08-07 21:24:32 -0700118void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800119 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700120 sp<IGraphicBufferProducer> producer;
121 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700122 BufferQueue::createBufferQueue(&producer, &consumer);
123 mProducer = new MonitoredProducer(producer, mFlinger);
124 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800125 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800126 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700127 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800128
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700129#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
130#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800131 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700132#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800133 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800134#endif
Andy McFadden69052052012-09-14 16:10:11 -0700135
Mathias Agopian84300952012-11-21 16:02:13 -0800136 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
137 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700138}
139
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700140Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800141 sp<Client> c(mClientRef.promote());
142 if (c != 0) {
143 c->detachLayer(this);
144 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700145 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700146 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700147}
148
Mathias Agopian13127d82013-03-05 17:47:11 -0800149// ---------------------------------------------------------------------------
150// callbacks
151// ---------------------------------------------------------------------------
152
Dan Stozac7014012014-02-14 15:03:43 -0800153void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800154 HWComposer::HWCLayerInterface* layer) {
155 if (layer) {
156 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700157 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800158 }
159}
160
Igor Murashkina4a31492012-10-29 13:36:11 -0700161void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700162 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800163 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700164}
165
Jesse Hall399184a2014-03-03 15:42:54 -0800166void Layer::onSidebandStreamChanged() {
167 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
168 // mSidebandStreamChanged was false
169 mFlinger->signalLayerUpdate();
170 }
171}
172
Mathias Agopian67106042013-03-14 19:18:13 -0700173// called with SurfaceFlinger::mStateLock from the drawing thread after
174// the layer has been remove from the current state list (and just before
175// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800176void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800177 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700178}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700179
Mathias Agopian13127d82013-03-05 17:47:11 -0800180// ---------------------------------------------------------------------------
181// set-up
182// ---------------------------------------------------------------------------
183
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700184const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800185 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800186}
187
Mathias Agopianf9d93272009-06-19 17:00:27 -0700188status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800189 PixelFormat format, uint32_t flags)
190{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700191 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700192 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700193
194 // never allow a surface larger than what our underlying GL implementation
195 // can handle.
196 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800197 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700198 return BAD_VALUE;
199 }
200
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700201 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700202
Mathias Agopian3165cc22012-08-08 19:42:09 -0700203 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
204 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700205 mCurrentOpacity = getOpacityForFormat(format);
206
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800207 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
208 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
209 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700210
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800211 return NO_ERROR;
212}
213
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700214sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800215 Mutex::Autolock _l(mLock);
216
217 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700218 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800219
220 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700221
222 /*
223 * The layer handle is just a BBinder object passed to the client
224 * (remote process) -- we don't keep any reference on our side such that
225 * the dtor is called when the remote side let go of its reference.
226 *
227 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
228 * this layer when the handle is destroyed.
229 */
230
231 class Handle : public BBinder, public LayerCleaner {
232 wp<const Layer> mOwner;
233 public:
234 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
235 : LayerCleaner(flinger, layer), mOwner(layer) {
236 }
237 };
238
239 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800240}
241
Dan Stozab9b08832014-03-13 11:55:57 -0700242sp<IGraphicBufferProducer> Layer::getProducer() const {
243 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700244}
245
Mathias Agopian13127d82013-03-05 17:47:11 -0800246// ---------------------------------------------------------------------------
247// h/w composer set-up
248// ---------------------------------------------------------------------------
249
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800250Rect Layer::getContentCrop() const {
251 // this is the crop rectangle that applies to the buffer
252 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700253 Rect crop;
254 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800255 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700256 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800257 } else if (mActiveBuffer != NULL) {
258 // otherwise we use the whole buffer
259 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700260 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800261 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700262 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700263 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700264 return crop;
265}
266
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700267static Rect reduce(const Rect& win, const Region& exclude) {
268 if (CC_LIKELY(exclude.isEmpty())) {
269 return win;
270 }
271 if (exclude.isRect()) {
272 return win.reduce(exclude.getBounds());
273 }
274 return Region(win).subtract(exclude).getBounds();
275}
276
Mathias Agopian13127d82013-03-05 17:47:11 -0800277Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700278 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800279 Rect win(s.active.w, s.active.h);
280 if (!s.active.crop.isEmpty()) {
281 win.intersect(s.active.crop, &win);
282 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700283 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700284 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800285}
286
Mathias Agopian6b442672013-07-09 21:24:52 -0700287FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800288 // the content crop is the area of the content that gets scaled to the
289 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700290 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800291
292 // the active.crop is the area of the window that gets cropped, but not
293 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700294 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800295
296 // apply the projection's clipping to the window crop in
297 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700298 // if there are no window scaling involved, this operation will map to full
299 // pixels in the buffer.
300 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
301 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700302
303 Rect activeCrop(s.active.w, s.active.h);
304 if (!s.active.crop.isEmpty()) {
305 activeCrop = s.active.crop;
306 }
307
308 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800309 activeCrop.intersect(hw->getViewport(), &activeCrop);
310 activeCrop = s.transform.inverse().transform(activeCrop);
311
312 // paranoia: make sure the window-crop is constrained in the
313 // window's bounds
314 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
315
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700316 // subtract the transparent region and snap to the bounds
317 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
318
Mathias Agopian13127d82013-03-05 17:47:11 -0800319 if (!activeCrop.isEmpty()) {
320 // Transform the window crop to match the buffer coordinate system,
321 // which means using the inverse of the current transform set on the
322 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700323 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800324 int winWidth = s.active.w;
325 int winHeight = s.active.h;
326 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
327 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
328 NATIVE_WINDOW_TRANSFORM_FLIP_H;
329 winWidth = s.active.h;
330 winHeight = s.active.w;
331 }
332 const Rect winCrop = activeCrop.transform(
333 invTransform, s.active.w, s.active.h);
334
Mathias Agopian6b442672013-07-09 21:24:52 -0700335 // below, crop is intersected with winCrop expressed in crop's coordinate space
336 float xScale = crop.getWidth() / float(winWidth);
337 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800338
Mathias Agopian6b442672013-07-09 21:24:52 -0700339 float insetL = winCrop.left * xScale;
340 float insetT = winCrop.top * yScale;
341 float insetR = (winWidth - winCrop.right ) * xScale;
342 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800343
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());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800367 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800368 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 Agopianc1c05de2013-09-17 23:45:22 -0700391 Transform transform(tr * s.transform * bufferOrientation);
392
393 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
394 /*
395 * the code below applies the display's inverse transform to the buffer
396 */
397 uint32_t invTransform = hw->getOrientationTransform();
398 // calculate the inverse transform
399 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
400 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
401 NATIVE_WINDOW_TRANSFORM_FLIP_H;
402 }
403 // and apply to the current transform
404 transform = transform * Transform(invTransform);
405 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700406
407 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800408 const uint32_t orientation = transform.getOrientation();
409 if (orientation & Transform::ROT_INVALID) {
410 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700411 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700412 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800413 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700414 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700415}
416
Mathias Agopian42977342012-08-05 00:40:46 -0700417void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700418 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800419 // we have to set the visible region on every frame because
420 // we currently free it during onLayerDisplayed(), which is called
421 // after HWComposer::commit() -- every frame.
422 // Apply this display's projection's viewport to the visible region
423 // before giving it to the HWC HAL.
424 const Transform& tr = hw->getTransform();
425 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
426 layer.setVisibleRegionScreen(visible);
427
Jesse Hall399184a2014-03-03 15:42:54 -0800428 if (mSidebandStream.get()) {
429 layer.setSidebandStream(mSidebandStream);
430 } else {
431 // NOTE: buffer can be NULL if the client never drew into this
432 // layer yet, or if we ran out of memory
433 layer.setBuffer(mActiveBuffer);
434 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700435}
Jesse Halldc5b4852012-06-29 15:21:18 -0700436
Dan Stozac7014012014-02-14 15:03:43 -0800437void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700438 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700439 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700440
441 // TODO: there is a possible optimization here: we only need to set the
442 // acquire fence the first time a new buffer is acquired on EACH display.
443
444 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800445 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800446 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700447 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700448 if (fenceFd == -1) {
449 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
450 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700451 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700452 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700453 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700454}
455
Mathias Agopian13127d82013-03-05 17:47:11 -0800456// ---------------------------------------------------------------------------
457// drawing...
458// ---------------------------------------------------------------------------
459
460void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800461 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800462}
463
Dan Stozac7014012014-02-14 15:03:43 -0800464void Layer::draw(const sp<const DisplayDevice>& hw,
465 bool useIdentityTransform) const {
466 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800467}
468
Dan Stozac7014012014-02-14 15:03:43 -0800469void Layer::draw(const sp<const DisplayDevice>& hw) const {
470 onDraw(hw, Region(hw->bounds()), false);
471}
472
473void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
474 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800475{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800476 ATRACE_CALL();
477
Mathias Agopiana67932f2011-04-20 14:20:59 -0700478 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800479 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700480 // in fact never been drawn into. This happens frequently with
481 // SurfaceView because the WindowManager can't know when the client
482 // has drawn the first time.
483
484 // If there is nothing under us, we paint the screen in black, otherwise
485 // we just skip this update.
486
487 // figure out if there is something below us
488 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700489 const SurfaceFlinger::LayerVector& drawingLayers(
490 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700491 const size_t count = drawingLayers.size();
492 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800493 const sp<Layer>& layer(drawingLayers[i]);
494 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700495 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700496 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700497 }
498 // if not everything below us is covered, we plug the holes!
499 Region holes(clip.subtract(under));
500 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700501 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700502 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800503 return;
504 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700505
Andy McFadden97eba892012-12-11 15:21:45 -0800506 // Bind the current buffer to the GL texture, and wait for it to be
507 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800508 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
509 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800510 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700511 // Go ahead and draw the buffer anyway; no matter what we do the screen
512 // is probably going to have something visibly wrong.
513 }
514
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700515 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
516
Mathias Agopian875d8e12013-06-07 15:35:48 -0700517 RenderEngine& engine(mFlinger->getRenderEngine());
518
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700519 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700520 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700521 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700522
523 // Query the texture matrix given our current filtering mode.
524 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800525 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
526 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700527
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700528 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
529
530 /*
531 * the code below applies the display's inverse transform to the texture transform
532 */
533
534 // create a 4x4 transform matrix from the display transform flags
535 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
536 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
537 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
538
539 mat4 tr;
540 uint32_t transform = hw->getOrientationTransform();
541 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
542 tr = tr * rot90;
543 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
544 tr = tr * flipH;
545 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
546 tr = tr * flipV;
547
548 // calculate the inverse
549 tr = inverse(tr);
550
551 // and finally apply it to the original texture matrix
552 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
553 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
554 }
555
Jamie Genniscbb1a952012-05-08 17:05:52 -0700556 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700557 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
558 mTexture.setFiltering(useFiltering);
559 mTexture.setMatrix(textureMatrix);
560
561 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700562 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700563 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700564 }
Dan Stozac7014012014-02-14 15:03:43 -0800565 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700566 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800567}
568
Mathias Agopian13127d82013-03-05 17:47:11 -0800569
Dan Stozac7014012014-02-14 15:03:43 -0800570void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
571 const Region& /* clip */, float red, float green, float blue,
572 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800573{
Mathias Agopian19733a32013-08-28 18:13:56 -0700574 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800575 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700576 engine.setupFillWithColor(red, green, blue, alpha);
577 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800578}
579
580void Layer::clearWithOpenGL(
581 const sp<const DisplayDevice>& hw, const Region& clip) const {
582 clearWithOpenGL(hw, clip, 0,0,0,0);
583}
584
Dan Stozac7014012014-02-14 15:03:43 -0800585void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
586 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800587 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700588 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800589
Dan Stozac7014012014-02-14 15:03:43 -0800590 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800591
Mathias Agopian13127d82013-03-05 17:47:11 -0800592 /*
593 * NOTE: the way we compute the texture coordinates here produces
594 * different results than when we take the HWC path -- in the later case
595 * the "source crop" is rounded to texel boundaries.
596 * This can produce significantly different results when the texture
597 * is scaled by a large amount.
598 *
599 * The GL code below is more logical (imho), and the difference with
600 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700601 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800602 * GL composition when a buffer scaling is applied (maybe with some
603 * minimal value)? Or, we could make GL behave like HWC -- but this feel
604 * like more of a hack.
605 */
606 const Rect win(computeBounds());
607
Mathias Agopian3f844832013-08-07 21:24:32 -0700608 float left = float(win.left) / float(s.active.w);
609 float top = float(win.top) / float(s.active.h);
610 float right = float(win.right) / float(s.active.w);
611 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800612
Mathias Agopian875d8e12013-06-07 15:35:48 -0700613 // TODO: we probably want to generate the texture coords with the mesh
614 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700615 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
616 texCoords[0] = vec2(left, 1.0f - top);
617 texCoords[1] = vec2(left, 1.0f - bottom);
618 texCoords[2] = vec2(right, 1.0f - bottom);
619 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800620
Mathias Agopian875d8e12013-06-07 15:35:48 -0700621 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800622 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700623 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700624 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800625}
626
Ruben Brunk1681d952014-06-27 15:51:55 -0700627uint32_t Layer::getProducerStickyTransform() const {
628 int producerStickyTransform = 0;
629 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
630 if (ret != OK) {
631 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
632 strerror(-ret), ret);
633 return 0;
634 }
635 return static_cast<uint32_t>(producerStickyTransform);
636}
637
Mathias Agopian13127d82013-03-05 17:47:11 -0800638void Layer::setFiltering(bool filtering) {
639 mFiltering = filtering;
640}
641
642bool Layer::getFiltering() const {
643 return mFiltering;
644}
645
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800646// As documented in libhardware header, formats in the range
647// 0x100 - 0x1FF are specific to the HAL implementation, and
648// are known to have no alpha channel
649// TODO: move definition for device-specific range into
650// hardware.h, instead of using hard-coded values here.
651#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
652
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700653bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700654 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
655 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800656 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700657 switch (format) {
658 case HAL_PIXEL_FORMAT_RGBA_8888:
659 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700660 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700661 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700662 }
663 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700664 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800665}
666
Mathias Agopian13127d82013-03-05 17:47:11 -0800667// ----------------------------------------------------------------------------
668// local state
669// ----------------------------------------------------------------------------
670
Dan Stozac7014012014-02-14 15:03:43 -0800671void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
672 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800673{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700674 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800675 const Transform tr(useIdentityTransform ?
676 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800677 const uint32_t hw_h = hw->getHeight();
678 Rect win(s.active.w, s.active.h);
679 if (!s.active.crop.isEmpty()) {
680 win.intersect(s.active.crop, &win);
681 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700682 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700683 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700684
Mathias Agopianff2ed702013-09-01 21:36:12 -0700685 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
686 position[0] = tr.transform(win.left, win.top);
687 position[1] = tr.transform(win.left, win.bottom);
688 position[2] = tr.transform(win.right, win.bottom);
689 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700690 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700691 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800692 }
693}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800694
Andy McFadden4125a4f2014-01-29 17:17:11 -0800695bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700696{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700697 // if we don't have a buffer yet, we're translucent regardless of the
698 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700699 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700700 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700701 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700702
703 // if the layer has the opaque flag, then we're always opaque,
704 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800705 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700706}
707
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800708bool Layer::isProtected() const
709{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700710 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800711 return (activeBuffer != 0) &&
712 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
713}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700714
Mathias Agopian13127d82013-03-05 17:47:11 -0800715bool Layer::isFixedSize() const {
716 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
717}
718
719bool Layer::isCropped() const {
720 return !mCurrentCrop.isEmpty();
721}
722
723bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
724 return mNeedsFiltering || hw->needsFiltering();
725}
726
727void Layer::setVisibleRegion(const Region& visibleRegion) {
728 // always called from main thread
729 this->visibleRegion = visibleRegion;
730}
731
732void Layer::setCoveredRegion(const Region& coveredRegion) {
733 // always called from main thread
734 this->coveredRegion = coveredRegion;
735}
736
737void Layer::setVisibleNonTransparentRegion(const Region&
738 setVisibleNonTransparentRegion) {
739 // always called from main thread
740 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
741}
742
743// ----------------------------------------------------------------------------
744// transaction
745// ----------------------------------------------------------------------------
746
747uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800748 ATRACE_CALL();
749
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700750 const Layer::State& s(getDrawingState());
751 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800752
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700753 const bool sizeChanged = (c.requested.w != s.requested.w) ||
754 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700755
756 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700757 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000758 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700759 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700760 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
761 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
762 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
763 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700764 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
765 c.active.w, c.active.h,
766 c.active.crop.left,
767 c.active.crop.top,
768 c.active.crop.right,
769 c.active.crop.bottom,
770 c.active.crop.getWidth(),
771 c.active.crop.getHeight(),
772 c.requested.w, c.requested.h,
773 c.requested.crop.left,
774 c.requested.crop.top,
775 c.requested.crop.right,
776 c.requested.crop.bottom,
777 c.requested.crop.getWidth(),
778 c.requested.crop.getHeight(),
779 s.active.w, s.active.h,
780 s.active.crop.left,
781 s.active.crop.top,
782 s.active.crop.right,
783 s.active.crop.bottom,
784 s.active.crop.getWidth(),
785 s.active.crop.getHeight(),
786 s.requested.w, s.requested.h,
787 s.requested.crop.left,
788 s.requested.crop.top,
789 s.requested.crop.right,
790 s.requested.crop.bottom,
791 s.requested.crop.getWidth(),
792 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800793
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700794 // record the new size, form this point on, when the client request
795 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800796 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700797 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800798 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700799
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700800 if (!isFixedSize()) {
801
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700802 const bool resizePending = (c.requested.w != c.active.w) ||
803 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700804
805 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800806 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700807 // if we have a pending resize, unless we are in fixed-size mode.
808 // the drawing state will be updated only once we receive a buffer
809 // with the correct size.
810 //
811 // in particular, we want to make sure the clip (which is part
812 // of the geometry state) is latched together with the size but is
813 // latched immediately when no resizing is involved.
814
815 flags |= eDontUpdateGeometryState;
816 }
817 }
818
Mathias Agopian13127d82013-03-05 17:47:11 -0800819 // always set active to requested, unless we're asked not to
820 // this is used by Layer, which special cases resizes.
821 if (flags & eDontUpdateGeometryState) {
822 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700823 Layer::State& editCurrentState(getCurrentState());
824 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800825 }
826
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700827 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800828 // invalidate and recompute the visible regions if needed
829 flags |= Layer::eVisibleRegion;
830 }
831
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700832 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800833 // invalidate and recompute the visible regions if needed
834 flags |= eVisibleRegion;
835 this->contentDirty = true;
836
837 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700838 const uint8_t type = c.transform.getType();
839 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800840 (type >= Transform::SCALE));
841 }
842
843 // Commit the transaction
844 commitTransaction();
845 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800846}
847
Mathias Agopian13127d82013-03-05 17:47:11 -0800848void Layer::commitTransaction() {
849 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700850}
851
Mathias Agopian13127d82013-03-05 17:47:11 -0800852uint32_t Layer::getTransactionFlags(uint32_t flags) {
853 return android_atomic_and(~flags, &mTransactionFlags) & flags;
854}
855
856uint32_t Layer::setTransactionFlags(uint32_t flags) {
857 return android_atomic_or(flags, &mTransactionFlags);
858}
859
860bool Layer::setPosition(float x, float y) {
861 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
862 return false;
863 mCurrentState.sequence++;
864 mCurrentState.transform.set(x, y);
865 setTransactionFlags(eTransactionNeeded);
866 return true;
867}
868bool Layer::setLayer(uint32_t z) {
869 if (mCurrentState.z == z)
870 return false;
871 mCurrentState.sequence++;
872 mCurrentState.z = z;
873 setTransactionFlags(eTransactionNeeded);
874 return true;
875}
876bool Layer::setSize(uint32_t w, uint32_t h) {
877 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
878 return false;
879 mCurrentState.requested.w = w;
880 mCurrentState.requested.h = h;
881 setTransactionFlags(eTransactionNeeded);
882 return true;
883}
884bool Layer::setAlpha(uint8_t alpha) {
885 if (mCurrentState.alpha == alpha)
886 return false;
887 mCurrentState.sequence++;
888 mCurrentState.alpha = alpha;
889 setTransactionFlags(eTransactionNeeded);
890 return true;
891}
892bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
893 mCurrentState.sequence++;
894 mCurrentState.transform.set(
895 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
896 setTransactionFlags(eTransactionNeeded);
897 return true;
898}
899bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700900 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800901 setTransactionFlags(eTransactionNeeded);
902 return true;
903}
904bool Layer::setFlags(uint8_t flags, uint8_t mask) {
905 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
906 if (mCurrentState.flags == newFlags)
907 return false;
908 mCurrentState.sequence++;
909 mCurrentState.flags = newFlags;
910 setTransactionFlags(eTransactionNeeded);
911 return true;
912}
913bool Layer::setCrop(const Rect& crop) {
914 if (mCurrentState.requested.crop == crop)
915 return false;
916 mCurrentState.sequence++;
917 mCurrentState.requested.crop = crop;
918 setTransactionFlags(eTransactionNeeded);
919 return true;
920}
921
922bool Layer::setLayerStack(uint32_t layerStack) {
923 if (mCurrentState.layerStack == layerStack)
924 return false;
925 mCurrentState.sequence++;
926 mCurrentState.layerStack = layerStack;
927 setTransactionFlags(eTransactionNeeded);
928 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700929}
930
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800931// ----------------------------------------------------------------------------
932// pageflip handling...
933// ----------------------------------------------------------------------------
934
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800935bool Layer::onPreComposition() {
936 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800937 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800938}
939
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700940void Layer::onPostComposition() {
941 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800942 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800943 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
944
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800945 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800946 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800947 mFrameTracker.setFrameReadyFence(frameReadyFence);
948 } else {
949 // There was no fence for this frame, so assume that it was ready
950 // to be presented at the desired present time.
951 mFrameTracker.setFrameReadyTime(desiredPresentTime);
952 }
953
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700954 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800955 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800956 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800957 mFrameTracker.setActualPresentFence(presentFence);
958 } else {
959 // The HWC doesn't support present fences, so use the refresh
960 // timestamp instead.
961 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
962 mFrameTracker.setActualPresentTime(presentTime);
963 }
964
965 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700966 mFrameLatencyNeeded = false;
967 }
968}
969
Mathias Agopianda27af92012-09-13 18:17:13 -0700970bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800971 const Layer::State& s(mDrawingState);
972 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +0900973 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700974}
975
Mathias Agopian4fec8732012-06-29 14:12:52 -0700976Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800977{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800978 ATRACE_CALL();
979
Jesse Hall399184a2014-03-03 15:42:54 -0800980 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
981 // mSidebandStreamChanged was true
982 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
983 }
984
Mathias Agopian4fec8732012-06-29 14:12:52 -0700985 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700986 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800987
988 // if we've already called updateTexImage() without going through
989 // a composition step, we have to skip this layer at this point
990 // because we cannot call updateTeximage() without a corresponding
991 // compositionComplete() call.
992 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800993 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700994 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800995 }
996
Jamie Gennis351a5132011-09-14 18:23:37 -0700997 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -0800998 const State& s(getDrawingState());
999 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001000 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001001
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001002 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001003 Layer::State& front;
1004 Layer::State& current;
1005 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001006 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001007 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001008 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001009 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001010 recomputeVisibleRegions(recomputeVisibleRegions),
1011 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001012 }
1013
1014 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001015 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001016 if (buf == NULL) {
1017 return false;
1018 }
1019
1020 uint32_t bufWidth = buf->getWidth();
1021 uint32_t bufHeight = buf->getHeight();
1022
1023 // check that we received a buffer of the right size
1024 // (Take the buffer's orientation into account)
1025 if (item.mTransform & Transform::ROT_90) {
1026 swap(bufWidth, bufHeight);
1027 }
1028
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001029 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1030 if (front.active != front.requested) {
1031
1032 if (isFixedSize ||
1033 (bufWidth == front.requested.w &&
1034 bufHeight == front.requested.h))
1035 {
1036 // Here we pretend the transaction happened by updating the
1037 // current and drawing states. Drawing state is only accessed
1038 // in this thread, no need to have it locked
1039 front.active = front.requested;
1040
1041 // We also need to update the current state so that
1042 // we don't end-up overwriting the drawing state with
1043 // this stale current state during the next transaction
1044 //
1045 // NOTE: We don't need to hold the transaction lock here
1046 // because State::active is only accessed from this thread.
1047 current.active = front.active;
1048
1049 // recompute visible region
1050 recomputeVisibleRegions = true;
1051 }
1052
1053 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001054 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001055 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1056 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001057 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001058 front.active.w, front.active.h,
1059 front.active.crop.left,
1060 front.active.crop.top,
1061 front.active.crop.right,
1062 front.active.crop.bottom,
1063 front.active.crop.getWidth(),
1064 front.active.crop.getHeight(),
1065 front.requested.w, front.requested.h,
1066 front.requested.crop.left,
1067 front.requested.crop.top,
1068 front.requested.crop.right,
1069 front.requested.crop.bottom,
1070 front.requested.crop.getWidth(),
1071 front.requested.crop.getHeight());
1072 }
1073
Ruben Brunk1681d952014-06-27 15:51:55 -07001074 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001075 if (front.active.w != bufWidth ||
1076 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001077 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001078 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1079 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001080 return true;
1081 }
1082 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001083
1084 // if the transparent region has changed (this test is
1085 // conservative, but that's fine, worst case we're doing
1086 // a bit of extra work), we latch the new one and we
1087 // trigger a visible-region recompute.
1088 if (!front.activeTransparentRegion.isTriviallyEqual(
1089 front.requestedTransparentRegion)) {
1090 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001091
1092 // We also need to update the current state so that
1093 // we don't end-up overwriting the drawing state with
1094 // this stale current state during the next transaction
1095 //
1096 // NOTE: We don't need to hold the transaction lock here
1097 // because State::active is only accessed from this thread.
1098 current.activeTransparentRegion = front.activeTransparentRegion;
1099
1100 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001101 recomputeVisibleRegions = true;
1102 }
1103
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001104 return false;
1105 }
1106 };
1107
Ruben Brunk1681d952014-06-27 15:51:55 -07001108 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1109 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001110
Andy McFadden41d67d72014-04-25 16:58:34 -07001111 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1112 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001113 if (updateResult == BufferQueue::PRESENT_LATER) {
1114 // Producer doesn't want buffer to be displayed yet. Signal a
1115 // layer update so we check again at the next opportunity.
1116 mFlinger->signalLayerUpdate();
1117 return outDirtyRegion;
1118 }
1119
1120 // Decrement the queued-frames count. Signal another event if we
1121 // have more frames pending.
1122 if (android_atomic_dec(&mQueuedFrames) > 1) {
1123 mFlinger->signalLayerUpdate();
1124 }
1125
1126 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001127 // something happened!
1128 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001129 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001130 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001131
Jamie Gennis351a5132011-09-14 18:23:37 -07001132 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001133 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001134 if (mActiveBuffer == NULL) {
1135 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001136 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001137 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001138
Mathias Agopian4824d402012-06-04 18:16:30 -07001139 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001140 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001141 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001142 // the first time we receive a buffer, we need to trigger a
1143 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001144 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001145 }
1146
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001147 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1148 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1149 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001150 if ((crop != mCurrentCrop) ||
1151 (transform != mCurrentTransform) ||
1152 (scalingMode != mCurrentScalingMode))
1153 {
1154 mCurrentCrop = crop;
1155 mCurrentTransform = transform;
1156 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001157 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001158 }
1159
1160 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001161 uint32_t bufWidth = mActiveBuffer->getWidth();
1162 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001163 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1164 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001165 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001166 }
1167 }
1168
1169 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001170 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001171 recomputeVisibleRegions = true;
1172 }
1173
Mathias Agopian4fec8732012-06-29 14:12:52 -07001174 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001175 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001176
1177 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001178 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001179 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001180 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001181}
1182
Mathias Agopiana67932f2011-04-20 14:20:59 -07001183uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001184{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001185 // TODO: should we do something special if mSecure is set?
1186 if (mProtectedByApp) {
1187 // need a hardware-protected path to external video sink
1188 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001189 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001190 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001191 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001192}
1193
Mathias Agopian84300952012-11-21 16:02:13 -08001194void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001195 uint32_t orientation = 0;
1196 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001197 // The transform hint is used to improve performance, but we can
1198 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001199 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001200 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001201 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001202 if (orientation & Transform::ROT_INVALID) {
1203 orientation = 0;
1204 }
1205 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001206 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001207}
1208
Mathias Agopian13127d82013-03-05 17:47:11 -08001209// ----------------------------------------------------------------------------
1210// debugging
1211// ----------------------------------------------------------------------------
1212
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001213void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001214{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001215 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001216
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001217 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001218 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001219 "+ %s %p (%s)\n",
1220 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001221 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001222
Mathias Agopian2ca79392013-04-02 18:30:32 -07001223 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001224 visibleRegion.dump(result, "visibleRegion");
1225 sp<Client> client(mClientRef.promote());
1226
Mathias Agopian74d211a2013-04-22 16:55:35 +02001227 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001228 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1229 "isOpaque=%1d, invalidate=%1d, "
1230 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1231 " client=%p\n",
1232 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1233 s.active.crop.left, s.active.crop.top,
1234 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001235 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001236 s.alpha, s.flags,
1237 s.transform[0][0], s.transform[0][1],
1238 s.transform[1][0], s.transform[1][1],
1239 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001240
1241 sp<const GraphicBuffer> buf0(mActiveBuffer);
1242 uint32_t w0=0, h0=0, s0=0, f0=0;
1243 if (buf0 != 0) {
1244 w0 = buf0->getWidth();
1245 h0 = buf0->getHeight();
1246 s0 = buf0->getStride();
1247 f0 = buf0->format;
1248 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001249 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001250 " "
1251 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1252 " queued-frames=%d, mRefreshPending=%d\n",
1253 mFormat, w0, h0, s0,f0,
1254 mQueuedFrames, mRefreshPending);
1255
Mathias Agopian13127d82013-03-05 17:47:11 -08001256 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001257 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001258 }
1259}
1260
Svetoslavd85084b2014-03-20 10:28:31 -07001261void Layer::dumpFrameStats(String8& result) const {
1262 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001263}
1264
Svetoslavd85084b2014-03-20 10:28:31 -07001265void Layer::clearFrameStats() {
1266 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001267}
1268
Jamie Gennis6547ff42013-07-16 20:12:42 -07001269void Layer::logFrameStats() {
1270 mFrameTracker.logAndResetStats(mName);
1271}
1272
Svetoslavd85084b2014-03-20 10:28:31 -07001273void Layer::getFrameStats(FrameStats* outStats) const {
1274 mFrameTracker.getStats(outStats);
1275}
1276
Mathias Agopian13127d82013-03-05 17:47:11 -08001277// ---------------------------------------------------------------------------
1278
1279Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1280 const sp<Layer>& layer)
1281 : mFlinger(flinger), mLayer(layer) {
1282}
1283
1284Layer::LayerCleaner::~LayerCleaner() {
1285 // destroy client resources
1286 mFlinger->onLayerDestroyed(mLayer);
1287}
1288
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001289// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001290}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001291
1292#if defined(__gl_h_)
1293#error "don't include gl/gl.h in this file"
1294#endif
1295
1296#if defined(__gl2_h_)
1297#error "don't include gl2/gl2.h in this file"
1298#endif