blob: fa07656e23d6c84e2c0f91c567517435cf0fbf87 [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) {
Michael Lentine7b902582014-08-19 18:14:06 -0700351 // If the activeCrop has been rotate the ends are rotated but not
352 // the space itself so when transforming ends back we can't rely on
353 // a modification of the axes of rotation. To account for this we
354 // need to reorient the inverse rotation in terms of the current
355 // axes of rotation.
356 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
357 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
358 if (is_h_flipped == is_v_flipped) {
359 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
360 NATIVE_WINDOW_TRANSFORM_FLIP_H;
361 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800362 winWidth = s.active.h;
363 winHeight = s.active.w;
364 }
365 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700366 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800367
Mathias Agopian6b442672013-07-09 21:24:52 -0700368 // below, crop is intersected with winCrop expressed in crop's coordinate space
369 float xScale = crop.getWidth() / float(winWidth);
370 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800371
Michael Lentinef7551402014-08-18 16:35:43 -0700372 float insetL = winCrop.left * xScale;
373 float insetT = winCrop.top * yScale;
374 float insetR = (winWidth - winCrop.right ) * xScale;
375 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800376
377 crop.left += insetL;
378 crop.top += insetT;
379 crop.right -= insetR;
380 crop.bottom -= insetB;
381 }
382 return crop;
383}
384
Mathias Agopian4fec8732012-06-29 14:12:52 -0700385void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700386 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700387 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700388{
Mathias Agopian13127d82013-03-05 17:47:11 -0800389 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700390
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700391 // enable this layer
392 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700393
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700394 if (isSecure() && !hw->isSecure()) {
395 layer.setSkip(true);
396 }
397
Mathias Agopian13127d82013-03-05 17:47:11 -0800398 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700399 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800400 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800401 layer.setBlending(mPremultipliedAlpha ?
402 HWC_BLENDING_PREMULT :
403 HWC_BLENDING_COVERAGE);
404 }
405
406 // apply the layer's transform, followed by the display's global transform
407 // here we're guaranteed that the layer's transform preserves rects
408 Rect frame(s.transform.transform(computeBounds()));
409 frame.intersect(hw->getViewport(), &frame);
410 const Transform& tr(hw->getTransform());
411 layer.setFrame(tr.transform(frame));
412 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800413 layer.setPlaneAlpha(s.alpha);
414
Mathias Agopian29a367b2011-07-12 14:51:45 -0700415 /*
416 * Transformations are applied in this order:
417 * 1) buffer orientation/flip/mirror
418 * 2) state transformation (window manager)
419 * 3) layer orientation (screen orientation)
420 * (NOTE: the matrices are multiplied in reverse order)
421 */
422
423 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700424 Transform transform(tr * s.transform * bufferOrientation);
425
426 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
427 /*
428 * the code below applies the display's inverse transform to the buffer
429 */
430 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700431 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700432 // calculate the inverse transform
433 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
434 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
435 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700436 // If the transform has been rotated the axis of flip has been swapped
437 // so we need to swap which flip operations we are performing
438 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
439 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
440 if (is_h_flipped != is_v_flipped) {
441 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
442 NATIVE_WINDOW_TRANSFORM_FLIP_H;
443 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700444 }
445 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700446 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700447 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700448
449 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800450 const uint32_t orientation = transform.getOrientation();
451 if (orientation & Transform::ROT_INVALID) {
452 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700453 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700454 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800455 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700456 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700457}
458
Mathias Agopian42977342012-08-05 00:40:46 -0700459void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700460 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800461 // we have to set the visible region on every frame because
462 // we currently free it during onLayerDisplayed(), which is called
463 // after HWComposer::commit() -- every frame.
464 // Apply this display's projection's viewport to the visible region
465 // before giving it to the HWC HAL.
466 const Transform& tr = hw->getTransform();
467 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
468 layer.setVisibleRegionScreen(visible);
469
Jesse Hall399184a2014-03-03 15:42:54 -0800470 if (mSidebandStream.get()) {
471 layer.setSidebandStream(mSidebandStream);
472 } else {
473 // NOTE: buffer can be NULL if the client never drew into this
474 // layer yet, or if we ran out of memory
475 layer.setBuffer(mActiveBuffer);
476 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700477}
Jesse Halldc5b4852012-06-29 15:21:18 -0700478
Dan Stozac7014012014-02-14 15:03:43 -0800479void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700480 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700481 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700482
483 // TODO: there is a possible optimization here: we only need to set the
484 // acquire fence the first time a new buffer is acquired on EACH display.
485
Riley Andrews03414a12014-07-01 14:22:59 -0700486 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800487 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800488 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700489 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700490 if (fenceFd == -1) {
491 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
492 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700493 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700494 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700495 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700496}
497
Riley Andrews03414a12014-07-01 14:22:59 -0700498Rect Layer::getPosition(
499 const sp<const DisplayDevice>& hw)
500{
501 // this gives us only the "orientation" component of the transform
502 const State& s(getCurrentState());
503
504 // apply the layer's transform, followed by the display's global transform
505 // here we're guaranteed that the layer's transform preserves rects
506 Rect win(s.active.w, s.active.h);
507 if (!s.active.crop.isEmpty()) {
508 win.intersect(s.active.crop, &win);
509 }
510 // subtract the transparent region and snap to the bounds
511 Rect bounds = reduce(win, s.activeTransparentRegion);
512 Rect frame(s.transform.transform(bounds));
513 frame.intersect(hw->getViewport(), &frame);
514 const Transform& tr(hw->getTransform());
515 return Rect(tr.transform(frame));
516}
517
Mathias Agopian13127d82013-03-05 17:47:11 -0800518// ---------------------------------------------------------------------------
519// drawing...
520// ---------------------------------------------------------------------------
521
522void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800523 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800524}
525
Dan Stozac7014012014-02-14 15:03:43 -0800526void Layer::draw(const sp<const DisplayDevice>& hw,
527 bool useIdentityTransform) const {
528 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800529}
530
Dan Stozac7014012014-02-14 15:03:43 -0800531void Layer::draw(const sp<const DisplayDevice>& hw) const {
532 onDraw(hw, Region(hw->bounds()), false);
533}
534
535void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
536 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800537{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800538 ATRACE_CALL();
539
Mathias Agopiana67932f2011-04-20 14:20:59 -0700540 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800541 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700542 // in fact never been drawn into. This happens frequently with
543 // SurfaceView because the WindowManager can't know when the client
544 // has drawn the first time.
545
546 // If there is nothing under us, we paint the screen in black, otherwise
547 // we just skip this update.
548
549 // figure out if there is something below us
550 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700551 const SurfaceFlinger::LayerVector& drawingLayers(
552 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700553 const size_t count = drawingLayers.size();
554 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800555 const sp<Layer>& layer(drawingLayers[i]);
556 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700557 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700558 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700559 }
560 // if not everything below us is covered, we plug the holes!
561 Region holes(clip.subtract(under));
562 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700563 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700564 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800565 return;
566 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700567
Andy McFadden97eba892012-12-11 15:21:45 -0800568 // Bind the current buffer to the GL texture, and wait for it to be
569 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800570 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
571 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800572 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700573 // Go ahead and draw the buffer anyway; no matter what we do the screen
574 // is probably going to have something visibly wrong.
575 }
576
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700577 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
578
Mathias Agopian875d8e12013-06-07 15:35:48 -0700579 RenderEngine& engine(mFlinger->getRenderEngine());
580
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700581 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700582 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700583 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700584
585 // Query the texture matrix given our current filtering mode.
586 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800587 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
588 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700589
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700590 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
591
592 /*
593 * the code below applies the display's inverse transform to the texture transform
594 */
595
596 // create a 4x4 transform matrix from the display transform flags
597 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
598 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
599 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
600
601 mat4 tr;
602 uint32_t transform = hw->getOrientationTransform();
603 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
604 tr = tr * rot90;
605 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
606 tr = tr * flipH;
607 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
608 tr = tr * flipV;
609
610 // calculate the inverse
611 tr = inverse(tr);
612
613 // and finally apply it to the original texture matrix
614 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
615 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
616 }
617
Jamie Genniscbb1a952012-05-08 17:05:52 -0700618 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700619 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
620 mTexture.setFiltering(useFiltering);
621 mTexture.setMatrix(textureMatrix);
622
623 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700624 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700625 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700626 }
Dan Stozac7014012014-02-14 15:03:43 -0800627 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700628 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800629}
630
Mathias Agopian13127d82013-03-05 17:47:11 -0800631
Dan Stozac7014012014-02-14 15:03:43 -0800632void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
633 const Region& /* clip */, float red, float green, float blue,
634 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800635{
Mathias Agopian19733a32013-08-28 18:13:56 -0700636 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800637 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700638 engine.setupFillWithColor(red, green, blue, alpha);
639 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800640}
641
642void Layer::clearWithOpenGL(
643 const sp<const DisplayDevice>& hw, const Region& clip) const {
644 clearWithOpenGL(hw, clip, 0,0,0,0);
645}
646
Dan Stozac7014012014-02-14 15:03:43 -0800647void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
648 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800649 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700650 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800651
Dan Stozac7014012014-02-14 15:03:43 -0800652 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800653
Mathias Agopian13127d82013-03-05 17:47:11 -0800654 /*
655 * NOTE: the way we compute the texture coordinates here produces
656 * different results than when we take the HWC path -- in the later case
657 * the "source crop" is rounded to texel boundaries.
658 * This can produce significantly different results when the texture
659 * is scaled by a large amount.
660 *
661 * The GL code below is more logical (imho), and the difference with
662 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700663 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800664 * GL composition when a buffer scaling is applied (maybe with some
665 * minimal value)? Or, we could make GL behave like HWC -- but this feel
666 * like more of a hack.
667 */
668 const Rect win(computeBounds());
669
Mathias Agopian3f844832013-08-07 21:24:32 -0700670 float left = float(win.left) / float(s.active.w);
671 float top = float(win.top) / float(s.active.h);
672 float right = float(win.right) / float(s.active.w);
673 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800674
Mathias Agopian875d8e12013-06-07 15:35:48 -0700675 // TODO: we probably want to generate the texture coords with the mesh
676 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700677 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
678 texCoords[0] = vec2(left, 1.0f - top);
679 texCoords[1] = vec2(left, 1.0f - bottom);
680 texCoords[2] = vec2(right, 1.0f - bottom);
681 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800682
Mathias Agopian875d8e12013-06-07 15:35:48 -0700683 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800684 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700685 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700686 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800687}
688
Ruben Brunk1681d952014-06-27 15:51:55 -0700689uint32_t Layer::getProducerStickyTransform() const {
690 int producerStickyTransform = 0;
691 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
692 if (ret != OK) {
693 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
694 strerror(-ret), ret);
695 return 0;
696 }
697 return static_cast<uint32_t>(producerStickyTransform);
698}
699
Mathias Agopian13127d82013-03-05 17:47:11 -0800700void Layer::setFiltering(bool filtering) {
701 mFiltering = filtering;
702}
703
704bool Layer::getFiltering() const {
705 return mFiltering;
706}
707
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800708// As documented in libhardware header, formats in the range
709// 0x100 - 0x1FF are specific to the HAL implementation, and
710// are known to have no alpha channel
711// TODO: move definition for device-specific range into
712// hardware.h, instead of using hard-coded values here.
713#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
714
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700715bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700716 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
717 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800718 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700719 switch (format) {
720 case HAL_PIXEL_FORMAT_RGBA_8888:
721 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700722 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700723 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700724 }
725 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700726 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800727}
728
Mathias Agopian13127d82013-03-05 17:47:11 -0800729// ----------------------------------------------------------------------------
730// local state
731// ----------------------------------------------------------------------------
732
Dan Stozac7014012014-02-14 15:03:43 -0800733void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
734 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800735{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700736 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800737 const Transform tr(useIdentityTransform ?
738 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800739 const uint32_t hw_h = hw->getHeight();
740 Rect win(s.active.w, s.active.h);
741 if (!s.active.crop.isEmpty()) {
742 win.intersect(s.active.crop, &win);
743 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700744 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700745 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700746
Mathias Agopianff2ed702013-09-01 21:36:12 -0700747 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
748 position[0] = tr.transform(win.left, win.top);
749 position[1] = tr.transform(win.left, win.bottom);
750 position[2] = tr.transform(win.right, win.bottom);
751 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700752 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700753 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800754 }
755}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800756
Andy McFadden4125a4f2014-01-29 17:17:11 -0800757bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700758{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700759 // if we don't have a buffer yet, we're translucent regardless of the
760 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700761 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700762 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700763 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700764
765 // if the layer has the opaque flag, then we're always opaque,
766 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800767 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700768}
769
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800770bool Layer::isProtected() const
771{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700772 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800773 return (activeBuffer != 0) &&
774 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
775}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700776
Mathias Agopian13127d82013-03-05 17:47:11 -0800777bool Layer::isFixedSize() const {
778 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
779}
780
781bool Layer::isCropped() const {
782 return !mCurrentCrop.isEmpty();
783}
784
785bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
786 return mNeedsFiltering || hw->needsFiltering();
787}
788
789void Layer::setVisibleRegion(const Region& visibleRegion) {
790 // always called from main thread
791 this->visibleRegion = visibleRegion;
792}
793
794void Layer::setCoveredRegion(const Region& coveredRegion) {
795 // always called from main thread
796 this->coveredRegion = coveredRegion;
797}
798
799void Layer::setVisibleNonTransparentRegion(const Region&
800 setVisibleNonTransparentRegion) {
801 // always called from main thread
802 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
803}
804
805// ----------------------------------------------------------------------------
806// transaction
807// ----------------------------------------------------------------------------
808
809uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800810 ATRACE_CALL();
811
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700812 const Layer::State& s(getDrawingState());
813 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800814
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700815 const bool sizeChanged = (c.requested.w != s.requested.w) ||
816 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700817
818 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700819 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000820 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700821 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700822 " current={ 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"
824 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
825 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700826 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
827 c.active.w, c.active.h,
828 c.active.crop.left,
829 c.active.crop.top,
830 c.active.crop.right,
831 c.active.crop.bottom,
832 c.active.crop.getWidth(),
833 c.active.crop.getHeight(),
834 c.requested.w, c.requested.h,
835 c.requested.crop.left,
836 c.requested.crop.top,
837 c.requested.crop.right,
838 c.requested.crop.bottom,
839 c.requested.crop.getWidth(),
840 c.requested.crop.getHeight(),
841 s.active.w, s.active.h,
842 s.active.crop.left,
843 s.active.crop.top,
844 s.active.crop.right,
845 s.active.crop.bottom,
846 s.active.crop.getWidth(),
847 s.active.crop.getHeight(),
848 s.requested.w, s.requested.h,
849 s.requested.crop.left,
850 s.requested.crop.top,
851 s.requested.crop.right,
852 s.requested.crop.bottom,
853 s.requested.crop.getWidth(),
854 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800855
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700856 // record the new size, form this point on, when the client request
857 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800858 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700859 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800860 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700861
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700862 if (!isFixedSize()) {
863
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700864 const bool resizePending = (c.requested.w != c.active.w) ||
865 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700866
867 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800868 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700869 // if we have a pending resize, unless we are in fixed-size mode.
870 // the drawing state will be updated only once we receive a buffer
871 // with the correct size.
872 //
873 // in particular, we want to make sure the clip (which is part
874 // of the geometry state) is latched together with the size but is
875 // latched immediately when no resizing is involved.
876
877 flags |= eDontUpdateGeometryState;
878 }
879 }
880
Mathias Agopian13127d82013-03-05 17:47:11 -0800881 // always set active to requested, unless we're asked not to
882 // this is used by Layer, which special cases resizes.
883 if (flags & eDontUpdateGeometryState) {
884 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700885 Layer::State& editCurrentState(getCurrentState());
886 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800887 }
888
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700889 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800890 // invalidate and recompute the visible regions if needed
891 flags |= Layer::eVisibleRegion;
892 }
893
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700894 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800895 // invalidate and recompute the visible regions if needed
896 flags |= eVisibleRegion;
897 this->contentDirty = true;
898
899 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700900 const uint8_t type = c.transform.getType();
901 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800902 (type >= Transform::SCALE));
903 }
904
905 // Commit the transaction
906 commitTransaction();
907 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800908}
909
Mathias Agopian13127d82013-03-05 17:47:11 -0800910void Layer::commitTransaction() {
911 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700912}
913
Mathias Agopian13127d82013-03-05 17:47:11 -0800914uint32_t Layer::getTransactionFlags(uint32_t flags) {
915 return android_atomic_and(~flags, &mTransactionFlags) & flags;
916}
917
918uint32_t Layer::setTransactionFlags(uint32_t flags) {
919 return android_atomic_or(flags, &mTransactionFlags);
920}
921
922bool Layer::setPosition(float x, float y) {
923 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
924 return false;
925 mCurrentState.sequence++;
926 mCurrentState.transform.set(x, y);
927 setTransactionFlags(eTransactionNeeded);
928 return true;
929}
930bool Layer::setLayer(uint32_t z) {
931 if (mCurrentState.z == z)
932 return false;
933 mCurrentState.sequence++;
934 mCurrentState.z = z;
935 setTransactionFlags(eTransactionNeeded);
936 return true;
937}
938bool Layer::setSize(uint32_t w, uint32_t h) {
939 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
940 return false;
941 mCurrentState.requested.w = w;
942 mCurrentState.requested.h = h;
943 setTransactionFlags(eTransactionNeeded);
944 return true;
945}
946bool Layer::setAlpha(uint8_t alpha) {
947 if (mCurrentState.alpha == alpha)
948 return false;
949 mCurrentState.sequence++;
950 mCurrentState.alpha = alpha;
951 setTransactionFlags(eTransactionNeeded);
952 return true;
953}
954bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
955 mCurrentState.sequence++;
956 mCurrentState.transform.set(
957 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
958 setTransactionFlags(eTransactionNeeded);
959 return true;
960}
961bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700962 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800963 setTransactionFlags(eTransactionNeeded);
964 return true;
965}
966bool Layer::setFlags(uint8_t flags, uint8_t mask) {
967 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
968 if (mCurrentState.flags == newFlags)
969 return false;
970 mCurrentState.sequence++;
971 mCurrentState.flags = newFlags;
972 setTransactionFlags(eTransactionNeeded);
973 return true;
974}
975bool Layer::setCrop(const Rect& crop) {
976 if (mCurrentState.requested.crop == crop)
977 return false;
978 mCurrentState.sequence++;
979 mCurrentState.requested.crop = crop;
980 setTransactionFlags(eTransactionNeeded);
981 return true;
982}
983
984bool Layer::setLayerStack(uint32_t layerStack) {
985 if (mCurrentState.layerStack == layerStack)
986 return false;
987 mCurrentState.sequence++;
988 mCurrentState.layerStack = layerStack;
989 setTransactionFlags(eTransactionNeeded);
990 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700991}
992
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800993// ----------------------------------------------------------------------------
994// pageflip handling...
995// ----------------------------------------------------------------------------
996
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800997bool Layer::onPreComposition() {
998 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -0800999 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001000}
1001
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001002void Layer::onPostComposition() {
1003 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001004 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001005 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1006
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001007 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001008 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001009 mFrameTracker.setFrameReadyFence(frameReadyFence);
1010 } else {
1011 // There was no fence for this frame, so assume that it was ready
1012 // to be presented at the desired present time.
1013 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1014 }
1015
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001016 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001017 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001018 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001019 mFrameTracker.setActualPresentFence(presentFence);
1020 } else {
1021 // The HWC doesn't support present fences, so use the refresh
1022 // timestamp instead.
1023 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1024 mFrameTracker.setActualPresentTime(presentTime);
1025 }
1026
1027 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001028 mFrameLatencyNeeded = false;
1029 }
1030}
1031
Mathias Agopianda27af92012-09-13 18:17:13 -07001032bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001033 const Layer::State& s(mDrawingState);
1034 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001035 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001036}
1037
Mathias Agopian4fec8732012-06-29 14:12:52 -07001038Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001039{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001040 ATRACE_CALL();
1041
Jesse Hall399184a2014-03-03 15:42:54 -08001042 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1043 // mSidebandStreamChanged was true
1044 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001045 recomputeVisibleRegions = true;
1046
1047 const State& s(getDrawingState());
1048 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001049 }
1050
Mathias Agopian4fec8732012-06-29 14:12:52 -07001051 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001052 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001053
1054 // if we've already called updateTexImage() without going through
1055 // a composition step, we have to skip this layer at this point
1056 // because we cannot call updateTeximage() without a corresponding
1057 // compositionComplete() call.
1058 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001059 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001060 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001061 }
1062
Jamie Gennis351a5132011-09-14 18:23:37 -07001063 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001064 const State& s(getDrawingState());
1065 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001066 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001067
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001068 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001069 Layer::State& front;
1070 Layer::State& current;
1071 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001072 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001073 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001074 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001075 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001076 recomputeVisibleRegions(recomputeVisibleRegions),
1077 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001078 }
1079
1080 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001081 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001082 if (buf == NULL) {
1083 return false;
1084 }
1085
1086 uint32_t bufWidth = buf->getWidth();
1087 uint32_t bufHeight = buf->getHeight();
1088
1089 // check that we received a buffer of the right size
1090 // (Take the buffer's orientation into account)
1091 if (item.mTransform & Transform::ROT_90) {
1092 swap(bufWidth, bufHeight);
1093 }
1094
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001095 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1096 if (front.active != front.requested) {
1097
1098 if (isFixedSize ||
1099 (bufWidth == front.requested.w &&
1100 bufHeight == front.requested.h))
1101 {
1102 // Here we pretend the transaction happened by updating the
1103 // current and drawing states. Drawing state is only accessed
1104 // in this thread, no need to have it locked
1105 front.active = front.requested;
1106
1107 // We also need to update the current state so that
1108 // we don't end-up overwriting the drawing state with
1109 // this stale current state during the next transaction
1110 //
1111 // NOTE: We don't need to hold the transaction lock here
1112 // because State::active is only accessed from this thread.
1113 current.active = front.active;
1114
1115 // recompute visible region
1116 recomputeVisibleRegions = true;
1117 }
1118
1119 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001120 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001121 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1122 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001123 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001124 front.active.w, front.active.h,
1125 front.active.crop.left,
1126 front.active.crop.top,
1127 front.active.crop.right,
1128 front.active.crop.bottom,
1129 front.active.crop.getWidth(),
1130 front.active.crop.getHeight(),
1131 front.requested.w, front.requested.h,
1132 front.requested.crop.left,
1133 front.requested.crop.top,
1134 front.requested.crop.right,
1135 front.requested.crop.bottom,
1136 front.requested.crop.getWidth(),
1137 front.requested.crop.getHeight());
1138 }
1139
Ruben Brunk1681d952014-06-27 15:51:55 -07001140 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001141 if (front.active.w != bufWidth ||
1142 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001143 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001144 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1145 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001146 return true;
1147 }
1148 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001149
1150 // if the transparent region has changed (this test is
1151 // conservative, but that's fine, worst case we're doing
1152 // a bit of extra work), we latch the new one and we
1153 // trigger a visible-region recompute.
1154 if (!front.activeTransparentRegion.isTriviallyEqual(
1155 front.requestedTransparentRegion)) {
1156 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001157
1158 // We also need to update the current state so that
1159 // we don't end-up overwriting the drawing state with
1160 // this stale current state during the next transaction
1161 //
1162 // NOTE: We don't need to hold the transaction lock here
1163 // because State::active is only accessed from this thread.
1164 current.activeTransparentRegion = front.activeTransparentRegion;
1165
1166 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001167 recomputeVisibleRegions = true;
1168 }
1169
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001170 return false;
1171 }
1172 };
1173
Ruben Brunk1681d952014-06-27 15:51:55 -07001174 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1175 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001176
Andy McFadden41d67d72014-04-25 16:58:34 -07001177 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1178 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001179 if (updateResult == BufferQueue::PRESENT_LATER) {
1180 // Producer doesn't want buffer to be displayed yet. Signal a
1181 // layer update so we check again at the next opportunity.
1182 mFlinger->signalLayerUpdate();
1183 return outDirtyRegion;
1184 }
1185
1186 // Decrement the queued-frames count. Signal another event if we
1187 // have more frames pending.
1188 if (android_atomic_dec(&mQueuedFrames) > 1) {
1189 mFlinger->signalLayerUpdate();
1190 }
1191
1192 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001193 // something happened!
1194 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001195 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001196 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001197
Jamie Gennis351a5132011-09-14 18:23:37 -07001198 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001199 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001200 if (mActiveBuffer == NULL) {
1201 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001202 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001203 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001204
Mathias Agopian4824d402012-06-04 18:16:30 -07001205 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001206 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001207 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001208 // the first time we receive a buffer, we need to trigger a
1209 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001210 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001211 }
1212
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001213 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1214 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1215 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001216 if ((crop != mCurrentCrop) ||
1217 (transform != mCurrentTransform) ||
1218 (scalingMode != mCurrentScalingMode))
1219 {
1220 mCurrentCrop = crop;
1221 mCurrentTransform = transform;
1222 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001223 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001224 }
1225
1226 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001227 uint32_t bufWidth = mActiveBuffer->getWidth();
1228 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001229 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1230 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001231 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001232 }
1233 }
1234
1235 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001236 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001237 recomputeVisibleRegions = true;
1238 }
1239
Mathias Agopian4fec8732012-06-29 14:12:52 -07001240 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001241 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001242
1243 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001244 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001245 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001246 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001247}
1248
Mathias Agopiana67932f2011-04-20 14:20:59 -07001249uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001250{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001251 // TODO: should we do something special if mSecure is set?
1252 if (mProtectedByApp) {
1253 // need a hardware-protected path to external video sink
1254 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001255 }
Riley Andrews03414a12014-07-01 14:22:59 -07001256 if (mPotentialCursor) {
1257 usage |= GraphicBuffer::USAGE_CURSOR;
1258 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001259 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001260 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001261}
1262
Mathias Agopian84300952012-11-21 16:02:13 -08001263void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001264 uint32_t orientation = 0;
1265 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001266 // The transform hint is used to improve performance, but we can
1267 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001268 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001269 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001270 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001271 if (orientation & Transform::ROT_INVALID) {
1272 orientation = 0;
1273 }
1274 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001275 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001276}
1277
Mathias Agopian13127d82013-03-05 17:47:11 -08001278// ----------------------------------------------------------------------------
1279// debugging
1280// ----------------------------------------------------------------------------
1281
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001282void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001283{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001284 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001285
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001286 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001287 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001288 "+ %s %p (%s)\n",
1289 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001290 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001291
Mathias Agopian2ca79392013-04-02 18:30:32 -07001292 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001293 visibleRegion.dump(result, "visibleRegion");
1294 sp<Client> client(mClientRef.promote());
1295
Mathias Agopian74d211a2013-04-22 16:55:35 +02001296 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001297 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1298 "isOpaque=%1d, invalidate=%1d, "
1299 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1300 " client=%p\n",
1301 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1302 s.active.crop.left, s.active.crop.top,
1303 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001304 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001305 s.alpha, s.flags,
1306 s.transform[0][0], s.transform[0][1],
1307 s.transform[1][0], s.transform[1][1],
1308 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001309
1310 sp<const GraphicBuffer> buf0(mActiveBuffer);
1311 uint32_t w0=0, h0=0, s0=0, f0=0;
1312 if (buf0 != 0) {
1313 w0 = buf0->getWidth();
1314 h0 = buf0->getHeight();
1315 s0 = buf0->getStride();
1316 f0 = buf0->format;
1317 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001318 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001319 " "
1320 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1321 " queued-frames=%d, mRefreshPending=%d\n",
1322 mFormat, w0, h0, s0,f0,
1323 mQueuedFrames, mRefreshPending);
1324
Mathias Agopian13127d82013-03-05 17:47:11 -08001325 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001326 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001327 }
1328}
1329
Svetoslavd85084b2014-03-20 10:28:31 -07001330void Layer::dumpFrameStats(String8& result) const {
1331 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001332}
1333
Svetoslavd85084b2014-03-20 10:28:31 -07001334void Layer::clearFrameStats() {
1335 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001336}
1337
Jamie Gennis6547ff42013-07-16 20:12:42 -07001338void Layer::logFrameStats() {
1339 mFrameTracker.logAndResetStats(mName);
1340}
1341
Svetoslavd85084b2014-03-20 10:28:31 -07001342void Layer::getFrameStats(FrameStats* outStats) const {
1343 mFrameTracker.getStats(outStats);
1344}
1345
Mathias Agopian13127d82013-03-05 17:47:11 -08001346// ---------------------------------------------------------------------------
1347
1348Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1349 const sp<Layer>& layer)
1350 : mFlinger(flinger), mLayer(layer) {
1351}
1352
1353Layer::LayerCleaner::~LayerCleaner() {
1354 // destroy client resources
1355 mFlinger->onLayerDestroyed(mLayer);
1356}
1357
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001358// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001359}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001360
1361#if defined(__gl_h_)
1362#error "don't include gl/gl.h in this file"
1363#endif
1364
1365#if defined(__gl2_h_)
1366#error "don't include gl2/gl2.h in this file"
1367#endif