blob: acc277531d2c31a6a73b9f7468080263c7aa878d [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
Dan Stoza8dc55392014-11-04 11:37:46 -0800162void Layer::onFrameAvailable(const BufferItem& /* item */) {
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());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700281 return computeBounds(s.activeTransparentRegion);
282}
283
284Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
285 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800286 Rect win(s.active.w, s.active.h);
287 if (!s.active.crop.isEmpty()) {
288 win.intersect(s.active.crop, &win);
289 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700290 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700291 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800292}
293
Mathias Agopian6b442672013-07-09 21:24:52 -0700294FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800295 // the content crop is the area of the content that gets scaled to the
296 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700297 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800298
299 // the active.crop is the area of the window that gets cropped, but not
300 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700301 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800302
303 // apply the projection's clipping to the window crop in
304 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700305 // if there are no window scaling involved, this operation will map to full
306 // pixels in the buffer.
307 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
308 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700309
310 Rect activeCrop(s.active.w, s.active.h);
311 if (!s.active.crop.isEmpty()) {
312 activeCrop = s.active.crop;
313 }
314
315 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800316 activeCrop.intersect(hw->getViewport(), &activeCrop);
317 activeCrop = s.transform.inverse().transform(activeCrop);
318
319 // paranoia: make sure the window-crop is constrained in the
320 // window's bounds
321 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
322
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700323 // subtract the transparent region and snap to the bounds
324 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
325
Mathias Agopian13127d82013-03-05 17:47:11 -0800326 if (!activeCrop.isEmpty()) {
327 // Transform the window crop to match the buffer coordinate system,
328 // which means using the inverse of the current transform set on the
329 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700330 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700331 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
332 /*
333 * the code below applies the display's inverse transform to the buffer
334 */
335 uint32_t invTransformOrient = hw->getOrientationTransform();
336 // calculate the inverse transform
337 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
338 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
339 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700340 // If the transform has been rotated the axis of flip has been swapped
341 // so we need to swap which flip operations we are performing
342 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
343 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
344 if (is_h_flipped != is_v_flipped) {
345 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
346 NATIVE_WINDOW_TRANSFORM_FLIP_H;
347 }
Michael Lentinef7551402014-08-18 16:35:43 -0700348 }
349 // and apply to the current transform
350 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
351 }
352
Mathias Agopian13127d82013-03-05 17:47:11 -0800353 int winWidth = s.active.w;
354 int winHeight = s.active.h;
355 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700356 // If the activeCrop has been rotate the ends are rotated but not
357 // the space itself so when transforming ends back we can't rely on
358 // a modification of the axes of rotation. To account for this we
359 // need to reorient the inverse rotation in terms of the current
360 // axes of rotation.
361 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
362 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
363 if (is_h_flipped == is_v_flipped) {
364 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
365 NATIVE_WINDOW_TRANSFORM_FLIP_H;
366 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800367 winWidth = s.active.h;
368 winHeight = s.active.w;
369 }
370 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700371 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800372
Mathias Agopian6b442672013-07-09 21:24:52 -0700373 // below, crop is intersected with winCrop expressed in crop's coordinate space
374 float xScale = crop.getWidth() / float(winWidth);
375 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800376
Michael Lentinef7551402014-08-18 16:35:43 -0700377 float insetL = winCrop.left * xScale;
378 float insetT = winCrop.top * yScale;
379 float insetR = (winWidth - winCrop.right ) * xScale;
380 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800381
382 crop.left += insetL;
383 crop.top += insetT;
384 crop.right -= insetR;
385 crop.bottom -= insetB;
386 }
387 return crop;
388}
389
Mathias Agopian4fec8732012-06-29 14:12:52 -0700390void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700391 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700392 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700393{
Mathias Agopian13127d82013-03-05 17:47:11 -0800394 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700395
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700396 // enable this layer
397 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700398
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700399 if (isSecure() && !hw->isSecure()) {
400 layer.setSkip(true);
401 }
402
Mathias Agopian13127d82013-03-05 17:47:11 -0800403 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700404 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800405 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800406 layer.setBlending(mPremultipliedAlpha ?
407 HWC_BLENDING_PREMULT :
408 HWC_BLENDING_COVERAGE);
409 }
410
411 // apply the layer's transform, followed by the display's global transform
412 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700413 Region activeTransparentRegion(s.activeTransparentRegion);
414 if (!s.active.crop.isEmpty()) {
415 Rect activeCrop(s.active.crop);
416 activeCrop = s.transform.transform(activeCrop);
417 activeCrop.intersect(hw->getViewport(), &activeCrop);
418 activeCrop = s.transform.inverse().transform(activeCrop);
419 // mark regions outside the crop as transparent
420 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
421 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
422 s.active.w, s.active.h));
423 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
424 activeCrop.left, activeCrop.bottom));
425 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
426 s.active.w, activeCrop.bottom));
427 }
428 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800429 frame.intersect(hw->getViewport(), &frame);
430 const Transform& tr(hw->getTransform());
431 layer.setFrame(tr.transform(frame));
432 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800433 layer.setPlaneAlpha(s.alpha);
434
Mathias Agopian29a367b2011-07-12 14:51:45 -0700435 /*
436 * Transformations are applied in this order:
437 * 1) buffer orientation/flip/mirror
438 * 2) state transformation (window manager)
439 * 3) layer orientation (screen orientation)
440 * (NOTE: the matrices are multiplied in reverse order)
441 */
442
443 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700444 Transform transform(tr * s.transform * bufferOrientation);
445
446 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
447 /*
448 * the code below applies the display's inverse transform to the buffer
449 */
450 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700451 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700452 // calculate the inverse transform
453 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
454 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
455 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700456 // If the transform has been rotated the axis of flip has been swapped
457 // so we need to swap which flip operations we are performing
458 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
459 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
460 if (is_h_flipped != is_v_flipped) {
461 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
462 NATIVE_WINDOW_TRANSFORM_FLIP_H;
463 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700464 }
465 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700466 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700467 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700468
469 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800470 const uint32_t orientation = transform.getOrientation();
471 if (orientation & Transform::ROT_INVALID) {
472 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700473 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700474 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800475 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700476 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700477}
478
Mathias Agopian42977342012-08-05 00:40:46 -0700479void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700480 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800481 // we have to set the visible region on every frame because
482 // we currently free it during onLayerDisplayed(), which is called
483 // after HWComposer::commit() -- every frame.
484 // Apply this display's projection's viewport to the visible region
485 // before giving it to the HWC HAL.
486 const Transform& tr = hw->getTransform();
487 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
488 layer.setVisibleRegionScreen(visible);
489
Jesse Hall399184a2014-03-03 15:42:54 -0800490 if (mSidebandStream.get()) {
491 layer.setSidebandStream(mSidebandStream);
492 } else {
493 // NOTE: buffer can be NULL if the client never drew into this
494 // layer yet, or if we ran out of memory
495 layer.setBuffer(mActiveBuffer);
496 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700497}
Jesse Halldc5b4852012-06-29 15:21:18 -0700498
Dan Stozac7014012014-02-14 15:03:43 -0800499void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700500 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700501 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700502
503 // TODO: there is a possible optimization here: we only need to set the
504 // acquire fence the first time a new buffer is acquired on EACH display.
505
Riley Andrews03414a12014-07-01 14:22:59 -0700506 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800507 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800508 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700509 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700510 if (fenceFd == -1) {
511 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
512 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700513 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700514 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700515 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700516}
517
Riley Andrews03414a12014-07-01 14:22:59 -0700518Rect Layer::getPosition(
519 const sp<const DisplayDevice>& hw)
520{
521 // this gives us only the "orientation" component of the transform
522 const State& s(getCurrentState());
523
524 // apply the layer's transform, followed by the display's global transform
525 // here we're guaranteed that the layer's transform preserves rects
526 Rect win(s.active.w, s.active.h);
527 if (!s.active.crop.isEmpty()) {
528 win.intersect(s.active.crop, &win);
529 }
530 // subtract the transparent region and snap to the bounds
531 Rect bounds = reduce(win, s.activeTransparentRegion);
532 Rect frame(s.transform.transform(bounds));
533 frame.intersect(hw->getViewport(), &frame);
534 const Transform& tr(hw->getTransform());
535 return Rect(tr.transform(frame));
536}
537
Mathias Agopian13127d82013-03-05 17:47:11 -0800538// ---------------------------------------------------------------------------
539// drawing...
540// ---------------------------------------------------------------------------
541
542void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800543 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800544}
545
Dan Stozac7014012014-02-14 15:03:43 -0800546void Layer::draw(const sp<const DisplayDevice>& hw,
547 bool useIdentityTransform) const {
548 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800549}
550
Dan Stozac7014012014-02-14 15:03:43 -0800551void Layer::draw(const sp<const DisplayDevice>& hw) const {
552 onDraw(hw, Region(hw->bounds()), false);
553}
554
555void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
556 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800557{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800558 ATRACE_CALL();
559
Mathias Agopiana67932f2011-04-20 14:20:59 -0700560 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800561 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700562 // in fact never been drawn into. This happens frequently with
563 // SurfaceView because the WindowManager can't know when the client
564 // has drawn the first time.
565
566 // If there is nothing under us, we paint the screen in black, otherwise
567 // we just skip this update.
568
569 // figure out if there is something below us
570 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700571 const SurfaceFlinger::LayerVector& drawingLayers(
572 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700573 const size_t count = drawingLayers.size();
574 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800575 const sp<Layer>& layer(drawingLayers[i]);
576 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700577 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700578 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700579 }
580 // if not everything below us is covered, we plug the holes!
581 Region holes(clip.subtract(under));
582 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700583 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700584 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800585 return;
586 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700587
Andy McFadden97eba892012-12-11 15:21:45 -0800588 // Bind the current buffer to the GL texture, and wait for it to be
589 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800590 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
591 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800592 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700593 // Go ahead and draw the buffer anyway; no matter what we do the screen
594 // is probably going to have something visibly wrong.
595 }
596
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700597 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
598
Mathias Agopian875d8e12013-06-07 15:35:48 -0700599 RenderEngine& engine(mFlinger->getRenderEngine());
600
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700601 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700602 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700603 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700604
605 // Query the texture matrix given our current filtering mode.
606 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800607 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
608 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700609
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700610 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
611
612 /*
613 * the code below applies the display's inverse transform to the texture transform
614 */
615
616 // create a 4x4 transform matrix from the display transform flags
617 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
618 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
619 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
620
621 mat4 tr;
622 uint32_t transform = hw->getOrientationTransform();
623 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
624 tr = tr * rot90;
625 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
626 tr = tr * flipH;
627 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
628 tr = tr * flipV;
629
630 // calculate the inverse
631 tr = inverse(tr);
632
633 // and finally apply it to the original texture matrix
634 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
635 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
636 }
637
Jamie Genniscbb1a952012-05-08 17:05:52 -0700638 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700639 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
640 mTexture.setFiltering(useFiltering);
641 mTexture.setMatrix(textureMatrix);
642
643 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700644 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700645 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700646 }
Dan Stozac7014012014-02-14 15:03:43 -0800647 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700648 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800649}
650
Mathias Agopian13127d82013-03-05 17:47:11 -0800651
Dan Stozac7014012014-02-14 15:03:43 -0800652void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
653 const Region& /* clip */, float red, float green, float blue,
654 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800655{
Mathias Agopian19733a32013-08-28 18:13:56 -0700656 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800657 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700658 engine.setupFillWithColor(red, green, blue, alpha);
659 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800660}
661
662void Layer::clearWithOpenGL(
663 const sp<const DisplayDevice>& hw, const Region& clip) const {
664 clearWithOpenGL(hw, clip, 0,0,0,0);
665}
666
Dan Stozac7014012014-02-14 15:03:43 -0800667void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
668 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800669 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700670 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800671
Dan Stozac7014012014-02-14 15:03:43 -0800672 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800673
Mathias Agopian13127d82013-03-05 17:47:11 -0800674 /*
675 * NOTE: the way we compute the texture coordinates here produces
676 * different results than when we take the HWC path -- in the later case
677 * the "source crop" is rounded to texel boundaries.
678 * This can produce significantly different results when the texture
679 * is scaled by a large amount.
680 *
681 * The GL code below is more logical (imho), and the difference with
682 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700683 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800684 * GL composition when a buffer scaling is applied (maybe with some
685 * minimal value)? Or, we could make GL behave like HWC -- but this feel
686 * like more of a hack.
687 */
688 const Rect win(computeBounds());
689
Mathias Agopian3f844832013-08-07 21:24:32 -0700690 float left = float(win.left) / float(s.active.w);
691 float top = float(win.top) / float(s.active.h);
692 float right = float(win.right) / float(s.active.w);
693 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800694
Mathias Agopian875d8e12013-06-07 15:35:48 -0700695 // TODO: we probably want to generate the texture coords with the mesh
696 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700697 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
698 texCoords[0] = vec2(left, 1.0f - top);
699 texCoords[1] = vec2(left, 1.0f - bottom);
700 texCoords[2] = vec2(right, 1.0f - bottom);
701 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800702
Mathias Agopian875d8e12013-06-07 15:35:48 -0700703 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800704 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700705 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700706 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800707}
708
Ruben Brunk1681d952014-06-27 15:51:55 -0700709uint32_t Layer::getProducerStickyTransform() const {
710 int producerStickyTransform = 0;
711 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
712 if (ret != OK) {
713 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
714 strerror(-ret), ret);
715 return 0;
716 }
717 return static_cast<uint32_t>(producerStickyTransform);
718}
719
Mathias Agopian13127d82013-03-05 17:47:11 -0800720void Layer::setFiltering(bool filtering) {
721 mFiltering = filtering;
722}
723
724bool Layer::getFiltering() const {
725 return mFiltering;
726}
727
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800728// As documented in libhardware header, formats in the range
729// 0x100 - 0x1FF are specific to the HAL implementation, and
730// are known to have no alpha channel
731// TODO: move definition for device-specific range into
732// hardware.h, instead of using hard-coded values here.
733#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
734
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700735bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700736 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
737 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800738 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700739 switch (format) {
740 case HAL_PIXEL_FORMAT_RGBA_8888:
741 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700742 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700743 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700744 }
745 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700746 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800747}
748
Mathias Agopian13127d82013-03-05 17:47:11 -0800749// ----------------------------------------------------------------------------
750// local state
751// ----------------------------------------------------------------------------
752
Dan Stozac7014012014-02-14 15:03:43 -0800753void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
754 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800755{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700756 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800757 const Transform tr(useIdentityTransform ?
758 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800759 const uint32_t hw_h = hw->getHeight();
760 Rect win(s.active.w, s.active.h);
761 if (!s.active.crop.isEmpty()) {
762 win.intersect(s.active.crop, &win);
763 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700764 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700765 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700766
Mathias Agopianff2ed702013-09-01 21:36:12 -0700767 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
768 position[0] = tr.transform(win.left, win.top);
769 position[1] = tr.transform(win.left, win.bottom);
770 position[2] = tr.transform(win.right, win.bottom);
771 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700772 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700773 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800774 }
775}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800776
Andy McFadden4125a4f2014-01-29 17:17:11 -0800777bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700778{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700779 // if we don't have a buffer yet, we're translucent regardless of the
780 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700781 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700782 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700783 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700784
785 // if the layer has the opaque flag, then we're always opaque,
786 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800787 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700788}
789
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800790bool Layer::isProtected() const
791{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700792 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800793 return (activeBuffer != 0) &&
794 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
795}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700796
Mathias Agopian13127d82013-03-05 17:47:11 -0800797bool Layer::isFixedSize() const {
798 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
799}
800
801bool Layer::isCropped() const {
802 return !mCurrentCrop.isEmpty();
803}
804
805bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
806 return mNeedsFiltering || hw->needsFiltering();
807}
808
809void Layer::setVisibleRegion(const Region& visibleRegion) {
810 // always called from main thread
811 this->visibleRegion = visibleRegion;
812}
813
814void Layer::setCoveredRegion(const Region& coveredRegion) {
815 // always called from main thread
816 this->coveredRegion = coveredRegion;
817}
818
819void Layer::setVisibleNonTransparentRegion(const Region&
820 setVisibleNonTransparentRegion) {
821 // always called from main thread
822 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
823}
824
825// ----------------------------------------------------------------------------
826// transaction
827// ----------------------------------------------------------------------------
828
829uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800830 ATRACE_CALL();
831
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700832 const Layer::State& s(getDrawingState());
833 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800834
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700835 const bool sizeChanged = (c.requested.w != s.requested.w) ||
836 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700837
838 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700839 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000840 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700841 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700842 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
843 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
844 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
845 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700846 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
847 c.active.w, c.active.h,
848 c.active.crop.left,
849 c.active.crop.top,
850 c.active.crop.right,
851 c.active.crop.bottom,
852 c.active.crop.getWidth(),
853 c.active.crop.getHeight(),
854 c.requested.w, c.requested.h,
855 c.requested.crop.left,
856 c.requested.crop.top,
857 c.requested.crop.right,
858 c.requested.crop.bottom,
859 c.requested.crop.getWidth(),
860 c.requested.crop.getHeight(),
861 s.active.w, s.active.h,
862 s.active.crop.left,
863 s.active.crop.top,
864 s.active.crop.right,
865 s.active.crop.bottom,
866 s.active.crop.getWidth(),
867 s.active.crop.getHeight(),
868 s.requested.w, s.requested.h,
869 s.requested.crop.left,
870 s.requested.crop.top,
871 s.requested.crop.right,
872 s.requested.crop.bottom,
873 s.requested.crop.getWidth(),
874 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800875
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700876 // record the new size, form this point on, when the client request
877 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800878 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700879 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800880 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700881
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700882 if (!isFixedSize()) {
883
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700884 const bool resizePending = (c.requested.w != c.active.w) ||
885 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700886
887 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800888 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700889 // if we have a pending resize, unless we are in fixed-size mode.
890 // the drawing state will be updated only once we receive a buffer
891 // with the correct size.
892 //
893 // in particular, we want to make sure the clip (which is part
894 // of the geometry state) is latched together with the size but is
895 // latched immediately when no resizing is involved.
896
897 flags |= eDontUpdateGeometryState;
898 }
899 }
900
Mathias Agopian13127d82013-03-05 17:47:11 -0800901 // always set active to requested, unless we're asked not to
902 // this is used by Layer, which special cases resizes.
903 if (flags & eDontUpdateGeometryState) {
904 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700905 Layer::State& editCurrentState(getCurrentState());
906 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800907 }
908
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700909 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800910 // invalidate and recompute the visible regions if needed
911 flags |= Layer::eVisibleRegion;
912 }
913
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700914 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800915 // invalidate and recompute the visible regions if needed
916 flags |= eVisibleRegion;
917 this->contentDirty = true;
918
919 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700920 const uint8_t type = c.transform.getType();
921 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800922 (type >= Transform::SCALE));
923 }
924
925 // Commit the transaction
926 commitTransaction();
927 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800928}
929
Mathias Agopian13127d82013-03-05 17:47:11 -0800930void Layer::commitTransaction() {
931 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700932}
933
Mathias Agopian13127d82013-03-05 17:47:11 -0800934uint32_t Layer::getTransactionFlags(uint32_t flags) {
935 return android_atomic_and(~flags, &mTransactionFlags) & flags;
936}
937
938uint32_t Layer::setTransactionFlags(uint32_t flags) {
939 return android_atomic_or(flags, &mTransactionFlags);
940}
941
942bool Layer::setPosition(float x, float y) {
943 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
944 return false;
945 mCurrentState.sequence++;
946 mCurrentState.transform.set(x, y);
947 setTransactionFlags(eTransactionNeeded);
948 return true;
949}
950bool Layer::setLayer(uint32_t z) {
951 if (mCurrentState.z == z)
952 return false;
953 mCurrentState.sequence++;
954 mCurrentState.z = z;
955 setTransactionFlags(eTransactionNeeded);
956 return true;
957}
958bool Layer::setSize(uint32_t w, uint32_t h) {
959 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
960 return false;
961 mCurrentState.requested.w = w;
962 mCurrentState.requested.h = h;
963 setTransactionFlags(eTransactionNeeded);
964 return true;
965}
966bool Layer::setAlpha(uint8_t alpha) {
967 if (mCurrentState.alpha == alpha)
968 return false;
969 mCurrentState.sequence++;
970 mCurrentState.alpha = alpha;
971 setTransactionFlags(eTransactionNeeded);
972 return true;
973}
974bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
975 mCurrentState.sequence++;
976 mCurrentState.transform.set(
977 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
978 setTransactionFlags(eTransactionNeeded);
979 return true;
980}
981bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700982 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800983 setTransactionFlags(eTransactionNeeded);
984 return true;
985}
986bool Layer::setFlags(uint8_t flags, uint8_t mask) {
987 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
988 if (mCurrentState.flags == newFlags)
989 return false;
990 mCurrentState.sequence++;
991 mCurrentState.flags = newFlags;
992 setTransactionFlags(eTransactionNeeded);
993 return true;
994}
995bool Layer::setCrop(const Rect& crop) {
996 if (mCurrentState.requested.crop == crop)
997 return false;
998 mCurrentState.sequence++;
999 mCurrentState.requested.crop = crop;
1000 setTransactionFlags(eTransactionNeeded);
1001 return true;
1002}
1003
1004bool Layer::setLayerStack(uint32_t layerStack) {
1005 if (mCurrentState.layerStack == layerStack)
1006 return false;
1007 mCurrentState.sequence++;
1008 mCurrentState.layerStack = layerStack;
1009 setTransactionFlags(eTransactionNeeded);
1010 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001011}
1012
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001013// ----------------------------------------------------------------------------
1014// pageflip handling...
1015// ----------------------------------------------------------------------------
1016
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001017bool Layer::onPreComposition() {
1018 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001019 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001020}
1021
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001022void Layer::onPostComposition() {
1023 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001024 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001025 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1026
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001027 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001028 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001029 mFrameTracker.setFrameReadyFence(frameReadyFence);
1030 } else {
1031 // There was no fence for this frame, so assume that it was ready
1032 // to be presented at the desired present time.
1033 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1034 }
1035
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001036 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001037 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001038 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001039 mFrameTracker.setActualPresentFence(presentFence);
1040 } else {
1041 // The HWC doesn't support present fences, so use the refresh
1042 // timestamp instead.
1043 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1044 mFrameTracker.setActualPresentTime(presentTime);
1045 }
1046
1047 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001048 mFrameLatencyNeeded = false;
1049 }
1050}
1051
Mathias Agopianda27af92012-09-13 18:17:13 -07001052bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001053 const Layer::State& s(mDrawingState);
1054 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001055 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001056}
1057
Mathias Agopian4fec8732012-06-29 14:12:52 -07001058Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001059{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001060 ATRACE_CALL();
1061
Jesse Hall399184a2014-03-03 15:42:54 -08001062 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1063 // mSidebandStreamChanged was true
1064 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001065 recomputeVisibleRegions = true;
1066
1067 const State& s(getDrawingState());
1068 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001069 }
1070
Mathias Agopian4fec8732012-06-29 14:12:52 -07001071 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001072 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001073
1074 // if we've already called updateTexImage() without going through
1075 // a composition step, we have to skip this layer at this point
1076 // because we cannot call updateTeximage() without a corresponding
1077 // compositionComplete() call.
1078 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001079 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001080 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001081 }
1082
Jamie Gennis351a5132011-09-14 18:23:37 -07001083 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001084 const State& s(getDrawingState());
1085 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001086 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001087
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001088 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001089 Layer::State& front;
1090 Layer::State& current;
1091 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001092 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001093 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001094 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001095 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001096 recomputeVisibleRegions(recomputeVisibleRegions),
1097 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001098 }
1099
1100 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001101 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001102 if (buf == NULL) {
1103 return false;
1104 }
1105
1106 uint32_t bufWidth = buf->getWidth();
1107 uint32_t bufHeight = buf->getHeight();
1108
1109 // check that we received a buffer of the right size
1110 // (Take the buffer's orientation into account)
1111 if (item.mTransform & Transform::ROT_90) {
1112 swap(bufWidth, bufHeight);
1113 }
1114
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001115 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1116 if (front.active != front.requested) {
1117
1118 if (isFixedSize ||
1119 (bufWidth == front.requested.w &&
1120 bufHeight == front.requested.h))
1121 {
1122 // Here we pretend the transaction happened by updating the
1123 // current and drawing states. Drawing state is only accessed
1124 // in this thread, no need to have it locked
1125 front.active = front.requested;
1126
1127 // We also need to update the current state so that
1128 // we don't end-up overwriting the drawing state with
1129 // this stale current state during the next transaction
1130 //
1131 // NOTE: We don't need to hold the transaction lock here
1132 // because State::active is only accessed from this thread.
1133 current.active = front.active;
1134
1135 // recompute visible region
1136 recomputeVisibleRegions = true;
1137 }
1138
1139 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001140 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001141 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1142 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001143 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001144 front.active.w, front.active.h,
1145 front.active.crop.left,
1146 front.active.crop.top,
1147 front.active.crop.right,
1148 front.active.crop.bottom,
1149 front.active.crop.getWidth(),
1150 front.active.crop.getHeight(),
1151 front.requested.w, front.requested.h,
1152 front.requested.crop.left,
1153 front.requested.crop.top,
1154 front.requested.crop.right,
1155 front.requested.crop.bottom,
1156 front.requested.crop.getWidth(),
1157 front.requested.crop.getHeight());
1158 }
1159
Ruben Brunk1681d952014-06-27 15:51:55 -07001160 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001161 if (front.active.w != bufWidth ||
1162 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001163 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001164 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1165 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001166 return true;
1167 }
1168 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001169
1170 // if the transparent region has changed (this test is
1171 // conservative, but that's fine, worst case we're doing
1172 // a bit of extra work), we latch the new one and we
1173 // trigger a visible-region recompute.
1174 if (!front.activeTransparentRegion.isTriviallyEqual(
1175 front.requestedTransparentRegion)) {
1176 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001177
1178 // We also need to update the current state so that
1179 // we don't end-up overwriting the drawing state with
1180 // this stale current state during the next transaction
1181 //
1182 // NOTE: We don't need to hold the transaction lock here
1183 // because State::active is only accessed from this thread.
1184 current.activeTransparentRegion = front.activeTransparentRegion;
1185
1186 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001187 recomputeVisibleRegions = true;
1188 }
1189
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001190 return false;
1191 }
1192 };
1193
Ruben Brunk1681d952014-06-27 15:51:55 -07001194 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1195 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001196
Andy McFadden41d67d72014-04-25 16:58:34 -07001197 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1198 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001199 if (updateResult == BufferQueue::PRESENT_LATER) {
1200 // Producer doesn't want buffer to be displayed yet. Signal a
1201 // layer update so we check again at the next opportunity.
1202 mFlinger->signalLayerUpdate();
1203 return outDirtyRegion;
1204 }
1205
1206 // Decrement the queued-frames count. Signal another event if we
1207 // have more frames pending.
1208 if (android_atomic_dec(&mQueuedFrames) > 1) {
1209 mFlinger->signalLayerUpdate();
1210 }
1211
1212 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001213 // something happened!
1214 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001215 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001216 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001217
Jamie Gennis351a5132011-09-14 18:23:37 -07001218 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001219 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001220 if (mActiveBuffer == NULL) {
1221 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001222 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001223 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001224
Mathias Agopian4824d402012-06-04 18:16:30 -07001225 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001226 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001227 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001228 // the first time we receive a buffer, we need to trigger a
1229 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001230 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001231 }
1232
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001233 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1234 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1235 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001236 if ((crop != mCurrentCrop) ||
1237 (transform != mCurrentTransform) ||
1238 (scalingMode != mCurrentScalingMode))
1239 {
1240 mCurrentCrop = crop;
1241 mCurrentTransform = transform;
1242 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001243 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001244 }
1245
1246 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001247 uint32_t bufWidth = mActiveBuffer->getWidth();
1248 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001249 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1250 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001251 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001252 }
1253 }
1254
1255 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001256 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001257 recomputeVisibleRegions = true;
1258 }
1259
Mathias Agopian4fec8732012-06-29 14:12:52 -07001260 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001261 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001262
1263 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001264 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001265 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001266 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001267}
1268
Mathias Agopiana67932f2011-04-20 14:20:59 -07001269uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001270{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001271 // TODO: should we do something special if mSecure is set?
1272 if (mProtectedByApp) {
1273 // need a hardware-protected path to external video sink
1274 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001275 }
Riley Andrews03414a12014-07-01 14:22:59 -07001276 if (mPotentialCursor) {
1277 usage |= GraphicBuffer::USAGE_CURSOR;
1278 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001279 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001280 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001281}
1282
Mathias Agopian84300952012-11-21 16:02:13 -08001283void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001284 uint32_t orientation = 0;
1285 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001286 // The transform hint is used to improve performance, but we can
1287 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001288 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001289 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001290 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001291 if (orientation & Transform::ROT_INVALID) {
1292 orientation = 0;
1293 }
1294 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001295 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001296}
1297
Mathias Agopian13127d82013-03-05 17:47:11 -08001298// ----------------------------------------------------------------------------
1299// debugging
1300// ----------------------------------------------------------------------------
1301
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001302void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001303{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001304 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001305
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001306 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001307 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001308 "+ %s %p (%s)\n",
1309 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001310 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001311
Mathias Agopian2ca79392013-04-02 18:30:32 -07001312 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001313 visibleRegion.dump(result, "visibleRegion");
1314 sp<Client> client(mClientRef.promote());
1315
Mathias Agopian74d211a2013-04-22 16:55:35 +02001316 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001317 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1318 "isOpaque=%1d, invalidate=%1d, "
1319 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1320 " client=%p\n",
1321 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1322 s.active.crop.left, s.active.crop.top,
1323 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001324 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001325 s.alpha, s.flags,
1326 s.transform[0][0], s.transform[0][1],
1327 s.transform[1][0], s.transform[1][1],
1328 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001329
1330 sp<const GraphicBuffer> buf0(mActiveBuffer);
1331 uint32_t w0=0, h0=0, s0=0, f0=0;
1332 if (buf0 != 0) {
1333 w0 = buf0->getWidth();
1334 h0 = buf0->getHeight();
1335 s0 = buf0->getStride();
1336 f0 = buf0->format;
1337 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001338 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001339 " "
1340 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1341 " queued-frames=%d, mRefreshPending=%d\n",
1342 mFormat, w0, h0, s0,f0,
1343 mQueuedFrames, mRefreshPending);
1344
Mathias Agopian13127d82013-03-05 17:47:11 -08001345 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001346 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001347 }
1348}
1349
Svetoslavd85084b2014-03-20 10:28:31 -07001350void Layer::dumpFrameStats(String8& result) const {
1351 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001352}
1353
Svetoslavd85084b2014-03-20 10:28:31 -07001354void Layer::clearFrameStats() {
1355 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001356}
1357
Jamie Gennis6547ff42013-07-16 20:12:42 -07001358void Layer::logFrameStats() {
1359 mFrameTracker.logAndResetStats(mName);
1360}
1361
Svetoslavd85084b2014-03-20 10:28:31 -07001362void Layer::getFrameStats(FrameStats* outStats) const {
1363 mFrameTracker.getStats(outStats);
1364}
1365
Mathias Agopian13127d82013-03-05 17:47:11 -08001366// ---------------------------------------------------------------------------
1367
1368Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1369 const sp<Layer>& layer)
1370 : mFlinger(flinger), mLayer(layer) {
1371}
1372
1373Layer::LayerCleaner::~LayerCleaner() {
1374 // destroy client resources
1375 mFlinger->onLayerDestroyed(mLayer);
1376}
1377
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001378// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001379}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001380
1381#if defined(__gl_h_)
1382#error "don't include gl/gl.h in this file"
1383#endif
1384
1385#if defined(__gl2_h_)
1386#error "don't include gl2/gl2.h in this file"
1387#endif