blob: 91e9a02f26cf7b6fff29efd223a01b6b6ba9e9e5 [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"),
Mathias Agopian13127d82013-03-05 17:47:11 -080066 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070068 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080069 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070070 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 Agopian5cdc8992013-08-13 20:51:23 -070077 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070078 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080079 mProtectedByApp(false),
80 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070081 mClientRef(client),
82 mPotentialCursor(false)
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
Riley Andrews03414a12014-07-01 14:22:59 -0700203 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700204 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
205 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700206 mCurrentOpacity = getOpacityForFormat(format);
207
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800208 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
209 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
210 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700211
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800212 return NO_ERROR;
213}
214
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700215sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800216 Mutex::Autolock _l(mLock);
217
218 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700219 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800220
221 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700222
223 /*
224 * The layer handle is just a BBinder object passed to the client
225 * (remote process) -- we don't keep any reference on our side such that
226 * the dtor is called when the remote side let go of its reference.
227 *
228 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
229 * this layer when the handle is destroyed.
230 */
231
232 class Handle : public BBinder, public LayerCleaner {
233 wp<const Layer> mOwner;
234 public:
235 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
236 : LayerCleaner(flinger, layer), mOwner(layer) {
237 }
238 };
239
240 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800241}
242
Dan Stozab9b08832014-03-13 11:55:57 -0700243sp<IGraphicBufferProducer> Layer::getProducer() const {
244 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700245}
246
Mathias Agopian13127d82013-03-05 17:47:11 -0800247// ---------------------------------------------------------------------------
248// h/w composer set-up
249// ---------------------------------------------------------------------------
250
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800251Rect Layer::getContentCrop() const {
252 // this is the crop rectangle that applies to the buffer
253 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700254 Rect crop;
255 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800256 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700257 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800258 } else if (mActiveBuffer != NULL) {
259 // otherwise we use the whole buffer
260 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700261 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800262 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700263 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700264 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700265 return crop;
266}
267
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700268static Rect reduce(const Rect& win, const Region& exclude) {
269 if (CC_LIKELY(exclude.isEmpty())) {
270 return win;
271 }
272 if (exclude.isRect()) {
273 return win.reduce(exclude.getBounds());
274 }
275 return Region(win).subtract(exclude).getBounds();
276}
277
Mathias Agopian13127d82013-03-05 17:47:11 -0800278Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700279 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800280 Rect win(s.active.w, s.active.h);
281 if (!s.active.crop.isEmpty()) {
282 win.intersect(s.active.crop, &win);
283 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700284 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700285 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800286}
287
Mathias Agopian6b442672013-07-09 21:24:52 -0700288FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800289 // the content crop is the area of the content that gets scaled to the
290 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700291 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800292
293 // the active.crop is the area of the window that gets cropped, but not
294 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700295 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800296
297 // apply the projection's clipping to the window crop in
298 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700299 // if there are no window scaling involved, this operation will map to full
300 // pixels in the buffer.
301 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
302 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700303
304 Rect activeCrop(s.active.w, s.active.h);
305 if (!s.active.crop.isEmpty()) {
306 activeCrop = s.active.crop;
307 }
308
309 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800310 activeCrop.intersect(hw->getViewport(), &activeCrop);
311 activeCrop = s.transform.inverse().transform(activeCrop);
312
313 // paranoia: make sure the window-crop is constrained in the
314 // window's bounds
315 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
316
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700317 // subtract the transparent region and snap to the bounds
318 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
319
Mathias Agopian13127d82013-03-05 17:47:11 -0800320 if (!activeCrop.isEmpty()) {
321 // Transform the window crop to match the buffer coordinate system,
322 // which means using the inverse of the current transform set on the
323 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700324 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700325 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
326 /*
327 * the code below applies the display's inverse transform to the buffer
328 */
329 uint32_t invTransformOrient = hw->getOrientationTransform();
330 // calculate the inverse transform
331 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
332 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
333 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700334 // If the transform has been rotated the axis of flip has been swapped
335 // so we need to swap which flip operations we are performing
336 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
337 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
338 if (is_h_flipped != is_v_flipped) {
339 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
340 NATIVE_WINDOW_TRANSFORM_FLIP_H;
341 }
Michael Lentinef7551402014-08-18 16:35:43 -0700342 }
343 // and apply to the current transform
344 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
345 }
346
Mathias Agopian13127d82013-03-05 17:47:11 -0800347 int winWidth = s.active.w;
348 int winHeight = s.active.h;
349 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700350 // If the activeCrop has been rotate the ends are rotated but not
351 // the space itself so when transforming ends back we can't rely on
352 // a modification of the axes of rotation. To account for this we
353 // need to reorient the inverse rotation in terms of the current
354 // axes of rotation.
355 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
356 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
357 if (is_h_flipped == is_v_flipped) {
358 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
359 NATIVE_WINDOW_TRANSFORM_FLIP_H;
360 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800361 winWidth = s.active.h;
362 winHeight = s.active.w;
363 }
364 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700365 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800366
Mathias Agopian6b442672013-07-09 21:24:52 -0700367 // below, crop is intersected with winCrop expressed in crop's coordinate space
368 float xScale = crop.getWidth() / float(winWidth);
369 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800370
Michael Lentinef7551402014-08-18 16:35:43 -0700371 float insetL = winCrop.left * xScale;
372 float insetT = winCrop.top * yScale;
373 float insetR = (winWidth - winCrop.right ) * xScale;
374 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800375
376 crop.left += insetL;
377 crop.top += insetT;
378 crop.right -= insetR;
379 crop.bottom -= insetB;
380 }
381 return crop;
382}
383
Mathias Agopian4fec8732012-06-29 14:12:52 -0700384void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700385 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700386 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700387{
Mathias Agopian13127d82013-03-05 17:47:11 -0800388 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700389
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700390 // enable this layer
391 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700392
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700393 if (isSecure() && !hw->isSecure()) {
394 layer.setSkip(true);
395 }
396
Mathias Agopian13127d82013-03-05 17:47:11 -0800397 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700398 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800399 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800400 layer.setBlending(mPremultipliedAlpha ?
401 HWC_BLENDING_PREMULT :
402 HWC_BLENDING_COVERAGE);
403 }
404
405 // apply the layer's transform, followed by the display's global transform
406 // here we're guaranteed that the layer's transform preserves rects
407 Rect frame(s.transform.transform(computeBounds()));
408 frame.intersect(hw->getViewport(), &frame);
409 const Transform& tr(hw->getTransform());
410 layer.setFrame(tr.transform(frame));
411 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800412 layer.setPlaneAlpha(s.alpha);
413
Mathias Agopian29a367b2011-07-12 14:51:45 -0700414 /*
415 * Transformations are applied in this order:
416 * 1) buffer orientation/flip/mirror
417 * 2) state transformation (window manager)
418 * 3) layer orientation (screen orientation)
419 * (NOTE: the matrices are multiplied in reverse order)
420 */
421
422 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700423 Transform transform(tr * s.transform * bufferOrientation);
424
425 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
426 /*
427 * the code below applies the display's inverse transform to the buffer
428 */
429 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700430 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700431 // calculate the inverse transform
432 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
433 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
434 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700435 // If the transform has been rotated the axis of flip has been swapped
436 // so we need to swap which flip operations we are performing
437 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
438 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
439 if (is_h_flipped != is_v_flipped) {
440 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
441 NATIVE_WINDOW_TRANSFORM_FLIP_H;
442 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700443 }
444 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700445 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700446 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700447
448 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800449 const uint32_t orientation = transform.getOrientation();
450 if (orientation & Transform::ROT_INVALID) {
451 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700452 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700453 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800454 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700455 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700456}
457
Mathias Agopian42977342012-08-05 00:40:46 -0700458void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700459 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800460 // we have to set the visible region on every frame because
461 // we currently free it during onLayerDisplayed(), which is called
462 // after HWComposer::commit() -- every frame.
463 // Apply this display's projection's viewport to the visible region
464 // before giving it to the HWC HAL.
465 const Transform& tr = hw->getTransform();
466 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
467 layer.setVisibleRegionScreen(visible);
468
Jesse Hall399184a2014-03-03 15:42:54 -0800469 if (mSidebandStream.get()) {
470 layer.setSidebandStream(mSidebandStream);
471 } else {
472 // NOTE: buffer can be NULL if the client never drew into this
473 // layer yet, or if we ran out of memory
474 layer.setBuffer(mActiveBuffer);
475 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700476}
Jesse Halldc5b4852012-06-29 15:21:18 -0700477
Dan Stozac7014012014-02-14 15:03:43 -0800478void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700479 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700480 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700481
482 // TODO: there is a possible optimization here: we only need to set the
483 // acquire fence the first time a new buffer is acquired on EACH display.
484
Riley Andrews03414a12014-07-01 14:22:59 -0700485 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800486 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800487 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700488 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700489 if (fenceFd == -1) {
490 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
491 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700492 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700493 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700494 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700495}
496
Riley Andrews03414a12014-07-01 14:22:59 -0700497Rect Layer::getPosition(
498 const sp<const DisplayDevice>& hw)
499{
500 // this gives us only the "orientation" component of the transform
501 const State& s(getCurrentState());
502
503 // apply the layer's transform, followed by the display's global transform
504 // here we're guaranteed that the layer's transform preserves rects
505 Rect win(s.active.w, s.active.h);
506 if (!s.active.crop.isEmpty()) {
507 win.intersect(s.active.crop, &win);
508 }
509 // subtract the transparent region and snap to the bounds
510 Rect bounds = reduce(win, s.activeTransparentRegion);
511 Rect frame(s.transform.transform(bounds));
512 frame.intersect(hw->getViewport(), &frame);
513 const Transform& tr(hw->getTransform());
514 return Rect(tr.transform(frame));
515}
516
Mathias Agopian13127d82013-03-05 17:47:11 -0800517// ---------------------------------------------------------------------------
518// drawing...
519// ---------------------------------------------------------------------------
520
521void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800522 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800523}
524
Dan Stozac7014012014-02-14 15:03:43 -0800525void Layer::draw(const sp<const DisplayDevice>& hw,
526 bool useIdentityTransform) const {
527 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800528}
529
Dan Stozac7014012014-02-14 15:03:43 -0800530void Layer::draw(const sp<const DisplayDevice>& hw) const {
531 onDraw(hw, Region(hw->bounds()), false);
532}
533
534void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
535 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800536{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800537 ATRACE_CALL();
538
Mathias Agopiana67932f2011-04-20 14:20:59 -0700539 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800540 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700541 // in fact never been drawn into. This happens frequently with
542 // SurfaceView because the WindowManager can't know when the client
543 // has drawn the first time.
544
545 // If there is nothing under us, we paint the screen in black, otherwise
546 // we just skip this update.
547
548 // figure out if there is something below us
549 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700550 const SurfaceFlinger::LayerVector& drawingLayers(
551 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700552 const size_t count = drawingLayers.size();
553 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800554 const sp<Layer>& layer(drawingLayers[i]);
555 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700556 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700557 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700558 }
559 // if not everything below us is covered, we plug the holes!
560 Region holes(clip.subtract(under));
561 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700562 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700563 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800564 return;
565 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700566
Andy McFadden97eba892012-12-11 15:21:45 -0800567 // Bind the current buffer to the GL texture, and wait for it to be
568 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800569 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
570 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800571 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700572 // Go ahead and draw the buffer anyway; no matter what we do the screen
573 // is probably going to have something visibly wrong.
574 }
575
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700576 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
577
Mathias Agopian875d8e12013-06-07 15:35:48 -0700578 RenderEngine& engine(mFlinger->getRenderEngine());
579
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700580 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700581 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700582 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700583
584 // Query the texture matrix given our current filtering mode.
585 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800586 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
587 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700588
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700589 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
590
591 /*
592 * the code below applies the display's inverse transform to the texture transform
593 */
594
595 // create a 4x4 transform matrix from the display transform flags
596 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
597 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
598 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
599
600 mat4 tr;
601 uint32_t transform = hw->getOrientationTransform();
602 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
603 tr = tr * rot90;
604 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
605 tr = tr * flipH;
606 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
607 tr = tr * flipV;
608
609 // calculate the inverse
610 tr = inverse(tr);
611
612 // and finally apply it to the original texture matrix
613 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
614 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
615 }
616
Jamie Genniscbb1a952012-05-08 17:05:52 -0700617 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700618 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
619 mTexture.setFiltering(useFiltering);
620 mTexture.setMatrix(textureMatrix);
621
622 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700623 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700624 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700625 }
Dan Stozac7014012014-02-14 15:03:43 -0800626 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700627 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800628}
629
Mathias Agopian13127d82013-03-05 17:47:11 -0800630
Dan Stozac7014012014-02-14 15:03:43 -0800631void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
632 const Region& /* clip */, float red, float green, float blue,
633 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800634{
Mathias Agopian19733a32013-08-28 18:13:56 -0700635 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800636 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700637 engine.setupFillWithColor(red, green, blue, alpha);
638 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800639}
640
641void Layer::clearWithOpenGL(
642 const sp<const DisplayDevice>& hw, const Region& clip) const {
643 clearWithOpenGL(hw, clip, 0,0,0,0);
644}
645
Dan Stozac7014012014-02-14 15:03:43 -0800646void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
647 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700648 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800649
Dan Stozac7014012014-02-14 15:03:43 -0800650 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800651
Mathias Agopian13127d82013-03-05 17:47:11 -0800652 /*
653 * NOTE: the way we compute the texture coordinates here produces
654 * different results than when we take the HWC path -- in the later case
655 * the "source crop" is rounded to texel boundaries.
656 * This can produce significantly different results when the texture
657 * is scaled by a large amount.
658 *
659 * The GL code below is more logical (imho), and the difference with
660 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700661 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800662 * GL composition when a buffer scaling is applied (maybe with some
663 * minimal value)? Or, we could make GL behave like HWC -- but this feel
664 * like more of a hack.
665 */
666 const Rect win(computeBounds());
667
Mathias Agopian3f844832013-08-07 21:24:32 -0700668 float left = float(win.left) / float(s.active.w);
669 float top = float(win.top) / float(s.active.h);
670 float right = float(win.right) / float(s.active.w);
671 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800672
Mathias Agopian875d8e12013-06-07 15:35:48 -0700673 // TODO: we probably want to generate the texture coords with the mesh
674 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700675 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
676 texCoords[0] = vec2(left, 1.0f - top);
677 texCoords[1] = vec2(left, 1.0f - bottom);
678 texCoords[2] = vec2(right, 1.0f - bottom);
679 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800680
Mathias Agopian875d8e12013-06-07 15:35:48 -0700681 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800682 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700683 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700684 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800685}
686
Ruben Brunk1681d952014-06-27 15:51:55 -0700687uint32_t Layer::getProducerStickyTransform() const {
688 int producerStickyTransform = 0;
689 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
690 if (ret != OK) {
691 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
692 strerror(-ret), ret);
693 return 0;
694 }
695 return static_cast<uint32_t>(producerStickyTransform);
696}
697
Mathias Agopian13127d82013-03-05 17:47:11 -0800698void Layer::setFiltering(bool filtering) {
699 mFiltering = filtering;
700}
701
702bool Layer::getFiltering() const {
703 return mFiltering;
704}
705
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800706// As documented in libhardware header, formats in the range
707// 0x100 - 0x1FF are specific to the HAL implementation, and
708// are known to have no alpha channel
709// TODO: move definition for device-specific range into
710// hardware.h, instead of using hard-coded values here.
711#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
712
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700713bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700714 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
715 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800716 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700717 switch (format) {
718 case HAL_PIXEL_FORMAT_RGBA_8888:
719 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700720 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700721 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700722 }
723 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700724 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800725}
726
Mathias Agopian13127d82013-03-05 17:47:11 -0800727// ----------------------------------------------------------------------------
728// local state
729// ----------------------------------------------------------------------------
730
Dan Stozac7014012014-02-14 15:03:43 -0800731void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
732 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800733{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700734 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800735 const Transform tr(useIdentityTransform ?
736 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800737 const uint32_t hw_h = hw->getHeight();
738 Rect win(s.active.w, s.active.h);
739 if (!s.active.crop.isEmpty()) {
740 win.intersect(s.active.crop, &win);
741 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700742 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700743 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700744
Mathias Agopianff2ed702013-09-01 21:36:12 -0700745 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
746 position[0] = tr.transform(win.left, win.top);
747 position[1] = tr.transform(win.left, win.bottom);
748 position[2] = tr.transform(win.right, win.bottom);
749 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700750 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700751 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800752 }
753}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800754
Andy McFadden4125a4f2014-01-29 17:17:11 -0800755bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700756{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700757 // if we don't have a buffer yet, we're translucent regardless of the
758 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700759 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700760 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700761 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700762
763 // if the layer has the opaque flag, then we're always opaque,
764 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800765 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700766}
767
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800768bool Layer::isProtected() const
769{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700770 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800771 return (activeBuffer != 0) &&
772 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
773}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700774
Mathias Agopian13127d82013-03-05 17:47:11 -0800775bool Layer::isFixedSize() const {
776 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
777}
778
779bool Layer::isCropped() const {
780 return !mCurrentCrop.isEmpty();
781}
782
783bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
784 return mNeedsFiltering || hw->needsFiltering();
785}
786
787void Layer::setVisibleRegion(const Region& visibleRegion) {
788 // always called from main thread
789 this->visibleRegion = visibleRegion;
790}
791
792void Layer::setCoveredRegion(const Region& coveredRegion) {
793 // always called from main thread
794 this->coveredRegion = coveredRegion;
795}
796
797void Layer::setVisibleNonTransparentRegion(const Region&
798 setVisibleNonTransparentRegion) {
799 // always called from main thread
800 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
801}
802
803// ----------------------------------------------------------------------------
804// transaction
805// ----------------------------------------------------------------------------
806
807uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800808 ATRACE_CALL();
809
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700810 const Layer::State& s(getDrawingState());
811 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800812
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700813 const bool sizeChanged = (c.requested.w != s.requested.w) ||
814 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700815
816 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700817 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000818 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700819 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700820 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
821 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
822 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
823 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700824 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
825 c.active.w, c.active.h,
826 c.active.crop.left,
827 c.active.crop.top,
828 c.active.crop.right,
829 c.active.crop.bottom,
830 c.active.crop.getWidth(),
831 c.active.crop.getHeight(),
832 c.requested.w, c.requested.h,
833 c.requested.crop.left,
834 c.requested.crop.top,
835 c.requested.crop.right,
836 c.requested.crop.bottom,
837 c.requested.crop.getWidth(),
838 c.requested.crop.getHeight(),
839 s.active.w, s.active.h,
840 s.active.crop.left,
841 s.active.crop.top,
842 s.active.crop.right,
843 s.active.crop.bottom,
844 s.active.crop.getWidth(),
845 s.active.crop.getHeight(),
846 s.requested.w, s.requested.h,
847 s.requested.crop.left,
848 s.requested.crop.top,
849 s.requested.crop.right,
850 s.requested.crop.bottom,
851 s.requested.crop.getWidth(),
852 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800853
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700854 // record the new size, form this point on, when the client request
855 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800856 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700857 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800858 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700859
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700860 if (!isFixedSize()) {
861
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700862 const bool resizePending = (c.requested.w != c.active.w) ||
863 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700864
865 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800866 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700867 // if we have a pending resize, unless we are in fixed-size mode.
868 // the drawing state will be updated only once we receive a buffer
869 // with the correct size.
870 //
871 // in particular, we want to make sure the clip (which is part
872 // of the geometry state) is latched together with the size but is
873 // latched immediately when no resizing is involved.
874
875 flags |= eDontUpdateGeometryState;
876 }
877 }
878
Mathias Agopian13127d82013-03-05 17:47:11 -0800879 // always set active to requested, unless we're asked not to
880 // this is used by Layer, which special cases resizes.
881 if (flags & eDontUpdateGeometryState) {
882 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700883 Layer::State& editCurrentState(getCurrentState());
884 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800885 }
886
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700887 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800888 // invalidate and recompute the visible regions if needed
889 flags |= Layer::eVisibleRegion;
890 }
891
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700892 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800893 // invalidate and recompute the visible regions if needed
894 flags |= eVisibleRegion;
895 this->contentDirty = true;
896
897 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700898 const uint8_t type = c.transform.getType();
899 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800900 (type >= Transform::SCALE));
901 }
902
903 // Commit the transaction
904 commitTransaction();
905 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800906}
907
Mathias Agopian13127d82013-03-05 17:47:11 -0800908void Layer::commitTransaction() {
909 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700910}
911
Mathias Agopian13127d82013-03-05 17:47:11 -0800912uint32_t Layer::getTransactionFlags(uint32_t flags) {
913 return android_atomic_and(~flags, &mTransactionFlags) & flags;
914}
915
916uint32_t Layer::setTransactionFlags(uint32_t flags) {
917 return android_atomic_or(flags, &mTransactionFlags);
918}
919
920bool Layer::setPosition(float x, float y) {
921 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
922 return false;
923 mCurrentState.sequence++;
924 mCurrentState.transform.set(x, y);
925 setTransactionFlags(eTransactionNeeded);
926 return true;
927}
928bool Layer::setLayer(uint32_t z) {
929 if (mCurrentState.z == z)
930 return false;
931 mCurrentState.sequence++;
932 mCurrentState.z = z;
933 setTransactionFlags(eTransactionNeeded);
934 return true;
935}
936bool Layer::setSize(uint32_t w, uint32_t h) {
937 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
938 return false;
939 mCurrentState.requested.w = w;
940 mCurrentState.requested.h = h;
941 setTransactionFlags(eTransactionNeeded);
942 return true;
943}
944bool Layer::setAlpha(uint8_t alpha) {
945 if (mCurrentState.alpha == alpha)
946 return false;
947 mCurrentState.sequence++;
948 mCurrentState.alpha = alpha;
949 setTransactionFlags(eTransactionNeeded);
950 return true;
951}
952bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
953 mCurrentState.sequence++;
954 mCurrentState.transform.set(
955 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
956 setTransactionFlags(eTransactionNeeded);
957 return true;
958}
959bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700960 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800961 setTransactionFlags(eTransactionNeeded);
962 return true;
963}
964bool Layer::setFlags(uint8_t flags, uint8_t mask) {
965 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
966 if (mCurrentState.flags == newFlags)
967 return false;
968 mCurrentState.sequence++;
969 mCurrentState.flags = newFlags;
970 setTransactionFlags(eTransactionNeeded);
971 return true;
972}
973bool Layer::setCrop(const Rect& crop) {
974 if (mCurrentState.requested.crop == crop)
975 return false;
976 mCurrentState.sequence++;
977 mCurrentState.requested.crop = crop;
978 setTransactionFlags(eTransactionNeeded);
979 return true;
980}
981
982bool Layer::setLayerStack(uint32_t layerStack) {
983 if (mCurrentState.layerStack == layerStack)
984 return false;
985 mCurrentState.sequence++;
986 mCurrentState.layerStack = layerStack;
987 setTransactionFlags(eTransactionNeeded);
988 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700989}
990
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800991// ----------------------------------------------------------------------------
992// pageflip handling...
993// ----------------------------------------------------------------------------
994
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800995bool Layer::onPreComposition() {
996 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800997 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800998}
999
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001000void Layer::onPostComposition() {
1001 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001002 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001003 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1004
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001005 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001006 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001007 mFrameTracker.setFrameReadyFence(frameReadyFence);
1008 } else {
1009 // There was no fence for this frame, so assume that it was ready
1010 // to be presented at the desired present time.
1011 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1012 }
1013
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001014 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001015 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001016 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001017 mFrameTracker.setActualPresentFence(presentFence);
1018 } else {
1019 // The HWC doesn't support present fences, so use the refresh
1020 // timestamp instead.
1021 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1022 mFrameTracker.setActualPresentTime(presentTime);
1023 }
1024
1025 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001026 mFrameLatencyNeeded = false;
1027 }
1028}
1029
Mathias Agopianda27af92012-09-13 18:17:13 -07001030bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001031 const Layer::State& s(mDrawingState);
1032 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001033 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001034}
1035
Mathias Agopian4fec8732012-06-29 14:12:52 -07001036Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001037{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001038 ATRACE_CALL();
1039
Jesse Hall399184a2014-03-03 15:42:54 -08001040 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1041 // mSidebandStreamChanged was true
1042 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001043 recomputeVisibleRegions = true;
1044
1045 const State& s(getDrawingState());
1046 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001047 }
1048
Mathias Agopian4fec8732012-06-29 14:12:52 -07001049 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001050 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001051
1052 // if we've already called updateTexImage() without going through
1053 // a composition step, we have to skip this layer at this point
1054 // because we cannot call updateTeximage() without a corresponding
1055 // compositionComplete() call.
1056 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001057 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001058 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001059 }
1060
Jamie Gennis351a5132011-09-14 18:23:37 -07001061 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001062 const State& s(getDrawingState());
1063 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001064 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001065
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001066 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001067 Layer::State& front;
1068 Layer::State& current;
1069 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001070 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001071 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001072 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001073 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001074 recomputeVisibleRegions(recomputeVisibleRegions),
1075 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001076 }
1077
1078 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001079 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001080 if (buf == NULL) {
1081 return false;
1082 }
1083
1084 uint32_t bufWidth = buf->getWidth();
1085 uint32_t bufHeight = buf->getHeight();
1086
1087 // check that we received a buffer of the right size
1088 // (Take the buffer's orientation into account)
1089 if (item.mTransform & Transform::ROT_90) {
1090 swap(bufWidth, bufHeight);
1091 }
1092
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001093 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1094 if (front.active != front.requested) {
1095
1096 if (isFixedSize ||
1097 (bufWidth == front.requested.w &&
1098 bufHeight == front.requested.h))
1099 {
1100 // Here we pretend the transaction happened by updating the
1101 // current and drawing states. Drawing state is only accessed
1102 // in this thread, no need to have it locked
1103 front.active = front.requested;
1104
1105 // We also need to update the current state so that
1106 // we don't end-up overwriting the drawing state with
1107 // this stale current state during the next transaction
1108 //
1109 // NOTE: We don't need to hold the transaction lock here
1110 // because State::active is only accessed from this thread.
1111 current.active = front.active;
1112
1113 // recompute visible region
1114 recomputeVisibleRegions = true;
1115 }
1116
1117 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001118 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001119 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1120 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001121 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001122 front.active.w, front.active.h,
1123 front.active.crop.left,
1124 front.active.crop.top,
1125 front.active.crop.right,
1126 front.active.crop.bottom,
1127 front.active.crop.getWidth(),
1128 front.active.crop.getHeight(),
1129 front.requested.w, front.requested.h,
1130 front.requested.crop.left,
1131 front.requested.crop.top,
1132 front.requested.crop.right,
1133 front.requested.crop.bottom,
1134 front.requested.crop.getWidth(),
1135 front.requested.crop.getHeight());
1136 }
1137
Ruben Brunk1681d952014-06-27 15:51:55 -07001138 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001139 if (front.active.w != bufWidth ||
1140 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001141 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001142 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1143 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001144 return true;
1145 }
1146 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001147
1148 // if the transparent region has changed (this test is
1149 // conservative, but that's fine, worst case we're doing
1150 // a bit of extra work), we latch the new one and we
1151 // trigger a visible-region recompute.
1152 if (!front.activeTransparentRegion.isTriviallyEqual(
1153 front.requestedTransparentRegion)) {
1154 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001155
1156 // We also need to update the current state so that
1157 // we don't end-up overwriting the drawing state with
1158 // this stale current state during the next transaction
1159 //
1160 // NOTE: We don't need to hold the transaction lock here
1161 // because State::active is only accessed from this thread.
1162 current.activeTransparentRegion = front.activeTransparentRegion;
1163
1164 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001165 recomputeVisibleRegions = true;
1166 }
1167
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001168 return false;
1169 }
1170 };
1171
Ruben Brunk1681d952014-06-27 15:51:55 -07001172 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1173 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001174
Andy McFadden41d67d72014-04-25 16:58:34 -07001175 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1176 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001177 if (updateResult == BufferQueue::PRESENT_LATER) {
1178 // Producer doesn't want buffer to be displayed yet. Signal a
1179 // layer update so we check again at the next opportunity.
1180 mFlinger->signalLayerUpdate();
1181 return outDirtyRegion;
1182 }
1183
1184 // Decrement the queued-frames count. Signal another event if we
1185 // have more frames pending.
1186 if (android_atomic_dec(&mQueuedFrames) > 1) {
1187 mFlinger->signalLayerUpdate();
1188 }
1189
1190 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001191 // something happened!
1192 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001193 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001194 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001195
Jamie Gennis351a5132011-09-14 18:23:37 -07001196 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001197 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001198 if (mActiveBuffer == NULL) {
1199 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001200 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001201 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001202
Mathias Agopian4824d402012-06-04 18:16:30 -07001203 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001204 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001205 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001206 // the first time we receive a buffer, we need to trigger a
1207 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001208 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001209 }
1210
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001211 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1212 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1213 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001214 if ((crop != mCurrentCrop) ||
1215 (transform != mCurrentTransform) ||
1216 (scalingMode != mCurrentScalingMode))
1217 {
1218 mCurrentCrop = crop;
1219 mCurrentTransform = transform;
1220 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001221 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001222 }
1223
1224 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001225 uint32_t bufWidth = mActiveBuffer->getWidth();
1226 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001227 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1228 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001229 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001230 }
1231 }
1232
1233 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001234 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001235 recomputeVisibleRegions = true;
1236 }
1237
Mathias Agopian4fec8732012-06-29 14:12:52 -07001238 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001239 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001240
1241 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001242 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001243 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001244 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001245}
1246
Mathias Agopiana67932f2011-04-20 14:20:59 -07001247uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001248{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001249 // TODO: should we do something special if mSecure is set?
1250 if (mProtectedByApp) {
1251 // need a hardware-protected path to external video sink
1252 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001253 }
Riley Andrews03414a12014-07-01 14:22:59 -07001254 if (mPotentialCursor) {
1255 usage |= GraphicBuffer::USAGE_CURSOR;
1256 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001257 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001258 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001259}
1260
Mathias Agopian84300952012-11-21 16:02:13 -08001261void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001262 uint32_t orientation = 0;
1263 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001264 // The transform hint is used to improve performance, but we can
1265 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001266 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001267 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001268 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001269 if (orientation & Transform::ROT_INVALID) {
1270 orientation = 0;
1271 }
1272 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001273 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001274}
1275
Mathias Agopian13127d82013-03-05 17:47:11 -08001276// ----------------------------------------------------------------------------
1277// debugging
1278// ----------------------------------------------------------------------------
1279
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001280void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001281{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001282 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001283
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001284 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001285 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001286 "+ %s %p (%s)\n",
1287 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001288 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001289
Mathias Agopian2ca79392013-04-02 18:30:32 -07001290 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001291 visibleRegion.dump(result, "visibleRegion");
1292 sp<Client> client(mClientRef.promote());
1293
Mathias Agopian74d211a2013-04-22 16:55:35 +02001294 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001295 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1296 "isOpaque=%1d, invalidate=%1d, "
1297 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1298 " client=%p\n",
1299 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1300 s.active.crop.left, s.active.crop.top,
1301 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001302 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001303 s.alpha, s.flags,
1304 s.transform[0][0], s.transform[0][1],
1305 s.transform[1][0], s.transform[1][1],
1306 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001307
1308 sp<const GraphicBuffer> buf0(mActiveBuffer);
1309 uint32_t w0=0, h0=0, s0=0, f0=0;
1310 if (buf0 != 0) {
1311 w0 = buf0->getWidth();
1312 h0 = buf0->getHeight();
1313 s0 = buf0->getStride();
1314 f0 = buf0->format;
1315 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001316 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001317 " "
1318 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1319 " queued-frames=%d, mRefreshPending=%d\n",
1320 mFormat, w0, h0, s0,f0,
1321 mQueuedFrames, mRefreshPending);
1322
Mathias Agopian13127d82013-03-05 17:47:11 -08001323 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001324 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001325 }
1326}
1327
Svetoslavd85084b2014-03-20 10:28:31 -07001328void Layer::dumpFrameStats(String8& result) const {
1329 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001330}
1331
Svetoslavd85084b2014-03-20 10:28:31 -07001332void Layer::clearFrameStats() {
1333 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001334}
1335
Jamie Gennis6547ff42013-07-16 20:12:42 -07001336void Layer::logFrameStats() {
1337 mFrameTracker.logAndResetStats(mName);
1338}
1339
Svetoslavd85084b2014-03-20 10:28:31 -07001340void Layer::getFrameStats(FrameStats* outStats) const {
1341 mFrameTracker.getStats(outStats);
1342}
1343
Mathias Agopian13127d82013-03-05 17:47:11 -08001344// ---------------------------------------------------------------------------
1345
1346Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1347 const sp<Layer>& layer)
1348 : mFlinger(flinger), mLayer(layer) {
1349}
1350
1351Layer::LayerCleaner::~LayerCleaner() {
1352 // destroy client resources
1353 mFlinger->onLayerDestroyed(mLayer);
1354}
1355
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001356// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001357}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001358
1359#if defined(__gl_h_)
1360#error "don't include gl/gl.h in this file"
1361#endif
1362
1363#if defined(__gl2_h_)
1364#error "don't include gl2/gl2.h in this file"
1365#endif