blob: 2bbb223fcd22eab8fdafd657eb1ca8ce0e5e058d [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),
Riley Andrews03414a12014-07-01 14:22:59 -070082 mClientRef(client),
83 mPotentialCursor(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080084{
Mathias Agopiana67932f2011-04-20 14:20:59 -070085 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070086 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070087 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070088
89 uint32_t layerFlags = 0;
90 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080091 layerFlags |= layer_state_t::eLayerHidden;
92 if (flags & ISurfaceComposerClient::eOpaque)
93 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070094
95 if (flags & ISurfaceComposerClient::eNonPremultiplied)
96 mPremultipliedAlpha = false;
97
98 mName = name;
99
100 mCurrentState.active.w = w;
101 mCurrentState.active.h = h;
102 mCurrentState.active.crop.makeInvalid();
103 mCurrentState.z = 0;
104 mCurrentState.alpha = 0xFF;
105 mCurrentState.layerStack = 0;
106 mCurrentState.flags = layerFlags;
107 mCurrentState.sequence = 0;
108 mCurrentState.transform.set(0, 0);
109 mCurrentState.requested = mCurrentState.active;
110
111 // drawing state & current state are identical
112 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700113
114 nsecs_t displayPeriod =
115 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
116 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800117}
118
Mathias Agopian3f844832013-08-07 21:24:32 -0700119void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800120 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700121 sp<IGraphicBufferProducer> producer;
122 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700123 BufferQueue::createBufferQueue(&producer, &consumer);
124 mProducer = new MonitoredProducer(producer, mFlinger);
125 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800126 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800127 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700128 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800129
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700130#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
131#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800132 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700133#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800134 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800135#endif
Andy McFadden69052052012-09-14 16:10:11 -0700136
Mathias Agopian84300952012-11-21 16:02:13 -0800137 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
138 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700139}
140
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700141Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800142 sp<Client> c(mClientRef.promote());
143 if (c != 0) {
144 c->detachLayer(this);
145 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700146 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700147 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700148}
149
Mathias Agopian13127d82013-03-05 17:47:11 -0800150// ---------------------------------------------------------------------------
151// callbacks
152// ---------------------------------------------------------------------------
153
Dan Stozac7014012014-02-14 15:03:43 -0800154void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800155 HWComposer::HWCLayerInterface* layer) {
156 if (layer) {
157 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700158 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800159 }
160}
161
Igor Murashkina4a31492012-10-29 13:36:11 -0700162void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700163 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800164 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700165}
166
Jesse Hall399184a2014-03-03 15:42:54 -0800167void Layer::onSidebandStreamChanged() {
168 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
169 // mSidebandStreamChanged was false
170 mFlinger->signalLayerUpdate();
171 }
172}
173
Mathias Agopian67106042013-03-14 19:18:13 -0700174// called with SurfaceFlinger::mStateLock from the drawing thread after
175// the layer has been remove from the current state list (and just before
176// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800177void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800178 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700179}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700180
Mathias Agopian13127d82013-03-05 17:47:11 -0800181// ---------------------------------------------------------------------------
182// set-up
183// ---------------------------------------------------------------------------
184
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700185const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800186 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800187}
188
Mathias Agopianf9d93272009-06-19 17:00:27 -0700189status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800190 PixelFormat format, uint32_t flags)
191{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700192 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700193 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700194
195 // never allow a surface larger than what our underlying GL implementation
196 // can handle.
197 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800198 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700199 return BAD_VALUE;
200 }
201
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700202 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700203
Riley Andrews03414a12014-07-01 14:22:59 -0700204 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700205 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
206 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700207 mCurrentOpacity = getOpacityForFormat(format);
208
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800209 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
210 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
211 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700212
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800213 return NO_ERROR;
214}
215
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700216sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800217 Mutex::Autolock _l(mLock);
218
219 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700220 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800221
222 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700223
224 /*
225 * The layer handle is just a BBinder object passed to the client
226 * (remote process) -- we don't keep any reference on our side such that
227 * the dtor is called when the remote side let go of its reference.
228 *
229 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
230 * this layer when the handle is destroyed.
231 */
232
233 class Handle : public BBinder, public LayerCleaner {
234 wp<const Layer> mOwner;
235 public:
236 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
237 : LayerCleaner(flinger, layer), mOwner(layer) {
238 }
239 };
240
241 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800242}
243
Dan Stozab9b08832014-03-13 11:55:57 -0700244sp<IGraphicBufferProducer> Layer::getProducer() const {
245 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700246}
247
Mathias Agopian13127d82013-03-05 17:47:11 -0800248// ---------------------------------------------------------------------------
249// h/w composer set-up
250// ---------------------------------------------------------------------------
251
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800252Rect Layer::getContentCrop() const {
253 // this is the crop rectangle that applies to the buffer
254 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700255 Rect crop;
256 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800257 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700258 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800259 } else if (mActiveBuffer != NULL) {
260 // otherwise we use the whole buffer
261 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700262 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800263 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700264 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700265 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700266 return crop;
267}
268
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700269static Rect reduce(const Rect& win, const Region& exclude) {
270 if (CC_LIKELY(exclude.isEmpty())) {
271 return win;
272 }
273 if (exclude.isRect()) {
274 return win.reduce(exclude.getBounds());
275 }
276 return Region(win).subtract(exclude).getBounds();
277}
278
Mathias Agopian13127d82013-03-05 17:47:11 -0800279Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700280 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800281 Rect win(s.active.w, s.active.h);
282 if (!s.active.crop.isEmpty()) {
283 win.intersect(s.active.crop, &win);
284 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700285 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700286 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800287}
288
Mathias Agopian6b442672013-07-09 21:24:52 -0700289FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800290 // the content crop is the area of the content that gets scaled to the
291 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700292 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800293
294 // the active.crop is the area of the window that gets cropped, but not
295 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700296 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800297
298 // apply the projection's clipping to the window crop in
299 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700300 // if there are no window scaling involved, this operation will map to full
301 // pixels in the buffer.
302 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
303 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700304
305 Rect activeCrop(s.active.w, s.active.h);
306 if (!s.active.crop.isEmpty()) {
307 activeCrop = s.active.crop;
308 }
309
310 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800311 activeCrop.intersect(hw->getViewport(), &activeCrop);
312 activeCrop = s.transform.inverse().transform(activeCrop);
313
314 // paranoia: make sure the window-crop is constrained in the
315 // window's bounds
316 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
317
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700318 // subtract the transparent region and snap to the bounds
319 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
320
Mathias Agopian13127d82013-03-05 17:47:11 -0800321 if (!activeCrop.isEmpty()) {
322 // Transform the window crop to match the buffer coordinate system,
323 // which means using the inverse of the current transform set on the
324 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700325 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700326 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
327 /*
328 * the code below applies the display's inverse transform to the buffer
329 */
330 uint32_t invTransformOrient = hw->getOrientationTransform();
331 // calculate the inverse transform
332 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
333 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
334 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700335 // If the transform has been rotated the axis of flip has been swapped
336 // so we need to swap which flip operations we are performing
337 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
338 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
339 if (is_h_flipped != is_v_flipped) {
340 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
341 NATIVE_WINDOW_TRANSFORM_FLIP_H;
342 }
Michael Lentinef7551402014-08-18 16:35:43 -0700343 }
344 // and apply to the current transform
345 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
346 }
347
Mathias Agopian13127d82013-03-05 17:47:11 -0800348 int winWidth = s.active.w;
349 int winHeight = s.active.h;
350 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
351 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
352 NATIVE_WINDOW_TRANSFORM_FLIP_H;
353 winWidth = s.active.h;
354 winHeight = s.active.w;
355 }
356 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700357 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800358
Mathias Agopian6b442672013-07-09 21:24:52 -0700359 // below, crop is intersected with winCrop expressed in crop's coordinate space
360 float xScale = crop.getWidth() / float(winWidth);
361 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800362
Michael Lentinef7551402014-08-18 16:35:43 -0700363 float insetL = winCrop.left * xScale;
364 float insetT = winCrop.top * yScale;
365 float insetR = (winWidth - winCrop.right ) * xScale;
366 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800367
368 crop.left += insetL;
369 crop.top += insetT;
370 crop.right -= insetR;
371 crop.bottom -= insetB;
372 }
373 return crop;
374}
375
Mathias Agopian4fec8732012-06-29 14:12:52 -0700376void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700377 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700378 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700379{
Mathias Agopian13127d82013-03-05 17:47:11 -0800380 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700381
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700382 // enable this layer
383 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700384
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700385 if (isSecure() && !hw->isSecure()) {
386 layer.setSkip(true);
387 }
388
Mathias Agopian13127d82013-03-05 17:47:11 -0800389 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700390 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800391 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800392 layer.setBlending(mPremultipliedAlpha ?
393 HWC_BLENDING_PREMULT :
394 HWC_BLENDING_COVERAGE);
395 }
396
397 // apply the layer's transform, followed by the display's global transform
398 // here we're guaranteed that the layer's transform preserves rects
399 Rect frame(s.transform.transform(computeBounds()));
400 frame.intersect(hw->getViewport(), &frame);
401 const Transform& tr(hw->getTransform());
402 layer.setFrame(tr.transform(frame));
403 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800404 layer.setPlaneAlpha(s.alpha);
405
Mathias Agopian29a367b2011-07-12 14:51:45 -0700406 /*
407 * Transformations are applied in this order:
408 * 1) buffer orientation/flip/mirror
409 * 2) state transformation (window manager)
410 * 3) layer orientation (screen orientation)
411 * (NOTE: the matrices are multiplied in reverse order)
412 */
413
414 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700415 Transform transform(tr * s.transform * bufferOrientation);
416
417 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
418 /*
419 * the code below applies the display's inverse transform to the buffer
420 */
421 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700422 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700423 // calculate the inverse transform
424 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
425 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
426 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700427 // If the transform has been rotated the axis of flip has been swapped
428 // so we need to swap which flip operations we are performing
429 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
430 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
431 if (is_h_flipped != is_v_flipped) {
432 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
433 NATIVE_WINDOW_TRANSFORM_FLIP_H;
434 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700435 }
436 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700437 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700438 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700439
440 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800441 const uint32_t orientation = transform.getOrientation();
442 if (orientation & Transform::ROT_INVALID) {
443 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700444 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700445 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800446 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700447 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700448}
449
Mathias Agopian42977342012-08-05 00:40:46 -0700450void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700451 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800452 // we have to set the visible region on every frame because
453 // we currently free it during onLayerDisplayed(), which is called
454 // after HWComposer::commit() -- every frame.
455 // Apply this display's projection's viewport to the visible region
456 // before giving it to the HWC HAL.
457 const Transform& tr = hw->getTransform();
458 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
459 layer.setVisibleRegionScreen(visible);
460
Jesse Hall399184a2014-03-03 15:42:54 -0800461 if (mSidebandStream.get()) {
462 layer.setSidebandStream(mSidebandStream);
463 } else {
464 // NOTE: buffer can be NULL if the client never drew into this
465 // layer yet, or if we ran out of memory
466 layer.setBuffer(mActiveBuffer);
467 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700468}
Jesse Halldc5b4852012-06-29 15:21:18 -0700469
Dan Stozac7014012014-02-14 15:03:43 -0800470void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700471 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700472 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700473
474 // TODO: there is a possible optimization here: we only need to set the
475 // acquire fence the first time a new buffer is acquired on EACH display.
476
Riley Andrews03414a12014-07-01 14:22:59 -0700477 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800478 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800479 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700480 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700481 if (fenceFd == -1) {
482 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
483 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700484 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700485 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700486 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700487}
488
Riley Andrews03414a12014-07-01 14:22:59 -0700489Rect Layer::getPosition(
490 const sp<const DisplayDevice>& hw)
491{
492 // this gives us only the "orientation" component of the transform
493 const State& s(getCurrentState());
494
495 // apply the layer's transform, followed by the display's global transform
496 // here we're guaranteed that the layer's transform preserves rects
497 Rect win(s.active.w, s.active.h);
498 if (!s.active.crop.isEmpty()) {
499 win.intersect(s.active.crop, &win);
500 }
501 // subtract the transparent region and snap to the bounds
502 Rect bounds = reduce(win, s.activeTransparentRegion);
503 Rect frame(s.transform.transform(bounds));
504 frame.intersect(hw->getViewport(), &frame);
505 const Transform& tr(hw->getTransform());
506 return Rect(tr.transform(frame));
507}
508
Mathias Agopian13127d82013-03-05 17:47:11 -0800509// ---------------------------------------------------------------------------
510// drawing...
511// ---------------------------------------------------------------------------
512
513void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800514 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800515}
516
Dan Stozac7014012014-02-14 15:03:43 -0800517void Layer::draw(const sp<const DisplayDevice>& hw,
518 bool useIdentityTransform) const {
519 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800520}
521
Dan Stozac7014012014-02-14 15:03:43 -0800522void Layer::draw(const sp<const DisplayDevice>& hw) const {
523 onDraw(hw, Region(hw->bounds()), false);
524}
525
526void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
527 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800528{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800529 ATRACE_CALL();
530
Mathias Agopiana67932f2011-04-20 14:20:59 -0700531 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800532 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700533 // in fact never been drawn into. This happens frequently with
534 // SurfaceView because the WindowManager can't know when the client
535 // has drawn the first time.
536
537 // If there is nothing under us, we paint the screen in black, otherwise
538 // we just skip this update.
539
540 // figure out if there is something below us
541 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700542 const SurfaceFlinger::LayerVector& drawingLayers(
543 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700544 const size_t count = drawingLayers.size();
545 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800546 const sp<Layer>& layer(drawingLayers[i]);
547 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700548 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700549 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700550 }
551 // if not everything below us is covered, we plug the holes!
552 Region holes(clip.subtract(under));
553 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700554 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700555 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800556 return;
557 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700558
Andy McFadden97eba892012-12-11 15:21:45 -0800559 // Bind the current buffer to the GL texture, and wait for it to be
560 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800561 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
562 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800563 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700564 // Go ahead and draw the buffer anyway; no matter what we do the screen
565 // is probably going to have something visibly wrong.
566 }
567
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700568 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
569
Mathias Agopian875d8e12013-06-07 15:35:48 -0700570 RenderEngine& engine(mFlinger->getRenderEngine());
571
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700572 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700573 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700574 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700575
576 // Query the texture matrix given our current filtering mode.
577 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800578 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
579 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700580
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700581 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
582
583 /*
584 * the code below applies the display's inverse transform to the texture transform
585 */
586
587 // create a 4x4 transform matrix from the display transform flags
588 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
589 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
590 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
591
592 mat4 tr;
593 uint32_t transform = hw->getOrientationTransform();
594 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
595 tr = tr * rot90;
596 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
597 tr = tr * flipH;
598 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
599 tr = tr * flipV;
600
601 // calculate the inverse
602 tr = inverse(tr);
603
604 // and finally apply it to the original texture matrix
605 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
606 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
607 }
608
Jamie Genniscbb1a952012-05-08 17:05:52 -0700609 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700610 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
611 mTexture.setFiltering(useFiltering);
612 mTexture.setMatrix(textureMatrix);
613
614 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700615 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700616 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700617 }
Dan Stozac7014012014-02-14 15:03:43 -0800618 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700619 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800620}
621
Mathias Agopian13127d82013-03-05 17:47:11 -0800622
Dan Stozac7014012014-02-14 15:03:43 -0800623void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
624 const Region& /* clip */, float red, float green, float blue,
625 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800626{
Mathias Agopian19733a32013-08-28 18:13:56 -0700627 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800628 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700629 engine.setupFillWithColor(red, green, blue, alpha);
630 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800631}
632
633void Layer::clearWithOpenGL(
634 const sp<const DisplayDevice>& hw, const Region& clip) const {
635 clearWithOpenGL(hw, clip, 0,0,0,0);
636}
637
Dan Stozac7014012014-02-14 15:03:43 -0800638void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
639 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800640 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700641 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800642
Dan Stozac7014012014-02-14 15:03:43 -0800643 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800644
Mathias Agopian13127d82013-03-05 17:47:11 -0800645 /*
646 * NOTE: the way we compute the texture coordinates here produces
647 * different results than when we take the HWC path -- in the later case
648 * the "source crop" is rounded to texel boundaries.
649 * This can produce significantly different results when the texture
650 * is scaled by a large amount.
651 *
652 * The GL code below is more logical (imho), and the difference with
653 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700654 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800655 * GL composition when a buffer scaling is applied (maybe with some
656 * minimal value)? Or, we could make GL behave like HWC -- but this feel
657 * like more of a hack.
658 */
659 const Rect win(computeBounds());
660
Mathias Agopian3f844832013-08-07 21:24:32 -0700661 float left = float(win.left) / float(s.active.w);
662 float top = float(win.top) / float(s.active.h);
663 float right = float(win.right) / float(s.active.w);
664 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800665
Mathias Agopian875d8e12013-06-07 15:35:48 -0700666 // TODO: we probably want to generate the texture coords with the mesh
667 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700668 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
669 texCoords[0] = vec2(left, 1.0f - top);
670 texCoords[1] = vec2(left, 1.0f - bottom);
671 texCoords[2] = vec2(right, 1.0f - bottom);
672 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800673
Mathias Agopian875d8e12013-06-07 15:35:48 -0700674 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800675 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700676 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700677 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800678}
679
Ruben Brunk1681d952014-06-27 15:51:55 -0700680uint32_t Layer::getProducerStickyTransform() const {
681 int producerStickyTransform = 0;
682 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
683 if (ret != OK) {
684 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
685 strerror(-ret), ret);
686 return 0;
687 }
688 return static_cast<uint32_t>(producerStickyTransform);
689}
690
Mathias Agopian13127d82013-03-05 17:47:11 -0800691void Layer::setFiltering(bool filtering) {
692 mFiltering = filtering;
693}
694
695bool Layer::getFiltering() const {
696 return mFiltering;
697}
698
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800699// As documented in libhardware header, formats in the range
700// 0x100 - 0x1FF are specific to the HAL implementation, and
701// are known to have no alpha channel
702// TODO: move definition for device-specific range into
703// hardware.h, instead of using hard-coded values here.
704#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
705
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700706bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700707 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
708 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800709 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700710 switch (format) {
711 case HAL_PIXEL_FORMAT_RGBA_8888:
712 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700713 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700714 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700715 }
716 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700717 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800718}
719
Mathias Agopian13127d82013-03-05 17:47:11 -0800720// ----------------------------------------------------------------------------
721// local state
722// ----------------------------------------------------------------------------
723
Dan Stozac7014012014-02-14 15:03:43 -0800724void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
725 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800726{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700727 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800728 const Transform tr(useIdentityTransform ?
729 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800730 const uint32_t hw_h = hw->getHeight();
731 Rect win(s.active.w, s.active.h);
732 if (!s.active.crop.isEmpty()) {
733 win.intersect(s.active.crop, &win);
734 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700735 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700736 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700737
Mathias Agopianff2ed702013-09-01 21:36:12 -0700738 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
739 position[0] = tr.transform(win.left, win.top);
740 position[1] = tr.transform(win.left, win.bottom);
741 position[2] = tr.transform(win.right, win.bottom);
742 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700743 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700744 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800745 }
746}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800747
Andy McFadden4125a4f2014-01-29 17:17:11 -0800748bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700749{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700750 // if we don't have a buffer yet, we're translucent regardless of the
751 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700752 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700753 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700754 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700755
756 // if the layer has the opaque flag, then we're always opaque,
757 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800758 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700759}
760
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800761bool Layer::isProtected() const
762{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700763 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800764 return (activeBuffer != 0) &&
765 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
766}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700767
Mathias Agopian13127d82013-03-05 17:47:11 -0800768bool Layer::isFixedSize() const {
769 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
770}
771
772bool Layer::isCropped() const {
773 return !mCurrentCrop.isEmpty();
774}
775
776bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
777 return mNeedsFiltering || hw->needsFiltering();
778}
779
780void Layer::setVisibleRegion(const Region& visibleRegion) {
781 // always called from main thread
782 this->visibleRegion = visibleRegion;
783}
784
785void Layer::setCoveredRegion(const Region& coveredRegion) {
786 // always called from main thread
787 this->coveredRegion = coveredRegion;
788}
789
790void Layer::setVisibleNonTransparentRegion(const Region&
791 setVisibleNonTransparentRegion) {
792 // always called from main thread
793 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
794}
795
796// ----------------------------------------------------------------------------
797// transaction
798// ----------------------------------------------------------------------------
799
800uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800801 ATRACE_CALL();
802
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700803 const Layer::State& s(getDrawingState());
804 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800805
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700806 const bool sizeChanged = (c.requested.w != s.requested.w) ||
807 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700808
809 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700810 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000811 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700812 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700813 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
814 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
815 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
816 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700817 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
818 c.active.w, c.active.h,
819 c.active.crop.left,
820 c.active.crop.top,
821 c.active.crop.right,
822 c.active.crop.bottom,
823 c.active.crop.getWidth(),
824 c.active.crop.getHeight(),
825 c.requested.w, c.requested.h,
826 c.requested.crop.left,
827 c.requested.crop.top,
828 c.requested.crop.right,
829 c.requested.crop.bottom,
830 c.requested.crop.getWidth(),
831 c.requested.crop.getHeight(),
832 s.active.w, s.active.h,
833 s.active.crop.left,
834 s.active.crop.top,
835 s.active.crop.right,
836 s.active.crop.bottom,
837 s.active.crop.getWidth(),
838 s.active.crop.getHeight(),
839 s.requested.w, s.requested.h,
840 s.requested.crop.left,
841 s.requested.crop.top,
842 s.requested.crop.right,
843 s.requested.crop.bottom,
844 s.requested.crop.getWidth(),
845 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800846
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700847 // record the new size, form this point on, when the client request
848 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800849 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700850 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800851 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700852
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700853 if (!isFixedSize()) {
854
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700855 const bool resizePending = (c.requested.w != c.active.w) ||
856 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700857
858 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800859 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700860 // if we have a pending resize, unless we are in fixed-size mode.
861 // the drawing state will be updated only once we receive a buffer
862 // with the correct size.
863 //
864 // in particular, we want to make sure the clip (which is part
865 // of the geometry state) is latched together with the size but is
866 // latched immediately when no resizing is involved.
867
868 flags |= eDontUpdateGeometryState;
869 }
870 }
871
Mathias Agopian13127d82013-03-05 17:47:11 -0800872 // always set active to requested, unless we're asked not to
873 // this is used by Layer, which special cases resizes.
874 if (flags & eDontUpdateGeometryState) {
875 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700876 Layer::State& editCurrentState(getCurrentState());
877 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800878 }
879
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700880 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800881 // invalidate and recompute the visible regions if needed
882 flags |= Layer::eVisibleRegion;
883 }
884
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700885 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800886 // invalidate and recompute the visible regions if needed
887 flags |= eVisibleRegion;
888 this->contentDirty = true;
889
890 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700891 const uint8_t type = c.transform.getType();
892 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800893 (type >= Transform::SCALE));
894 }
895
896 // Commit the transaction
897 commitTransaction();
898 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800899}
900
Mathias Agopian13127d82013-03-05 17:47:11 -0800901void Layer::commitTransaction() {
902 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700903}
904
Mathias Agopian13127d82013-03-05 17:47:11 -0800905uint32_t Layer::getTransactionFlags(uint32_t flags) {
906 return android_atomic_and(~flags, &mTransactionFlags) & flags;
907}
908
909uint32_t Layer::setTransactionFlags(uint32_t flags) {
910 return android_atomic_or(flags, &mTransactionFlags);
911}
912
913bool Layer::setPosition(float x, float y) {
914 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
915 return false;
916 mCurrentState.sequence++;
917 mCurrentState.transform.set(x, y);
918 setTransactionFlags(eTransactionNeeded);
919 return true;
920}
921bool Layer::setLayer(uint32_t z) {
922 if (mCurrentState.z == z)
923 return false;
924 mCurrentState.sequence++;
925 mCurrentState.z = z;
926 setTransactionFlags(eTransactionNeeded);
927 return true;
928}
929bool Layer::setSize(uint32_t w, uint32_t h) {
930 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
931 return false;
932 mCurrentState.requested.w = w;
933 mCurrentState.requested.h = h;
934 setTransactionFlags(eTransactionNeeded);
935 return true;
936}
937bool Layer::setAlpha(uint8_t alpha) {
938 if (mCurrentState.alpha == alpha)
939 return false;
940 mCurrentState.sequence++;
941 mCurrentState.alpha = alpha;
942 setTransactionFlags(eTransactionNeeded);
943 return true;
944}
945bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
946 mCurrentState.sequence++;
947 mCurrentState.transform.set(
948 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
949 setTransactionFlags(eTransactionNeeded);
950 return true;
951}
952bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700953 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800954 setTransactionFlags(eTransactionNeeded);
955 return true;
956}
957bool Layer::setFlags(uint8_t flags, uint8_t mask) {
958 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
959 if (mCurrentState.flags == newFlags)
960 return false;
961 mCurrentState.sequence++;
962 mCurrentState.flags = newFlags;
963 setTransactionFlags(eTransactionNeeded);
964 return true;
965}
966bool Layer::setCrop(const Rect& crop) {
967 if (mCurrentState.requested.crop == crop)
968 return false;
969 mCurrentState.sequence++;
970 mCurrentState.requested.crop = crop;
971 setTransactionFlags(eTransactionNeeded);
972 return true;
973}
974
975bool Layer::setLayerStack(uint32_t layerStack) {
976 if (mCurrentState.layerStack == layerStack)
977 return false;
978 mCurrentState.sequence++;
979 mCurrentState.layerStack = layerStack;
980 setTransactionFlags(eTransactionNeeded);
981 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700982}
983
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800984// ----------------------------------------------------------------------------
985// pageflip handling...
986// ----------------------------------------------------------------------------
987
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800988bool Layer::onPreComposition() {
989 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800990 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800991}
992
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700993void Layer::onPostComposition() {
994 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800995 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800996 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
997
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800998 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800999 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001000 mFrameTracker.setFrameReadyFence(frameReadyFence);
1001 } else {
1002 // There was no fence for this frame, so assume that it was ready
1003 // to be presented at the desired present time.
1004 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1005 }
1006
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001007 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001008 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001009 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001010 mFrameTracker.setActualPresentFence(presentFence);
1011 } else {
1012 // The HWC doesn't support present fences, so use the refresh
1013 // timestamp instead.
1014 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1015 mFrameTracker.setActualPresentTime(presentTime);
1016 }
1017
1018 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001019 mFrameLatencyNeeded = false;
1020 }
1021}
1022
Mathias Agopianda27af92012-09-13 18:17:13 -07001023bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001024 const Layer::State& s(mDrawingState);
1025 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001026 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001027}
1028
Mathias Agopian4fec8732012-06-29 14:12:52 -07001029Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001030{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001031 ATRACE_CALL();
1032
Jesse Hall399184a2014-03-03 15:42:54 -08001033 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1034 // mSidebandStreamChanged was true
1035 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
1036 }
1037
Mathias Agopian4fec8732012-06-29 14:12:52 -07001038 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001039 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001040
1041 // if we've already called updateTexImage() without going through
1042 // a composition step, we have to skip this layer at this point
1043 // because we cannot call updateTeximage() without a corresponding
1044 // compositionComplete() call.
1045 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001046 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001047 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001048 }
1049
Jamie Gennis351a5132011-09-14 18:23:37 -07001050 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001051 const State& s(getDrawingState());
1052 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001053 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001054
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001055 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001056 Layer::State& front;
1057 Layer::State& current;
1058 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001059 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001060 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001061 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001062 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001063 recomputeVisibleRegions(recomputeVisibleRegions),
1064 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001065 }
1066
1067 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001068 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001069 if (buf == NULL) {
1070 return false;
1071 }
1072
1073 uint32_t bufWidth = buf->getWidth();
1074 uint32_t bufHeight = buf->getHeight();
1075
1076 // check that we received a buffer of the right size
1077 // (Take the buffer's orientation into account)
1078 if (item.mTransform & Transform::ROT_90) {
1079 swap(bufWidth, bufHeight);
1080 }
1081
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001082 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1083 if (front.active != front.requested) {
1084
1085 if (isFixedSize ||
1086 (bufWidth == front.requested.w &&
1087 bufHeight == front.requested.h))
1088 {
1089 // Here we pretend the transaction happened by updating the
1090 // current and drawing states. Drawing state is only accessed
1091 // in this thread, no need to have it locked
1092 front.active = front.requested;
1093
1094 // We also need to update the current state so that
1095 // we don't end-up overwriting the drawing state with
1096 // this stale current state during the next transaction
1097 //
1098 // NOTE: We don't need to hold the transaction lock here
1099 // because State::active is only accessed from this thread.
1100 current.active = front.active;
1101
1102 // recompute visible region
1103 recomputeVisibleRegions = true;
1104 }
1105
1106 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001107 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001108 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1109 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001110 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001111 front.active.w, front.active.h,
1112 front.active.crop.left,
1113 front.active.crop.top,
1114 front.active.crop.right,
1115 front.active.crop.bottom,
1116 front.active.crop.getWidth(),
1117 front.active.crop.getHeight(),
1118 front.requested.w, front.requested.h,
1119 front.requested.crop.left,
1120 front.requested.crop.top,
1121 front.requested.crop.right,
1122 front.requested.crop.bottom,
1123 front.requested.crop.getWidth(),
1124 front.requested.crop.getHeight());
1125 }
1126
Ruben Brunk1681d952014-06-27 15:51:55 -07001127 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001128 if (front.active.w != bufWidth ||
1129 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001130 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001131 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1132 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001133 return true;
1134 }
1135 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001136
1137 // if the transparent region has changed (this test is
1138 // conservative, but that's fine, worst case we're doing
1139 // a bit of extra work), we latch the new one and we
1140 // trigger a visible-region recompute.
1141 if (!front.activeTransparentRegion.isTriviallyEqual(
1142 front.requestedTransparentRegion)) {
1143 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001144
1145 // We also need to update the current state so that
1146 // we don't end-up overwriting the drawing state with
1147 // this stale current state during the next transaction
1148 //
1149 // NOTE: We don't need to hold the transaction lock here
1150 // because State::active is only accessed from this thread.
1151 current.activeTransparentRegion = front.activeTransparentRegion;
1152
1153 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001154 recomputeVisibleRegions = true;
1155 }
1156
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001157 return false;
1158 }
1159 };
1160
Ruben Brunk1681d952014-06-27 15:51:55 -07001161 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1162 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001163
Andy McFadden41d67d72014-04-25 16:58:34 -07001164 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1165 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001166 if (updateResult == BufferQueue::PRESENT_LATER) {
1167 // Producer doesn't want buffer to be displayed yet. Signal a
1168 // layer update so we check again at the next opportunity.
1169 mFlinger->signalLayerUpdate();
1170 return outDirtyRegion;
1171 }
1172
1173 // Decrement the queued-frames count. Signal another event if we
1174 // have more frames pending.
1175 if (android_atomic_dec(&mQueuedFrames) > 1) {
1176 mFlinger->signalLayerUpdate();
1177 }
1178
1179 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001180 // something happened!
1181 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001182 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001183 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001184
Jamie Gennis351a5132011-09-14 18:23:37 -07001185 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001186 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001187 if (mActiveBuffer == NULL) {
1188 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001189 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001190 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001191
Mathias Agopian4824d402012-06-04 18:16:30 -07001192 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001193 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001194 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001195 // the first time we receive a buffer, we need to trigger a
1196 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001197 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001198 }
1199
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001200 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1201 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1202 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001203 if ((crop != mCurrentCrop) ||
1204 (transform != mCurrentTransform) ||
1205 (scalingMode != mCurrentScalingMode))
1206 {
1207 mCurrentCrop = crop;
1208 mCurrentTransform = transform;
1209 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001210 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001211 }
1212
1213 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001214 uint32_t bufWidth = mActiveBuffer->getWidth();
1215 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001216 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1217 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001218 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001219 }
1220 }
1221
1222 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001223 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001224 recomputeVisibleRegions = true;
1225 }
1226
Mathias Agopian4fec8732012-06-29 14:12:52 -07001227 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001228 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001229
1230 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001231 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001232 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001233 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001234}
1235
Mathias Agopiana67932f2011-04-20 14:20:59 -07001236uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001237{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001238 // TODO: should we do something special if mSecure is set?
1239 if (mProtectedByApp) {
1240 // need a hardware-protected path to external video sink
1241 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001242 }
Riley Andrews03414a12014-07-01 14:22:59 -07001243 if (mPotentialCursor) {
1244 usage |= GraphicBuffer::USAGE_CURSOR;
1245 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001246 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001247 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001248}
1249
Mathias Agopian84300952012-11-21 16:02:13 -08001250void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001251 uint32_t orientation = 0;
1252 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001253 // The transform hint is used to improve performance, but we can
1254 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001255 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001256 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001257 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001258 if (orientation & Transform::ROT_INVALID) {
1259 orientation = 0;
1260 }
1261 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001262 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001263}
1264
Mathias Agopian13127d82013-03-05 17:47:11 -08001265// ----------------------------------------------------------------------------
1266// debugging
1267// ----------------------------------------------------------------------------
1268
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001269void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001270{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001271 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001272
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001273 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001274 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001275 "+ %s %p (%s)\n",
1276 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001277 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001278
Mathias Agopian2ca79392013-04-02 18:30:32 -07001279 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001280 visibleRegion.dump(result, "visibleRegion");
1281 sp<Client> client(mClientRef.promote());
1282
Mathias Agopian74d211a2013-04-22 16:55:35 +02001283 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001284 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1285 "isOpaque=%1d, invalidate=%1d, "
1286 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1287 " client=%p\n",
1288 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1289 s.active.crop.left, s.active.crop.top,
1290 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001291 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001292 s.alpha, s.flags,
1293 s.transform[0][0], s.transform[0][1],
1294 s.transform[1][0], s.transform[1][1],
1295 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001296
1297 sp<const GraphicBuffer> buf0(mActiveBuffer);
1298 uint32_t w0=0, h0=0, s0=0, f0=0;
1299 if (buf0 != 0) {
1300 w0 = buf0->getWidth();
1301 h0 = buf0->getHeight();
1302 s0 = buf0->getStride();
1303 f0 = buf0->format;
1304 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001305 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001306 " "
1307 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1308 " queued-frames=%d, mRefreshPending=%d\n",
1309 mFormat, w0, h0, s0,f0,
1310 mQueuedFrames, mRefreshPending);
1311
Mathias Agopian13127d82013-03-05 17:47:11 -08001312 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001313 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001314 }
1315}
1316
Svetoslavd85084b2014-03-20 10:28:31 -07001317void Layer::dumpFrameStats(String8& result) const {
1318 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001319}
1320
Svetoslavd85084b2014-03-20 10:28:31 -07001321void Layer::clearFrameStats() {
1322 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001323}
1324
Jamie Gennis6547ff42013-07-16 20:12:42 -07001325void Layer::logFrameStats() {
1326 mFrameTracker.logAndResetStats(mName);
1327}
1328
Svetoslavd85084b2014-03-20 10:28:31 -07001329void Layer::getFrameStats(FrameStats* outStats) const {
1330 mFrameTracker.getStats(outStats);
1331}
1332
Mathias Agopian13127d82013-03-05 17:47:11 -08001333// ---------------------------------------------------------------------------
1334
1335Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1336 const sp<Layer>& layer)
1337 : mFlinger(flinger), mLayer(layer) {
1338}
1339
1340Layer::LayerCleaner::~LayerCleaner() {
1341 // destroy client resources
1342 mFlinger->onLayerDestroyed(mLayer);
1343}
1344
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001345// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001346}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001347
1348#if defined(__gl_h_)
1349#error "don't include gl/gl.h in this file"
1350#endif
1351
1352#if defined(__gl2_h_)
1353#error "don't include gl2/gl2.h in this file"
1354#endif