blob: 7bb7529edcf162a6c0d2be82c4a54d2c2e21a310 [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
Dan Stoza6b9454d2014-11-07 16:00:59 -080037#include <gui/BufferItem.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080038#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039
40#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020041#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070042#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043#include "Layer.h"
Dan Stozab9b08832014-03-13 11:55:57 -070044#include "MonitoredProducer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046
Mathias Agopian1b031492012-06-20 17:51:20 -070047#include "DisplayHardware/HWComposer.h"
48
Mathias Agopian875d8e12013-06-07 15:35:48 -070049#include "RenderEngine/RenderEngine.h"
50
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051#define DEBUG_RESIZE 0
52
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053namespace android {
54
55// ---------------------------------------------------------------------------
56
Mathias Agopian13127d82013-03-05 17:47:11 -080057int32_t Layer::sSequence = 1;
58
Mathias Agopian4d9b8222013-03-12 17:11:48 -070059Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
60 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080061 : contentDirty(false),
62 sequence(uint32_t(android_atomic_inc(&sSequence))),
63 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070064 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080065 mPremultipliedAlpha(true),
66 mName("unnamed"),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 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 Stoza6b9454d2014-11-07 16:00:59 -0800162void Layer::onFrameAvailable(const BufferItem& item) {
163 // Add this buffer from our internal queue tracker
164 { // Autolock scope
165 Mutex::Autolock lock(mQueueItemLock);
166 mQueueItems.push_back(item);
167 }
168
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700169 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800170 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700171}
172
Dan Stoza6b9454d2014-11-07 16:00:59 -0800173void Layer::onFrameReplaced(const BufferItem& item) {
174 Mutex::Autolock lock(mQueueItemLock);
175 if (mQueueItems.empty()) {
176 ALOGE("Can't replace a frame on an empty queue");
177 return;
178 }
179 mQueueItems.editItemAt(0) = item;
180}
181
Jesse Hall399184a2014-03-03 15:42:54 -0800182void Layer::onSidebandStreamChanged() {
183 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
184 // mSidebandStreamChanged was false
185 mFlinger->signalLayerUpdate();
186 }
187}
188
Mathias Agopian67106042013-03-14 19:18:13 -0700189// called with SurfaceFlinger::mStateLock from the drawing thread after
190// the layer has been remove from the current state list (and just before
191// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800192void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800193 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700194}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700195
Mathias Agopian13127d82013-03-05 17:47:11 -0800196// ---------------------------------------------------------------------------
197// set-up
198// ---------------------------------------------------------------------------
199
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700200const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800201 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800202}
203
Mathias Agopianf9d93272009-06-19 17:00:27 -0700204status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800205 PixelFormat format, uint32_t flags)
206{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700207 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700208 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700209
210 // never allow a surface larger than what our underlying GL implementation
211 // can handle.
212 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800213 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700214 return BAD_VALUE;
215 }
216
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700217 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700218
Riley Andrews03414a12014-07-01 14:22:59 -0700219 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700220 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
221 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700222 mCurrentOpacity = getOpacityForFormat(format);
223
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800224 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
225 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
226 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700227
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800228 return NO_ERROR;
229}
230
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700231sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800232 Mutex::Autolock _l(mLock);
233
234 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700235 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800236
237 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700238
239 /*
240 * The layer handle is just a BBinder object passed to the client
241 * (remote process) -- we don't keep any reference on our side such that
242 * the dtor is called when the remote side let go of its reference.
243 *
244 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
245 * this layer when the handle is destroyed.
246 */
247
248 class Handle : public BBinder, public LayerCleaner {
249 wp<const Layer> mOwner;
250 public:
251 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
252 : LayerCleaner(flinger, layer), mOwner(layer) {
253 }
254 };
255
256 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800257}
258
Dan Stozab9b08832014-03-13 11:55:57 -0700259sp<IGraphicBufferProducer> Layer::getProducer() const {
260 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700261}
262
Mathias Agopian13127d82013-03-05 17:47:11 -0800263// ---------------------------------------------------------------------------
264// h/w composer set-up
265// ---------------------------------------------------------------------------
266
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800267Rect Layer::getContentCrop() const {
268 // this is the crop rectangle that applies to the buffer
269 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700270 Rect crop;
271 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800272 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700273 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800274 } else if (mActiveBuffer != NULL) {
275 // otherwise we use the whole buffer
276 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700277 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800278 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700279 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700280 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700281 return crop;
282}
283
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700284static Rect reduce(const Rect& win, const Region& exclude) {
285 if (CC_LIKELY(exclude.isEmpty())) {
286 return win;
287 }
288 if (exclude.isRect()) {
289 return win.reduce(exclude.getBounds());
290 }
291 return Region(win).subtract(exclude).getBounds();
292}
293
Mathias Agopian13127d82013-03-05 17:47:11 -0800294Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700295 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700296 return computeBounds(s.activeTransparentRegion);
297}
298
299Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
300 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800301 Rect win(s.active.w, s.active.h);
302 if (!s.active.crop.isEmpty()) {
303 win.intersect(s.active.crop, &win);
304 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700305 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700306 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800307}
308
Mathias Agopian6b442672013-07-09 21:24:52 -0700309FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800310 // the content crop is the area of the content that gets scaled to the
311 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700312 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800313
314 // the active.crop is the area of the window that gets cropped, but not
315 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700316 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800317
318 // apply the projection's clipping to the window crop in
319 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700320 // if there are no window scaling involved, this operation will map to full
321 // pixels in the buffer.
322 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
323 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700324
325 Rect activeCrop(s.active.w, s.active.h);
326 if (!s.active.crop.isEmpty()) {
327 activeCrop = s.active.crop;
328 }
329
330 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800331 activeCrop.intersect(hw->getViewport(), &activeCrop);
332 activeCrop = s.transform.inverse().transform(activeCrop);
333
Michael Lentine28ea2172014-11-19 18:32:37 -0800334 // This needs to be here as transform.transform(Rect) computes the
335 // transformed rect and then takes the bounding box of the result before
336 // returning. This means
337 // transform.inverse().transform(transform.transform(Rect)) != Rect
338 // in which case we need to make sure the final rect is clipped to the
339 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800340 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
341
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700342 // subtract the transparent region and snap to the bounds
343 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
344
Mathias Agopian13127d82013-03-05 17:47:11 -0800345 if (!activeCrop.isEmpty()) {
346 // Transform the window crop to match the buffer coordinate system,
347 // which means using the inverse of the current transform set on the
348 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700349 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700350 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
351 /*
352 * the code below applies the display's inverse transform to the buffer
353 */
354 uint32_t invTransformOrient = hw->getOrientationTransform();
355 // calculate the inverse transform
356 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
357 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
358 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700359 // If the transform has been rotated the axis of flip has been swapped
360 // so we need to swap which flip operations we are performing
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 }
Michael Lentinef7551402014-08-18 16:35:43 -0700367 }
368 // and apply to the current transform
369 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
370 }
371
Mathias Agopian13127d82013-03-05 17:47:11 -0800372 int winWidth = s.active.w;
373 int winHeight = s.active.h;
374 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700375 // If the activeCrop has been rotate the ends are rotated but not
376 // the space itself so when transforming ends back we can't rely on
377 // a modification of the axes of rotation. To account for this we
378 // need to reorient the inverse rotation in terms of the current
379 // axes of rotation.
380 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
381 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
382 if (is_h_flipped == is_v_flipped) {
383 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
384 NATIVE_WINDOW_TRANSFORM_FLIP_H;
385 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800386 winWidth = s.active.h;
387 winHeight = s.active.w;
388 }
389 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700390 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800391
Mathias Agopian6b442672013-07-09 21:24:52 -0700392 // below, crop is intersected with winCrop expressed in crop's coordinate space
393 float xScale = crop.getWidth() / float(winWidth);
394 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800395
Michael Lentinef7551402014-08-18 16:35:43 -0700396 float insetL = winCrop.left * xScale;
397 float insetT = winCrop.top * yScale;
398 float insetR = (winWidth - winCrop.right ) * xScale;
399 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800400
401 crop.left += insetL;
402 crop.top += insetT;
403 crop.right -= insetR;
404 crop.bottom -= insetB;
405 }
406 return crop;
407}
408
Mathias Agopian4fec8732012-06-29 14:12:52 -0700409void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700410 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700411 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700412{
Mathias Agopian13127d82013-03-05 17:47:11 -0800413 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700414
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700415 // enable this layer
416 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700417
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700418 if (isSecure() && !hw->isSecure()) {
419 layer.setSkip(true);
420 }
421
Mathias Agopian13127d82013-03-05 17:47:11 -0800422 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700423 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800424 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800425 layer.setBlending(mPremultipliedAlpha ?
426 HWC_BLENDING_PREMULT :
427 HWC_BLENDING_COVERAGE);
428 }
429
430 // apply the layer's transform, followed by the display's global transform
431 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700432 Region activeTransparentRegion(s.activeTransparentRegion);
433 if (!s.active.crop.isEmpty()) {
434 Rect activeCrop(s.active.crop);
435 activeCrop = s.transform.transform(activeCrop);
436 activeCrop.intersect(hw->getViewport(), &activeCrop);
437 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800438 // This needs to be here as transform.transform(Rect) computes the
439 // transformed rect and then takes the bounding box of the result before
440 // returning. This means
441 // transform.inverse().transform(transform.transform(Rect)) != Rect
442 // in which case we need to make sure the final rect is clipped to the
443 // display bounds.
444 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700445 // mark regions outside the crop as transparent
446 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
447 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
448 s.active.w, s.active.h));
449 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
450 activeCrop.left, activeCrop.bottom));
451 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
452 s.active.w, activeCrop.bottom));
453 }
454 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800455 frame.intersect(hw->getViewport(), &frame);
456 const Transform& tr(hw->getTransform());
457 layer.setFrame(tr.transform(frame));
458 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800459 layer.setPlaneAlpha(s.alpha);
460
Mathias Agopian29a367b2011-07-12 14:51:45 -0700461 /*
462 * Transformations are applied in this order:
463 * 1) buffer orientation/flip/mirror
464 * 2) state transformation (window manager)
465 * 3) layer orientation (screen orientation)
466 * (NOTE: the matrices are multiplied in reverse order)
467 */
468
469 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700470 Transform transform(tr * s.transform * bufferOrientation);
471
472 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
473 /*
474 * the code below applies the display's inverse transform to the buffer
475 */
476 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700477 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700478 // calculate the inverse transform
479 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
480 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
481 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700482 // If the transform has been rotated the axis of flip has been swapped
483 // so we need to swap which flip operations we are performing
484 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
485 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
486 if (is_h_flipped != is_v_flipped) {
487 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
488 NATIVE_WINDOW_TRANSFORM_FLIP_H;
489 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700490 }
491 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700492 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700493 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700494
495 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800496 const uint32_t orientation = transform.getOrientation();
497 if (orientation & Transform::ROT_INVALID) {
498 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700499 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700500 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800501 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700502 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700503}
504
Mathias Agopian42977342012-08-05 00:40:46 -0700505void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700506 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800507 // we have to set the visible region on every frame because
508 // we currently free it during onLayerDisplayed(), which is called
509 // after HWComposer::commit() -- every frame.
510 // Apply this display's projection's viewport to the visible region
511 // before giving it to the HWC HAL.
512 const Transform& tr = hw->getTransform();
513 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
514 layer.setVisibleRegionScreen(visible);
515
Dan Stozaee44edd2015-03-23 15:50:23 -0700516 // Pass full-surface damage down untouched
517 if (surfaceDamageRegion.isRect() &&
518 surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
519 layer.setSurfaceDamage(surfaceDamageRegion);
520 } else {
521 Region surfaceDamage =
522 tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
523 layer.setSurfaceDamage(surfaceDamage);
524 }
525
Jesse Hall399184a2014-03-03 15:42:54 -0800526 if (mSidebandStream.get()) {
527 layer.setSidebandStream(mSidebandStream);
528 } else {
529 // NOTE: buffer can be NULL if the client never drew into this
530 // layer yet, or if we ran out of memory
531 layer.setBuffer(mActiveBuffer);
532 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700533}
Jesse Halldc5b4852012-06-29 15:21:18 -0700534
Dan Stozac7014012014-02-14 15:03:43 -0800535void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700536 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700537 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700538
539 // TODO: there is a possible optimization here: we only need to set the
540 // acquire fence the first time a new buffer is acquired on EACH display.
541
Riley Andrews03414a12014-07-01 14:22:59 -0700542 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800543 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800544 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700545 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700546 if (fenceFd == -1) {
547 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
548 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700549 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700550 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700551 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700552}
553
Riley Andrews03414a12014-07-01 14:22:59 -0700554Rect Layer::getPosition(
555 const sp<const DisplayDevice>& hw)
556{
557 // this gives us only the "orientation" component of the transform
558 const State& s(getCurrentState());
559
560 // apply the layer's transform, followed by the display's global transform
561 // here we're guaranteed that the layer's transform preserves rects
562 Rect win(s.active.w, s.active.h);
563 if (!s.active.crop.isEmpty()) {
564 win.intersect(s.active.crop, &win);
565 }
566 // subtract the transparent region and snap to the bounds
567 Rect bounds = reduce(win, s.activeTransparentRegion);
568 Rect frame(s.transform.transform(bounds));
569 frame.intersect(hw->getViewport(), &frame);
570 const Transform& tr(hw->getTransform());
571 return Rect(tr.transform(frame));
572}
573
Mathias Agopian13127d82013-03-05 17:47:11 -0800574// ---------------------------------------------------------------------------
575// drawing...
576// ---------------------------------------------------------------------------
577
578void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800579 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800580}
581
Dan Stozac7014012014-02-14 15:03:43 -0800582void Layer::draw(const sp<const DisplayDevice>& hw,
583 bool useIdentityTransform) const {
584 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800585}
586
Dan Stozac7014012014-02-14 15:03:43 -0800587void Layer::draw(const sp<const DisplayDevice>& hw) const {
588 onDraw(hw, Region(hw->bounds()), false);
589}
590
591void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
592 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800593{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800594 ATRACE_CALL();
595
Mathias Agopiana67932f2011-04-20 14:20:59 -0700596 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800597 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700598 // in fact never been drawn into. This happens frequently with
599 // SurfaceView because the WindowManager can't know when the client
600 // has drawn the first time.
601
602 // If there is nothing under us, we paint the screen in black, otherwise
603 // we just skip this update.
604
605 // figure out if there is something below us
606 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700607 const SurfaceFlinger::LayerVector& drawingLayers(
608 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700609 const size_t count = drawingLayers.size();
610 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800611 const sp<Layer>& layer(drawingLayers[i]);
612 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700613 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700614 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700615 }
616 // if not everything below us is covered, we plug the holes!
617 Region holes(clip.subtract(under));
618 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700619 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700620 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800621 return;
622 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700623
Andy McFadden97eba892012-12-11 15:21:45 -0800624 // Bind the current buffer to the GL texture, and wait for it to be
625 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800626 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
627 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800628 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700629 // Go ahead and draw the buffer anyway; no matter what we do the screen
630 // is probably going to have something visibly wrong.
631 }
632
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700633 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
634
Mathias Agopian875d8e12013-06-07 15:35:48 -0700635 RenderEngine& engine(mFlinger->getRenderEngine());
636
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700637 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700638 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700639 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700640
641 // Query the texture matrix given our current filtering mode.
642 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800643 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
644 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700645
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700646 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
647
648 /*
649 * the code below applies the display's inverse transform to the texture transform
650 */
651
652 // create a 4x4 transform matrix from the display transform flags
653 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
654 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
655 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
656
657 mat4 tr;
658 uint32_t transform = hw->getOrientationTransform();
659 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
660 tr = tr * rot90;
661 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
662 tr = tr * flipH;
663 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
664 tr = tr * flipV;
665
666 // calculate the inverse
667 tr = inverse(tr);
668
669 // and finally apply it to the original texture matrix
670 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
671 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
672 }
673
Jamie Genniscbb1a952012-05-08 17:05:52 -0700674 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700675 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
676 mTexture.setFiltering(useFiltering);
677 mTexture.setMatrix(textureMatrix);
678
679 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700680 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700681 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700682 }
Dan Stozac7014012014-02-14 15:03:43 -0800683 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700684 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800685}
686
Mathias Agopian13127d82013-03-05 17:47:11 -0800687
Dan Stozac7014012014-02-14 15:03:43 -0800688void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
689 const Region& /* clip */, float red, float green, float blue,
690 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800691{
Mathias Agopian19733a32013-08-28 18:13:56 -0700692 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800693 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700694 engine.setupFillWithColor(red, green, blue, alpha);
695 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800696}
697
698void Layer::clearWithOpenGL(
699 const sp<const DisplayDevice>& hw, const Region& clip) const {
700 clearWithOpenGL(hw, clip, 0,0,0,0);
701}
702
Dan Stozac7014012014-02-14 15:03:43 -0800703void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
704 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700705 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800706
Dan Stozac7014012014-02-14 15:03:43 -0800707 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800708
Mathias Agopian13127d82013-03-05 17:47:11 -0800709 /*
710 * NOTE: the way we compute the texture coordinates here produces
711 * different results than when we take the HWC path -- in the later case
712 * the "source crop" is rounded to texel boundaries.
713 * This can produce significantly different results when the texture
714 * is scaled by a large amount.
715 *
716 * The GL code below is more logical (imho), and the difference with
717 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700718 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800719 * GL composition when a buffer scaling is applied (maybe with some
720 * minimal value)? Or, we could make GL behave like HWC -- but this feel
721 * like more of a hack.
722 */
723 const Rect win(computeBounds());
724
Mathias Agopian3f844832013-08-07 21:24:32 -0700725 float left = float(win.left) / float(s.active.w);
726 float top = float(win.top) / float(s.active.h);
727 float right = float(win.right) / float(s.active.w);
728 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800729
Mathias Agopian875d8e12013-06-07 15:35:48 -0700730 // TODO: we probably want to generate the texture coords with the mesh
731 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700732 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
733 texCoords[0] = vec2(left, 1.0f - top);
734 texCoords[1] = vec2(left, 1.0f - bottom);
735 texCoords[2] = vec2(right, 1.0f - bottom);
736 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800737
Mathias Agopian875d8e12013-06-07 15:35:48 -0700738 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800739 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700740 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700741 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800742}
743
Ruben Brunk1681d952014-06-27 15:51:55 -0700744uint32_t Layer::getProducerStickyTransform() const {
745 int producerStickyTransform = 0;
746 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
747 if (ret != OK) {
748 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
749 strerror(-ret), ret);
750 return 0;
751 }
752 return static_cast<uint32_t>(producerStickyTransform);
753}
754
Mathias Agopian13127d82013-03-05 17:47:11 -0800755void Layer::setFiltering(bool filtering) {
756 mFiltering = filtering;
757}
758
759bool Layer::getFiltering() const {
760 return mFiltering;
761}
762
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800763// As documented in libhardware header, formats in the range
764// 0x100 - 0x1FF are specific to the HAL implementation, and
765// are known to have no alpha channel
766// TODO: move definition for device-specific range into
767// hardware.h, instead of using hard-coded values here.
768#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
769
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700770bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700771 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
772 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800773 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700774 switch (format) {
775 case HAL_PIXEL_FORMAT_RGBA_8888:
776 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700777 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700778 }
779 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700780 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800781}
782
Mathias Agopian13127d82013-03-05 17:47:11 -0800783// ----------------------------------------------------------------------------
784// local state
785// ----------------------------------------------------------------------------
786
Dan Stozac7014012014-02-14 15:03:43 -0800787void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
788 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800789{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700790 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800791 const Transform tr(useIdentityTransform ?
792 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800793 const uint32_t hw_h = hw->getHeight();
794 Rect win(s.active.w, s.active.h);
795 if (!s.active.crop.isEmpty()) {
796 win.intersect(s.active.crop, &win);
797 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700798 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700799 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700800
Mathias Agopianff2ed702013-09-01 21:36:12 -0700801 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
802 position[0] = tr.transform(win.left, win.top);
803 position[1] = tr.transform(win.left, win.bottom);
804 position[2] = tr.transform(win.right, win.bottom);
805 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700806 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700807 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800808 }
809}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800810
Andy McFadden4125a4f2014-01-29 17:17:11 -0800811bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700812{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700813 // if we don't have a buffer yet, we're translucent regardless of the
814 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700815 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700816 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700817 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700818
819 // if the layer has the opaque flag, then we're always opaque,
820 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800821 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700822}
823
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800824bool Layer::isProtected() const
825{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700826 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800827 return (activeBuffer != 0) &&
828 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
829}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700830
Mathias Agopian13127d82013-03-05 17:47:11 -0800831bool Layer::isFixedSize() const {
832 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
833}
834
835bool Layer::isCropped() const {
836 return !mCurrentCrop.isEmpty();
837}
838
839bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
840 return mNeedsFiltering || hw->needsFiltering();
841}
842
843void Layer::setVisibleRegion(const Region& visibleRegion) {
844 // always called from main thread
845 this->visibleRegion = visibleRegion;
846}
847
848void Layer::setCoveredRegion(const Region& coveredRegion) {
849 // always called from main thread
850 this->coveredRegion = coveredRegion;
851}
852
853void Layer::setVisibleNonTransparentRegion(const Region&
854 setVisibleNonTransparentRegion) {
855 // always called from main thread
856 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
857}
858
859// ----------------------------------------------------------------------------
860// transaction
861// ----------------------------------------------------------------------------
862
863uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800864 ATRACE_CALL();
865
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700866 const Layer::State& s(getDrawingState());
867 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800868
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700869 const bool sizeChanged = (c.requested.w != s.requested.w) ||
870 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700871
872 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700873 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000874 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700875 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700876 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
877 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
878 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
879 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700880 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
881 c.active.w, c.active.h,
882 c.active.crop.left,
883 c.active.crop.top,
884 c.active.crop.right,
885 c.active.crop.bottom,
886 c.active.crop.getWidth(),
887 c.active.crop.getHeight(),
888 c.requested.w, c.requested.h,
889 c.requested.crop.left,
890 c.requested.crop.top,
891 c.requested.crop.right,
892 c.requested.crop.bottom,
893 c.requested.crop.getWidth(),
894 c.requested.crop.getHeight(),
895 s.active.w, s.active.h,
896 s.active.crop.left,
897 s.active.crop.top,
898 s.active.crop.right,
899 s.active.crop.bottom,
900 s.active.crop.getWidth(),
901 s.active.crop.getHeight(),
902 s.requested.w, s.requested.h,
903 s.requested.crop.left,
904 s.requested.crop.top,
905 s.requested.crop.right,
906 s.requested.crop.bottom,
907 s.requested.crop.getWidth(),
908 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800909
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700910 // record the new size, form this point on, when the client request
911 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800912 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700913 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800914 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700915
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700916 if (!isFixedSize()) {
917
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700918 const bool resizePending = (c.requested.w != c.active.w) ||
919 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700920
921 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800922 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700923 // if we have a pending resize, unless we are in fixed-size mode.
924 // the drawing state will be updated only once we receive a buffer
925 // with the correct size.
926 //
927 // in particular, we want to make sure the clip (which is part
928 // of the geometry state) is latched together with the size but is
929 // latched immediately when no resizing is involved.
930
931 flags |= eDontUpdateGeometryState;
932 }
933 }
934
Mathias Agopian13127d82013-03-05 17:47:11 -0800935 // always set active to requested, unless we're asked not to
936 // this is used by Layer, which special cases resizes.
937 if (flags & eDontUpdateGeometryState) {
938 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700939 Layer::State& editCurrentState(getCurrentState());
940 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800941 }
942
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700943 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800944 // invalidate and recompute the visible regions if needed
945 flags |= Layer::eVisibleRegion;
946 }
947
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700948 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800949 // invalidate and recompute the visible regions if needed
950 flags |= eVisibleRegion;
951 this->contentDirty = true;
952
953 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700954 const uint8_t type = c.transform.getType();
955 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800956 (type >= Transform::SCALE));
957 }
958
959 // Commit the transaction
960 commitTransaction();
961 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800962}
963
Mathias Agopian13127d82013-03-05 17:47:11 -0800964void Layer::commitTransaction() {
965 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700966}
967
Mathias Agopian13127d82013-03-05 17:47:11 -0800968uint32_t Layer::getTransactionFlags(uint32_t flags) {
969 return android_atomic_and(~flags, &mTransactionFlags) & flags;
970}
971
972uint32_t Layer::setTransactionFlags(uint32_t flags) {
973 return android_atomic_or(flags, &mTransactionFlags);
974}
975
976bool Layer::setPosition(float x, float y) {
977 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
978 return false;
979 mCurrentState.sequence++;
980 mCurrentState.transform.set(x, y);
981 setTransactionFlags(eTransactionNeeded);
982 return true;
983}
984bool Layer::setLayer(uint32_t z) {
985 if (mCurrentState.z == z)
986 return false;
987 mCurrentState.sequence++;
988 mCurrentState.z = z;
989 setTransactionFlags(eTransactionNeeded);
990 return true;
991}
992bool Layer::setSize(uint32_t w, uint32_t h) {
993 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
994 return false;
995 mCurrentState.requested.w = w;
996 mCurrentState.requested.h = h;
997 setTransactionFlags(eTransactionNeeded);
998 return true;
999}
1000bool Layer::setAlpha(uint8_t alpha) {
1001 if (mCurrentState.alpha == alpha)
1002 return false;
1003 mCurrentState.sequence++;
1004 mCurrentState.alpha = alpha;
1005 setTransactionFlags(eTransactionNeeded);
1006 return true;
1007}
1008bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1009 mCurrentState.sequence++;
1010 mCurrentState.transform.set(
1011 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1012 setTransactionFlags(eTransactionNeeded);
1013 return true;
1014}
1015bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001016 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001017 setTransactionFlags(eTransactionNeeded);
1018 return true;
1019}
1020bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1021 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1022 if (mCurrentState.flags == newFlags)
1023 return false;
1024 mCurrentState.sequence++;
1025 mCurrentState.flags = newFlags;
1026 setTransactionFlags(eTransactionNeeded);
1027 return true;
1028}
1029bool Layer::setCrop(const Rect& crop) {
1030 if (mCurrentState.requested.crop == crop)
1031 return false;
1032 mCurrentState.sequence++;
1033 mCurrentState.requested.crop = crop;
1034 setTransactionFlags(eTransactionNeeded);
1035 return true;
1036}
1037
1038bool Layer::setLayerStack(uint32_t layerStack) {
1039 if (mCurrentState.layerStack == layerStack)
1040 return false;
1041 mCurrentState.sequence++;
1042 mCurrentState.layerStack = layerStack;
1043 setTransactionFlags(eTransactionNeeded);
1044 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001045}
1046
Dan Stozaee44edd2015-03-23 15:50:23 -07001047void Layer::useSurfaceDamage() {
1048 if (mFlinger->mForceFullDamage) {
1049 surfaceDamageRegion = Region::INVALID_REGION;
1050 } else {
1051 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1052 }
1053}
1054
1055void Layer::useEmptyDamage() {
1056 surfaceDamageRegion.clear();
1057}
1058
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001059// ----------------------------------------------------------------------------
1060// pageflip handling...
1061// ----------------------------------------------------------------------------
1062
Dan Stoza6b9454d2014-11-07 16:00:59 -08001063bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1064 Mutex::Autolock lock(mQueueItemLock);
1065 nsecs_t expectedPresent =
1066 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1067 return mQueueItems.empty() ?
1068 false : mQueueItems[0].mTimestamp < expectedPresent;
1069}
1070
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001071bool Layer::onPreComposition() {
1072 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001073 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001074}
1075
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001076void Layer::onPostComposition() {
1077 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001078 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001079 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1080
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001081 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001082 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001083 mFrameTracker.setFrameReadyFence(frameReadyFence);
1084 } else {
1085 // There was no fence for this frame, so assume that it was ready
1086 // to be presented at the desired present time.
1087 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1088 }
1089
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001090 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001091 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001092 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001093 mFrameTracker.setActualPresentFence(presentFence);
1094 } else {
1095 // The HWC doesn't support present fences, so use the refresh
1096 // timestamp instead.
1097 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1098 mFrameTracker.setActualPresentTime(presentTime);
1099 }
1100
1101 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001102 mFrameLatencyNeeded = false;
1103 }
1104}
1105
Mathias Agopianda27af92012-09-13 18:17:13 -07001106bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001107 const Layer::State& s(mDrawingState);
1108 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001109 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001110}
1111
Mathias Agopian4fec8732012-06-29 14:12:52 -07001112Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001113{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001114 ATRACE_CALL();
1115
Jesse Hall399184a2014-03-03 15:42:54 -08001116 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1117 // mSidebandStreamChanged was true
1118 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001119 recomputeVisibleRegions = true;
1120
1121 const State& s(getDrawingState());
1122 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001123 }
1124
Mathias Agopian4fec8732012-06-29 14:12:52 -07001125 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001126 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001127
1128 // if we've already called updateTexImage() without going through
1129 // a composition step, we have to skip this layer at this point
1130 // because we cannot call updateTeximage() without a corresponding
1131 // compositionComplete() call.
1132 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001133 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001134 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001135 }
1136
Jamie Gennis351a5132011-09-14 18:23:37 -07001137 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001138 const State& s(getDrawingState());
1139 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001140 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001141
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001142 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001143 Layer::State& front;
1144 Layer::State& current;
1145 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001146 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001147 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001148 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001149 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001150 recomputeVisibleRegions(recomputeVisibleRegions),
1151 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001152 }
1153
1154 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001155 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001156 if (buf == NULL) {
1157 return false;
1158 }
1159
1160 uint32_t bufWidth = buf->getWidth();
1161 uint32_t bufHeight = buf->getHeight();
1162
1163 // check that we received a buffer of the right size
1164 // (Take the buffer's orientation into account)
1165 if (item.mTransform & Transform::ROT_90) {
1166 swap(bufWidth, bufHeight);
1167 }
1168
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001169 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1170 if (front.active != front.requested) {
1171
1172 if (isFixedSize ||
1173 (bufWidth == front.requested.w &&
1174 bufHeight == front.requested.h))
1175 {
1176 // Here we pretend the transaction happened by updating the
1177 // current and drawing states. Drawing state is only accessed
1178 // in this thread, no need to have it locked
1179 front.active = front.requested;
1180
1181 // We also need to update the current state so that
1182 // we don't end-up overwriting the drawing state with
1183 // this stale current state during the next transaction
1184 //
1185 // NOTE: We don't need to hold the transaction lock here
1186 // because State::active is only accessed from this thread.
1187 current.active = front.active;
1188
1189 // recompute visible region
1190 recomputeVisibleRegions = true;
1191 }
1192
1193 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001194 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001195 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1196 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001197 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001198 front.active.w, front.active.h,
1199 front.active.crop.left,
1200 front.active.crop.top,
1201 front.active.crop.right,
1202 front.active.crop.bottom,
1203 front.active.crop.getWidth(),
1204 front.active.crop.getHeight(),
1205 front.requested.w, front.requested.h,
1206 front.requested.crop.left,
1207 front.requested.crop.top,
1208 front.requested.crop.right,
1209 front.requested.crop.bottom,
1210 front.requested.crop.getWidth(),
1211 front.requested.crop.getHeight());
1212 }
1213
Ruben Brunk1681d952014-06-27 15:51:55 -07001214 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001215 if (front.active.w != bufWidth ||
1216 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001217 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001218 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1219 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001220 return true;
1221 }
1222 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001223
1224 // if the transparent region has changed (this test is
1225 // conservative, but that's fine, worst case we're doing
1226 // a bit of extra work), we latch the new one and we
1227 // trigger a visible-region recompute.
1228 if (!front.activeTransparentRegion.isTriviallyEqual(
1229 front.requestedTransparentRegion)) {
1230 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001231
1232 // We also need to update the current state so that
1233 // we don't end-up overwriting the drawing state with
1234 // this stale current state during the next transaction
1235 //
1236 // NOTE: We don't need to hold the transaction lock here
1237 // because State::active is only accessed from this thread.
1238 current.activeTransparentRegion = front.activeTransparentRegion;
1239
1240 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001241 recomputeVisibleRegions = true;
1242 }
1243
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001244 return false;
1245 }
1246 };
1247
Ruben Brunk1681d952014-06-27 15:51:55 -07001248 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1249 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001250
Andy McFadden41d67d72014-04-25 16:58:34 -07001251 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1252 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001253 if (updateResult == BufferQueue::PRESENT_LATER) {
1254 // Producer doesn't want buffer to be displayed yet. Signal a
1255 // layer update so we check again at the next opportunity.
1256 mFlinger->signalLayerUpdate();
1257 return outDirtyRegion;
1258 }
1259
Dan Stoza6b9454d2014-11-07 16:00:59 -08001260 // Remove this buffer from our internal queue tracker
1261 { // Autolock scope
1262 Mutex::Autolock lock(mQueueItemLock);
1263 mQueueItems.removeAt(0);
1264 }
1265
Andy McFadden1585c4d2013-06-28 13:52:40 -07001266 // Decrement the queued-frames count. Signal another event if we
1267 // have more frames pending.
1268 if (android_atomic_dec(&mQueuedFrames) > 1) {
1269 mFlinger->signalLayerUpdate();
1270 }
1271
1272 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001273 // something happened!
1274 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001275 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001276 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001277
Jamie Gennis351a5132011-09-14 18:23:37 -07001278 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001279 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001280 if (mActiveBuffer == NULL) {
1281 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001282 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001283 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001284
Mathias Agopian4824d402012-06-04 18:16:30 -07001285 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001286 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001287 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001288 // the first time we receive a buffer, we need to trigger a
1289 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001290 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001291 }
1292
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001293 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1294 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1295 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001296 if ((crop != mCurrentCrop) ||
1297 (transform != mCurrentTransform) ||
1298 (scalingMode != mCurrentScalingMode))
1299 {
1300 mCurrentCrop = crop;
1301 mCurrentTransform = transform;
1302 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001303 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001304 }
1305
1306 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001307 uint32_t bufWidth = mActiveBuffer->getWidth();
1308 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001309 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1310 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001311 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001312 }
1313 }
1314
1315 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001316 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001317 recomputeVisibleRegions = true;
1318 }
1319
Mathias Agopian4fec8732012-06-29 14:12:52 -07001320 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001321 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001322
1323 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001324 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001325 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001326 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001327}
1328
Mathias Agopiana67932f2011-04-20 14:20:59 -07001329uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001330{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001331 // TODO: should we do something special if mSecure is set?
1332 if (mProtectedByApp) {
1333 // need a hardware-protected path to external video sink
1334 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001335 }
Riley Andrews03414a12014-07-01 14:22:59 -07001336 if (mPotentialCursor) {
1337 usage |= GraphicBuffer::USAGE_CURSOR;
1338 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001339 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001340 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001341}
1342
Mathias Agopian84300952012-11-21 16:02:13 -08001343void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001344 uint32_t orientation = 0;
1345 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001346 // The transform hint is used to improve performance, but we can
1347 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001348 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001349 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001350 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001351 if (orientation & Transform::ROT_INVALID) {
1352 orientation = 0;
1353 }
1354 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001355 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001356}
1357
Mathias Agopian13127d82013-03-05 17:47:11 -08001358// ----------------------------------------------------------------------------
1359// debugging
1360// ----------------------------------------------------------------------------
1361
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001362void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001363{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001364 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001365
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001366 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001367 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001368 "+ %s %p (%s)\n",
1369 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001370 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001371
Mathias Agopian2ca79392013-04-02 18:30:32 -07001372 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001373 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001374 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001375 sp<Client> client(mClientRef.promote());
1376
Mathias Agopian74d211a2013-04-22 16:55:35 +02001377 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001378 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1379 "isOpaque=%1d, invalidate=%1d, "
1380 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1381 " client=%p\n",
1382 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1383 s.active.crop.left, s.active.crop.top,
1384 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001385 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001386 s.alpha, s.flags,
1387 s.transform[0][0], s.transform[0][1],
1388 s.transform[1][0], s.transform[1][1],
1389 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001390
1391 sp<const GraphicBuffer> buf0(mActiveBuffer);
1392 uint32_t w0=0, h0=0, s0=0, f0=0;
1393 if (buf0 != 0) {
1394 w0 = buf0->getWidth();
1395 h0 = buf0->getHeight();
1396 s0 = buf0->getStride();
1397 f0 = buf0->format;
1398 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001399 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001400 " "
1401 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1402 " queued-frames=%d, mRefreshPending=%d\n",
1403 mFormat, w0, h0, s0,f0,
1404 mQueuedFrames, mRefreshPending);
1405
Mathias Agopian13127d82013-03-05 17:47:11 -08001406 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001407 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001408 }
1409}
1410
Svetoslavd85084b2014-03-20 10:28:31 -07001411void Layer::dumpFrameStats(String8& result) const {
1412 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001413}
1414
Svetoslavd85084b2014-03-20 10:28:31 -07001415void Layer::clearFrameStats() {
1416 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001417}
1418
Jamie Gennis6547ff42013-07-16 20:12:42 -07001419void Layer::logFrameStats() {
1420 mFrameTracker.logAndResetStats(mName);
1421}
1422
Svetoslavd85084b2014-03-20 10:28:31 -07001423void Layer::getFrameStats(FrameStats* outStats) const {
1424 mFrameTracker.getStats(outStats);
1425}
1426
Mathias Agopian13127d82013-03-05 17:47:11 -08001427// ---------------------------------------------------------------------------
1428
1429Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1430 const sp<Layer>& layer)
1431 : mFlinger(flinger), mLayer(layer) {
1432}
1433
1434Layer::LayerCleaner::~LayerCleaner() {
1435 // destroy client resources
1436 mFlinger->onLayerDestroyed(mLayer);
1437}
1438
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001439// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001440}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001441
1442#if defined(__gl_h_)
1443#error "don't include gl/gl.h in this file"
1444#endif
1445
1446#if defined(__gl2_h_)
1447#error "don't include gl2/gl2.h in this file"
1448#endif