blob: 9fb94dd3d3a0c40e7048c2fd764a3a0f16fc0d7a [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
Dan Stozaecc50402015-04-28 14:42:06 -0700130 // Set the shadow queue size to 0 to notify the BufferQueue that we are
131 // shadowing it
132 mSurfaceFlingerConsumer->setShadowQueueSize(0);
133
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700134#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
135#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800136 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700137#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800138 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800139#endif
Andy McFadden69052052012-09-14 16:10:11 -0700140
Mathias Agopian84300952012-11-21 16:02:13 -0800141 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
142 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700143}
144
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700145Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800146 sp<Client> c(mClientRef.promote());
147 if (c != 0) {
148 c->detachLayer(this);
149 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700150 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700151 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700152}
153
Mathias Agopian13127d82013-03-05 17:47:11 -0800154// ---------------------------------------------------------------------------
155// callbacks
156// ---------------------------------------------------------------------------
157
Dan Stozac7014012014-02-14 15:03:43 -0800158void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800159 HWComposer::HWCLayerInterface* layer) {
160 if (layer) {
161 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700162 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800163 }
164}
165
Dan Stoza6b9454d2014-11-07 16:00:59 -0800166void Layer::onFrameAvailable(const BufferItem& item) {
167 // Add this buffer from our internal queue tracker
168 { // Autolock scope
169 Mutex::Autolock lock(mQueueItemLock);
170 mQueueItems.push_back(item);
Dan Stozaecc50402015-04-28 14:42:06 -0700171 mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
172 android_atomic_inc(&mQueuedFrames);
Dan Stoza6b9454d2014-11-07 16:00:59 -0800173 }
174
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800175 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700176}
177
Dan Stoza6b9454d2014-11-07 16:00:59 -0800178void Layer::onFrameReplaced(const BufferItem& item) {
179 Mutex::Autolock lock(mQueueItemLock);
180 if (mQueueItems.empty()) {
181 ALOGE("Can't replace a frame on an empty queue");
182 return;
183 }
184 mQueueItems.editItemAt(0) = item;
185}
186
Jesse Hall399184a2014-03-03 15:42:54 -0800187void Layer::onSidebandStreamChanged() {
188 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
189 // mSidebandStreamChanged was false
190 mFlinger->signalLayerUpdate();
191 }
192}
193
Mathias Agopian67106042013-03-14 19:18:13 -0700194// called with SurfaceFlinger::mStateLock from the drawing thread after
195// the layer has been remove from the current state list (and just before
196// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800197void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800198 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700199}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700200
Mathias Agopian13127d82013-03-05 17:47:11 -0800201// ---------------------------------------------------------------------------
202// set-up
203// ---------------------------------------------------------------------------
204
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700205const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800206 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800207}
208
Mathias Agopianf9d93272009-06-19 17:00:27 -0700209status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800210 PixelFormat format, uint32_t flags)
211{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700212 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700213 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700214
215 // never allow a surface larger than what our underlying GL implementation
216 // can handle.
217 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800218 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700219 return BAD_VALUE;
220 }
221
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700222 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700223
Riley Andrews03414a12014-07-01 14:22:59 -0700224 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700225 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
226 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700227 mCurrentOpacity = getOpacityForFormat(format);
228
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800229 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
230 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
231 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700232
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800233 return NO_ERROR;
234}
235
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700236sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800237 Mutex::Autolock _l(mLock);
238
239 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700240 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800241
242 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700243
244 /*
245 * The layer handle is just a BBinder object passed to the client
246 * (remote process) -- we don't keep any reference on our side such that
247 * the dtor is called when the remote side let go of its reference.
248 *
249 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
250 * this layer when the handle is destroyed.
251 */
252
253 class Handle : public BBinder, public LayerCleaner {
254 wp<const Layer> mOwner;
255 public:
256 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
257 : LayerCleaner(flinger, layer), mOwner(layer) {
258 }
259 };
260
261 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800262}
263
Dan Stozab9b08832014-03-13 11:55:57 -0700264sp<IGraphicBufferProducer> Layer::getProducer() const {
265 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700266}
267
Mathias Agopian13127d82013-03-05 17:47:11 -0800268// ---------------------------------------------------------------------------
269// h/w composer set-up
270// ---------------------------------------------------------------------------
271
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800272Rect Layer::getContentCrop() const {
273 // this is the crop rectangle that applies to the buffer
274 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700275 Rect crop;
276 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800277 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700278 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800279 } else if (mActiveBuffer != NULL) {
280 // otherwise we use the whole buffer
281 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700282 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800283 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700284 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700285 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700286 return crop;
287}
288
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700289static Rect reduce(const Rect& win, const Region& exclude) {
290 if (CC_LIKELY(exclude.isEmpty())) {
291 return win;
292 }
293 if (exclude.isRect()) {
294 return win.reduce(exclude.getBounds());
295 }
296 return Region(win).subtract(exclude).getBounds();
297}
298
Mathias Agopian13127d82013-03-05 17:47:11 -0800299Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700300 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700301 return computeBounds(s.activeTransparentRegion);
302}
303
304Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
305 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800306 Rect win(s.active.w, s.active.h);
307 if (!s.active.crop.isEmpty()) {
308 win.intersect(s.active.crop, &win);
309 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700310 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700311 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800312}
313
Mathias Agopian6b442672013-07-09 21:24:52 -0700314FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800315 // the content crop is the area of the content that gets scaled to the
316 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700317 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800318
319 // the active.crop is the area of the window that gets cropped, but not
320 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700321 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800322
323 // apply the projection's clipping to the window crop in
324 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700325 // if there are no window scaling involved, this operation will map to full
326 // pixels in the buffer.
327 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
328 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700329
330 Rect activeCrop(s.active.w, s.active.h);
331 if (!s.active.crop.isEmpty()) {
332 activeCrop = s.active.crop;
333 }
334
335 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800336 activeCrop.intersect(hw->getViewport(), &activeCrop);
337 activeCrop = s.transform.inverse().transform(activeCrop);
338
Michael Lentine28ea2172014-11-19 18:32:37 -0800339 // This needs to be here as transform.transform(Rect) computes the
340 // transformed rect and then takes the bounding box of the result before
341 // returning. This means
342 // transform.inverse().transform(transform.transform(Rect)) != Rect
343 // in which case we need to make sure the final rect is clipped to the
344 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800345 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
346
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700347 // subtract the transparent region and snap to the bounds
348 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
349
Mathias Agopian13127d82013-03-05 17:47:11 -0800350 if (!activeCrop.isEmpty()) {
351 // Transform the window crop to match the buffer coordinate system,
352 // which means using the inverse of the current transform set on the
353 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700354 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700355 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
356 /*
357 * the code below applies the display's inverse transform to the buffer
358 */
359 uint32_t invTransformOrient = hw->getOrientationTransform();
360 // calculate the inverse transform
361 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
362 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
363 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700364 // If the transform has been rotated the axis of flip has been swapped
365 // so we need to swap which flip operations we are performing
366 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
367 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
368 if (is_h_flipped != is_v_flipped) {
369 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
370 NATIVE_WINDOW_TRANSFORM_FLIP_H;
371 }
Michael Lentinef7551402014-08-18 16:35:43 -0700372 }
373 // and apply to the current transform
374 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
375 }
376
Mathias Agopian13127d82013-03-05 17:47:11 -0800377 int winWidth = s.active.w;
378 int winHeight = s.active.h;
379 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700380 // If the activeCrop has been rotate the ends are rotated but not
381 // the space itself so when transforming ends back we can't rely on
382 // a modification of the axes of rotation. To account for this we
383 // need to reorient the inverse rotation in terms of the current
384 // axes of rotation.
385 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
386 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
387 if (is_h_flipped == is_v_flipped) {
388 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
389 NATIVE_WINDOW_TRANSFORM_FLIP_H;
390 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800391 winWidth = s.active.h;
392 winHeight = s.active.w;
393 }
394 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700395 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800396
Mathias Agopian6b442672013-07-09 21:24:52 -0700397 // below, crop is intersected with winCrop expressed in crop's coordinate space
398 float xScale = crop.getWidth() / float(winWidth);
399 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800400
Michael Lentinef7551402014-08-18 16:35:43 -0700401 float insetL = winCrop.left * xScale;
402 float insetT = winCrop.top * yScale;
403 float insetR = (winWidth - winCrop.right ) * xScale;
404 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800405
406 crop.left += insetL;
407 crop.top += insetT;
408 crop.right -= insetR;
409 crop.bottom -= insetB;
410 }
411 return crop;
412}
413
Mathias Agopian4fec8732012-06-29 14:12:52 -0700414void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700415 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700416 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700417{
Mathias Agopian13127d82013-03-05 17:47:11 -0800418 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700419
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700420 // enable this layer
421 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700422
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700423 if (isSecure() && !hw->isSecure()) {
424 layer.setSkip(true);
425 }
426
Mathias Agopian13127d82013-03-05 17:47:11 -0800427 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700428 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800429 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800430 layer.setBlending(mPremultipliedAlpha ?
431 HWC_BLENDING_PREMULT :
432 HWC_BLENDING_COVERAGE);
433 }
434
435 // apply the layer's transform, followed by the display's global transform
436 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700437 Region activeTransparentRegion(s.activeTransparentRegion);
438 if (!s.active.crop.isEmpty()) {
439 Rect activeCrop(s.active.crop);
440 activeCrop = s.transform.transform(activeCrop);
441 activeCrop.intersect(hw->getViewport(), &activeCrop);
442 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800443 // This needs to be here as transform.transform(Rect) computes the
444 // transformed rect and then takes the bounding box of the result before
445 // returning. This means
446 // transform.inverse().transform(transform.transform(Rect)) != Rect
447 // in which case we need to make sure the final rect is clipped to the
448 // display bounds.
449 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700450 // mark regions outside the crop as transparent
451 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
452 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
453 s.active.w, s.active.h));
454 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
455 activeCrop.left, activeCrop.bottom));
456 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
457 s.active.w, activeCrop.bottom));
458 }
459 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800460 frame.intersect(hw->getViewport(), &frame);
461 const Transform& tr(hw->getTransform());
462 layer.setFrame(tr.transform(frame));
463 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800464 layer.setPlaneAlpha(s.alpha);
465
Mathias Agopian29a367b2011-07-12 14:51:45 -0700466 /*
467 * Transformations are applied in this order:
468 * 1) buffer orientation/flip/mirror
469 * 2) state transformation (window manager)
470 * 3) layer orientation (screen orientation)
471 * (NOTE: the matrices are multiplied in reverse order)
472 */
473
474 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700475 Transform transform(tr * s.transform * bufferOrientation);
476
477 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
478 /*
479 * the code below applies the display's inverse transform to the buffer
480 */
481 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700482 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700483 // calculate the inverse transform
484 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
485 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
486 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700487 // If the transform has been rotated the axis of flip has been swapped
488 // so we need to swap which flip operations we are performing
489 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
490 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
491 if (is_h_flipped != is_v_flipped) {
492 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
493 NATIVE_WINDOW_TRANSFORM_FLIP_H;
494 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700495 }
496 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700497 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700498 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700499
500 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800501 const uint32_t orientation = transform.getOrientation();
502 if (orientation & Transform::ROT_INVALID) {
503 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700504 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700505 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800506 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700507 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700508}
509
Mathias Agopian42977342012-08-05 00:40:46 -0700510void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700511 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800512 // we have to set the visible region on every frame because
513 // we currently free it during onLayerDisplayed(), which is called
514 // after HWComposer::commit() -- every frame.
515 // Apply this display's projection's viewport to the visible region
516 // before giving it to the HWC HAL.
517 const Transform& tr = hw->getTransform();
518 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
519 layer.setVisibleRegionScreen(visible);
520
Dan Stozaee44edd2015-03-23 15:50:23 -0700521 // Pass full-surface damage down untouched
522 if (surfaceDamageRegion.isRect() &&
523 surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
524 layer.setSurfaceDamage(surfaceDamageRegion);
525 } else {
526 Region surfaceDamage =
527 tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
528 layer.setSurfaceDamage(surfaceDamage);
529 }
530
Jesse Hall399184a2014-03-03 15:42:54 -0800531 if (mSidebandStream.get()) {
532 layer.setSidebandStream(mSidebandStream);
533 } else {
534 // NOTE: buffer can be NULL if the client never drew into this
535 // layer yet, or if we ran out of memory
536 layer.setBuffer(mActiveBuffer);
537 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700538}
Jesse Halldc5b4852012-06-29 15:21:18 -0700539
Dan Stozac7014012014-02-14 15:03:43 -0800540void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700541 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700542 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700543
544 // TODO: there is a possible optimization here: we only need to set the
545 // acquire fence the first time a new buffer is acquired on EACH display.
546
Riley Andrews03414a12014-07-01 14:22:59 -0700547 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800548 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800549 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700550 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700551 if (fenceFd == -1) {
552 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
553 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700554 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700555 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700556 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700557}
558
Riley Andrews03414a12014-07-01 14:22:59 -0700559Rect Layer::getPosition(
560 const sp<const DisplayDevice>& hw)
561{
562 // this gives us only the "orientation" component of the transform
563 const State& s(getCurrentState());
564
565 // apply the layer's transform, followed by the display's global transform
566 // here we're guaranteed that the layer's transform preserves rects
567 Rect win(s.active.w, s.active.h);
568 if (!s.active.crop.isEmpty()) {
569 win.intersect(s.active.crop, &win);
570 }
571 // subtract the transparent region and snap to the bounds
572 Rect bounds = reduce(win, s.activeTransparentRegion);
573 Rect frame(s.transform.transform(bounds));
574 frame.intersect(hw->getViewport(), &frame);
575 const Transform& tr(hw->getTransform());
576 return Rect(tr.transform(frame));
577}
578
Mathias Agopian13127d82013-03-05 17:47:11 -0800579// ---------------------------------------------------------------------------
580// drawing...
581// ---------------------------------------------------------------------------
582
583void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800584 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800585}
586
Dan Stozac7014012014-02-14 15:03:43 -0800587void Layer::draw(const sp<const DisplayDevice>& hw,
588 bool useIdentityTransform) const {
589 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800590}
591
Dan Stozac7014012014-02-14 15:03:43 -0800592void Layer::draw(const sp<const DisplayDevice>& hw) const {
593 onDraw(hw, Region(hw->bounds()), false);
594}
595
596void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
597 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800598{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800599 ATRACE_CALL();
600
Mathias Agopiana67932f2011-04-20 14:20:59 -0700601 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800602 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700603 // in fact never been drawn into. This happens frequently with
604 // SurfaceView because the WindowManager can't know when the client
605 // has drawn the first time.
606
607 // If there is nothing under us, we paint the screen in black, otherwise
608 // we just skip this update.
609
610 // figure out if there is something below us
611 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700612 const SurfaceFlinger::LayerVector& drawingLayers(
613 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700614 const size_t count = drawingLayers.size();
615 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800616 const sp<Layer>& layer(drawingLayers[i]);
617 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700618 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700619 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700620 }
621 // if not everything below us is covered, we plug the holes!
622 Region holes(clip.subtract(under));
623 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700624 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700625 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800626 return;
627 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700628
Andy McFadden97eba892012-12-11 15:21:45 -0800629 // Bind the current buffer to the GL texture, and wait for it to be
630 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800631 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
632 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800633 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700634 // Go ahead and draw the buffer anyway; no matter what we do the screen
635 // is probably going to have something visibly wrong.
636 }
637
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700638 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
639
Mathias Agopian875d8e12013-06-07 15:35:48 -0700640 RenderEngine& engine(mFlinger->getRenderEngine());
641
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700642 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700643 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700644 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700645
646 // Query the texture matrix given our current filtering mode.
647 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800648 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
649 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700650
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700651 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
652
653 /*
654 * the code below applies the display's inverse transform to the texture transform
655 */
656
657 // create a 4x4 transform matrix from the display transform flags
658 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
659 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
660 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
661
662 mat4 tr;
663 uint32_t transform = hw->getOrientationTransform();
664 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
665 tr = tr * rot90;
666 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
667 tr = tr * flipH;
668 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
669 tr = tr * flipV;
670
671 // calculate the inverse
672 tr = inverse(tr);
673
674 // and finally apply it to the original texture matrix
675 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
676 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
677 }
678
Jamie Genniscbb1a952012-05-08 17:05:52 -0700679 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700680 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
681 mTexture.setFiltering(useFiltering);
682 mTexture.setMatrix(textureMatrix);
683
684 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700685 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700686 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700687 }
Dan Stozac7014012014-02-14 15:03:43 -0800688 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700689 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800690}
691
Mathias Agopian13127d82013-03-05 17:47:11 -0800692
Dan Stozac7014012014-02-14 15:03:43 -0800693void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
694 const Region& /* clip */, float red, float green, float blue,
695 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800696{
Mathias Agopian19733a32013-08-28 18:13:56 -0700697 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800698 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700699 engine.setupFillWithColor(red, green, blue, alpha);
700 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800701}
702
703void Layer::clearWithOpenGL(
704 const sp<const DisplayDevice>& hw, const Region& clip) const {
705 clearWithOpenGL(hw, clip, 0,0,0,0);
706}
707
Dan Stozac7014012014-02-14 15:03:43 -0800708void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
709 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700710 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800711
Dan Stozac7014012014-02-14 15:03:43 -0800712 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800713
Mathias Agopian13127d82013-03-05 17:47:11 -0800714 /*
715 * NOTE: the way we compute the texture coordinates here produces
716 * different results than when we take the HWC path -- in the later case
717 * the "source crop" is rounded to texel boundaries.
718 * This can produce significantly different results when the texture
719 * is scaled by a large amount.
720 *
721 * The GL code below is more logical (imho), and the difference with
722 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700723 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800724 * GL composition when a buffer scaling is applied (maybe with some
725 * minimal value)? Or, we could make GL behave like HWC -- but this feel
726 * like more of a hack.
727 */
728 const Rect win(computeBounds());
729
Mathias Agopian3f844832013-08-07 21:24:32 -0700730 float left = float(win.left) / float(s.active.w);
731 float top = float(win.top) / float(s.active.h);
732 float right = float(win.right) / float(s.active.w);
733 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800734
Mathias Agopian875d8e12013-06-07 15:35:48 -0700735 // TODO: we probably want to generate the texture coords with the mesh
736 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700737 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
738 texCoords[0] = vec2(left, 1.0f - top);
739 texCoords[1] = vec2(left, 1.0f - bottom);
740 texCoords[2] = vec2(right, 1.0f - bottom);
741 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800742
Mathias Agopian875d8e12013-06-07 15:35:48 -0700743 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800744 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700745 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700746 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800747}
748
Ruben Brunk1681d952014-06-27 15:51:55 -0700749uint32_t Layer::getProducerStickyTransform() const {
750 int producerStickyTransform = 0;
751 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
752 if (ret != OK) {
753 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
754 strerror(-ret), ret);
755 return 0;
756 }
757 return static_cast<uint32_t>(producerStickyTransform);
758}
759
Mathias Agopian13127d82013-03-05 17:47:11 -0800760void Layer::setFiltering(bool filtering) {
761 mFiltering = filtering;
762}
763
764bool Layer::getFiltering() const {
765 return mFiltering;
766}
767
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800768// As documented in libhardware header, formats in the range
769// 0x100 - 0x1FF are specific to the HAL implementation, and
770// are known to have no alpha channel
771// TODO: move definition for device-specific range into
772// hardware.h, instead of using hard-coded values here.
773#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
774
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700775bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700776 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
777 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800778 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700779 switch (format) {
780 case HAL_PIXEL_FORMAT_RGBA_8888:
781 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700782 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700783 }
784 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700785 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800786}
787
Mathias Agopian13127d82013-03-05 17:47:11 -0800788// ----------------------------------------------------------------------------
789// local state
790// ----------------------------------------------------------------------------
791
Dan Stozac7014012014-02-14 15:03:43 -0800792void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
793 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800794{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700795 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800796 const Transform tr(useIdentityTransform ?
797 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800798 const uint32_t hw_h = hw->getHeight();
799 Rect win(s.active.w, s.active.h);
800 if (!s.active.crop.isEmpty()) {
801 win.intersect(s.active.crop, &win);
802 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700803 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700804 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700805
Mathias Agopianff2ed702013-09-01 21:36:12 -0700806 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
807 position[0] = tr.transform(win.left, win.top);
808 position[1] = tr.transform(win.left, win.bottom);
809 position[2] = tr.transform(win.right, win.bottom);
810 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700811 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700812 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800813 }
814}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800815
Andy McFadden4125a4f2014-01-29 17:17:11 -0800816bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700817{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700818 // if we don't have a buffer yet, we're translucent regardless of the
819 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700820 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700821 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700822 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700823
824 // if the layer has the opaque flag, then we're always opaque,
825 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800826 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700827}
828
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800829bool Layer::isProtected() const
830{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700831 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800832 return (activeBuffer != 0) &&
833 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
834}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700835
Mathias Agopian13127d82013-03-05 17:47:11 -0800836bool Layer::isFixedSize() const {
837 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
838}
839
840bool Layer::isCropped() const {
841 return !mCurrentCrop.isEmpty();
842}
843
844bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
845 return mNeedsFiltering || hw->needsFiltering();
846}
847
848void Layer::setVisibleRegion(const Region& visibleRegion) {
849 // always called from main thread
850 this->visibleRegion = visibleRegion;
851}
852
853void Layer::setCoveredRegion(const Region& coveredRegion) {
854 // always called from main thread
855 this->coveredRegion = coveredRegion;
856}
857
858void Layer::setVisibleNonTransparentRegion(const Region&
859 setVisibleNonTransparentRegion) {
860 // always called from main thread
861 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
862}
863
864// ----------------------------------------------------------------------------
865// transaction
866// ----------------------------------------------------------------------------
867
868uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800869 ATRACE_CALL();
870
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700871 const Layer::State& s(getDrawingState());
872 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800873
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700874 const bool sizeChanged = (c.requested.w != s.requested.w) ||
875 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700876
877 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700878 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000879 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700880 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700881 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
882 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
883 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
884 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700885 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
886 c.active.w, c.active.h,
887 c.active.crop.left,
888 c.active.crop.top,
889 c.active.crop.right,
890 c.active.crop.bottom,
891 c.active.crop.getWidth(),
892 c.active.crop.getHeight(),
893 c.requested.w, c.requested.h,
894 c.requested.crop.left,
895 c.requested.crop.top,
896 c.requested.crop.right,
897 c.requested.crop.bottom,
898 c.requested.crop.getWidth(),
899 c.requested.crop.getHeight(),
900 s.active.w, s.active.h,
901 s.active.crop.left,
902 s.active.crop.top,
903 s.active.crop.right,
904 s.active.crop.bottom,
905 s.active.crop.getWidth(),
906 s.active.crop.getHeight(),
907 s.requested.w, s.requested.h,
908 s.requested.crop.left,
909 s.requested.crop.top,
910 s.requested.crop.right,
911 s.requested.crop.bottom,
912 s.requested.crop.getWidth(),
913 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800914
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700915 // record the new size, form this point on, when the client request
916 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800917 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700918 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800919 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700920
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700921 if (!isFixedSize()) {
922
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700923 const bool resizePending = (c.requested.w != c.active.w) ||
924 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700925
Dan Stoza9e9b0442015-04-22 14:59:08 -0700926 if (resizePending && mSidebandStream == NULL) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800927 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700928 // if we have a pending resize, unless we are in fixed-size mode.
929 // the drawing state will be updated only once we receive a buffer
930 // with the correct size.
931 //
932 // in particular, we want to make sure the clip (which is part
933 // of the geometry state) is latched together with the size but is
934 // latched immediately when no resizing is involved.
Dan Stoza9e9b0442015-04-22 14:59:08 -0700935 //
936 // If a sideband stream is attached, however, we want to skip this
937 // optimization so that transactions aren't missed when a buffer
938 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700939
940 flags |= eDontUpdateGeometryState;
941 }
942 }
943
Mathias Agopian13127d82013-03-05 17:47:11 -0800944 // always set active to requested, unless we're asked not to
945 // this is used by Layer, which special cases resizes.
946 if (flags & eDontUpdateGeometryState) {
947 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700948 Layer::State& editCurrentState(getCurrentState());
949 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800950 }
951
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700952 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800953 // invalidate and recompute the visible regions if needed
954 flags |= Layer::eVisibleRegion;
955 }
956
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700957 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800958 // invalidate and recompute the visible regions if needed
959 flags |= eVisibleRegion;
960 this->contentDirty = true;
961
962 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700963 const uint8_t type = c.transform.getType();
964 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800965 (type >= Transform::SCALE));
966 }
967
968 // Commit the transaction
969 commitTransaction();
970 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800971}
972
Mathias Agopian13127d82013-03-05 17:47:11 -0800973void Layer::commitTransaction() {
974 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700975}
976
Mathias Agopian13127d82013-03-05 17:47:11 -0800977uint32_t Layer::getTransactionFlags(uint32_t flags) {
978 return android_atomic_and(~flags, &mTransactionFlags) & flags;
979}
980
981uint32_t Layer::setTransactionFlags(uint32_t flags) {
982 return android_atomic_or(flags, &mTransactionFlags);
983}
984
985bool Layer::setPosition(float x, float y) {
986 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
987 return false;
988 mCurrentState.sequence++;
989 mCurrentState.transform.set(x, y);
990 setTransactionFlags(eTransactionNeeded);
991 return true;
992}
993bool Layer::setLayer(uint32_t z) {
994 if (mCurrentState.z == z)
995 return false;
996 mCurrentState.sequence++;
997 mCurrentState.z = z;
998 setTransactionFlags(eTransactionNeeded);
999 return true;
1000}
1001bool Layer::setSize(uint32_t w, uint32_t h) {
1002 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1003 return false;
1004 mCurrentState.requested.w = w;
1005 mCurrentState.requested.h = h;
1006 setTransactionFlags(eTransactionNeeded);
1007 return true;
1008}
1009bool Layer::setAlpha(uint8_t alpha) {
1010 if (mCurrentState.alpha == alpha)
1011 return false;
1012 mCurrentState.sequence++;
1013 mCurrentState.alpha = alpha;
1014 setTransactionFlags(eTransactionNeeded);
1015 return true;
1016}
1017bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1018 mCurrentState.sequence++;
1019 mCurrentState.transform.set(
1020 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1021 setTransactionFlags(eTransactionNeeded);
1022 return true;
1023}
1024bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001025 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001026 setTransactionFlags(eTransactionNeeded);
1027 return true;
1028}
1029bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1030 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1031 if (mCurrentState.flags == newFlags)
1032 return false;
1033 mCurrentState.sequence++;
1034 mCurrentState.flags = newFlags;
1035 setTransactionFlags(eTransactionNeeded);
1036 return true;
1037}
1038bool Layer::setCrop(const Rect& crop) {
1039 if (mCurrentState.requested.crop == crop)
1040 return false;
1041 mCurrentState.sequence++;
1042 mCurrentState.requested.crop = crop;
1043 setTransactionFlags(eTransactionNeeded);
1044 return true;
1045}
1046
1047bool Layer::setLayerStack(uint32_t layerStack) {
1048 if (mCurrentState.layerStack == layerStack)
1049 return false;
1050 mCurrentState.sequence++;
1051 mCurrentState.layerStack = layerStack;
1052 setTransactionFlags(eTransactionNeeded);
1053 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001054}
1055
Dan Stozaee44edd2015-03-23 15:50:23 -07001056void Layer::useSurfaceDamage() {
1057 if (mFlinger->mForceFullDamage) {
1058 surfaceDamageRegion = Region::INVALID_REGION;
1059 } else {
1060 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1061 }
1062}
1063
1064void Layer::useEmptyDamage() {
1065 surfaceDamageRegion.clear();
1066}
1067
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001068// ----------------------------------------------------------------------------
1069// pageflip handling...
1070// ----------------------------------------------------------------------------
1071
Dan Stoza6b9454d2014-11-07 16:00:59 -08001072bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1073 Mutex::Autolock lock(mQueueItemLock);
1074 nsecs_t expectedPresent =
1075 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1076 return mQueueItems.empty() ?
1077 false : mQueueItems[0].mTimestamp < expectedPresent;
1078}
1079
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001080bool Layer::onPreComposition() {
1081 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001082 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001083}
1084
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001085void Layer::onPostComposition() {
1086 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001087 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001088 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1089
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001090 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001091 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001092 mFrameTracker.setFrameReadyFence(frameReadyFence);
1093 } else {
1094 // There was no fence for this frame, so assume that it was ready
1095 // to be presented at the desired present time.
1096 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1097 }
1098
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001099 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001100 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001101 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001102 mFrameTracker.setActualPresentFence(presentFence);
1103 } else {
1104 // The HWC doesn't support present fences, so use the refresh
1105 // timestamp instead.
1106 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1107 mFrameTracker.setActualPresentTime(presentTime);
1108 }
1109
1110 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001111 mFrameLatencyNeeded = false;
1112 }
1113}
1114
Mathias Agopianda27af92012-09-13 18:17:13 -07001115bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001116 const Layer::State& s(mDrawingState);
1117 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001118 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001119}
1120
Mathias Agopian4fec8732012-06-29 14:12:52 -07001121Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001122{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001123 ATRACE_CALL();
1124
Jesse Hall399184a2014-03-03 15:42:54 -08001125 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1126 // mSidebandStreamChanged was true
1127 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001128 recomputeVisibleRegions = true;
1129
1130 const State& s(getDrawingState());
1131 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001132 }
1133
Mathias Agopian4fec8732012-06-29 14:12:52 -07001134 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001135 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001136
1137 // if we've already called updateTexImage() without going through
1138 // a composition step, we have to skip this layer at this point
1139 // because we cannot call updateTeximage() without a corresponding
1140 // compositionComplete() call.
1141 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001142 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001143 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001144 }
1145
Jamie Gennis351a5132011-09-14 18:23:37 -07001146 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001147 const State& s(getDrawingState());
1148 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001149 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001150
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001151 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001152 Layer::State& front;
1153 Layer::State& current;
1154 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001155 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001156 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001157 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001158 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001159 recomputeVisibleRegions(recomputeVisibleRegions),
1160 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001161 }
1162
1163 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001164 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001165 if (buf == NULL) {
1166 return false;
1167 }
1168
1169 uint32_t bufWidth = buf->getWidth();
1170 uint32_t bufHeight = buf->getHeight();
1171
1172 // check that we received a buffer of the right size
1173 // (Take the buffer's orientation into account)
1174 if (item.mTransform & Transform::ROT_90) {
1175 swap(bufWidth, bufHeight);
1176 }
1177
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001178 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1179 if (front.active != front.requested) {
1180
1181 if (isFixedSize ||
1182 (bufWidth == front.requested.w &&
1183 bufHeight == front.requested.h))
1184 {
1185 // Here we pretend the transaction happened by updating the
1186 // current and drawing states. Drawing state is only accessed
1187 // in this thread, no need to have it locked
1188 front.active = front.requested;
1189
1190 // We also need to update the current state so that
1191 // we don't end-up overwriting the drawing state with
1192 // this stale current state during the next transaction
1193 //
1194 // NOTE: We don't need to hold the transaction lock here
1195 // because State::active is only accessed from this thread.
1196 current.active = front.active;
1197
1198 // recompute visible region
1199 recomputeVisibleRegions = true;
1200 }
1201
1202 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001203 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001204 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1205 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001206 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001207 front.active.w, front.active.h,
1208 front.active.crop.left,
1209 front.active.crop.top,
1210 front.active.crop.right,
1211 front.active.crop.bottom,
1212 front.active.crop.getWidth(),
1213 front.active.crop.getHeight(),
1214 front.requested.w, front.requested.h,
1215 front.requested.crop.left,
1216 front.requested.crop.top,
1217 front.requested.crop.right,
1218 front.requested.crop.bottom,
1219 front.requested.crop.getWidth(),
1220 front.requested.crop.getHeight());
1221 }
1222
Ruben Brunk1681d952014-06-27 15:51:55 -07001223 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001224 if (front.active.w != bufWidth ||
1225 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001226 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001227 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1228 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001229 return true;
1230 }
1231 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001232
1233 // if the transparent region has changed (this test is
1234 // conservative, but that's fine, worst case we're doing
1235 // a bit of extra work), we latch the new one and we
1236 // trigger a visible-region recompute.
1237 if (!front.activeTransparentRegion.isTriviallyEqual(
1238 front.requestedTransparentRegion)) {
1239 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001240
1241 // We also need to update the current state so that
1242 // we don't end-up overwriting the drawing state with
1243 // this stale current state during the next transaction
1244 //
1245 // NOTE: We don't need to hold the transaction lock here
1246 // because State::active is only accessed from this thread.
1247 current.activeTransparentRegion = front.activeTransparentRegion;
1248
1249 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001250 recomputeVisibleRegions = true;
1251 }
1252
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001253 return false;
1254 }
1255 };
1256
Ruben Brunk1681d952014-06-27 15:51:55 -07001257 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1258 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001259
Andy McFadden41d67d72014-04-25 16:58:34 -07001260 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1261 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001262 if (updateResult == BufferQueue::PRESENT_LATER) {
1263 // Producer doesn't want buffer to be displayed yet. Signal a
1264 // layer update so we check again at the next opportunity.
1265 mFlinger->signalLayerUpdate();
1266 return outDirtyRegion;
Dan Stozaecc50402015-04-28 14:42:06 -07001267 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1268 // If the buffer has been rejected, remove it from the shadow queue
1269 // and return early
1270 Mutex::Autolock lock(mQueueItemLock);
1271
1272 // Update the BufferQueue with the new shadow queue size after
1273 // dropping this item
1274 mQueueItems.removeAt(0);
1275 mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
1276
1277 android_atomic_dec(&mQueuedFrames);
1278 return outDirtyRegion;
Andy McFadden1585c4d2013-06-28 13:52:40 -07001279 }
1280
Dan Stoza6b9454d2014-11-07 16:00:59 -08001281 { // Autolock scope
Dan Stozaecc50402015-04-28 14:42:06 -07001282 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1283
Dan Stoza6b9454d2014-11-07 16:00:59 -08001284 Mutex::Autolock lock(mQueueItemLock);
Dan Stozaecc50402015-04-28 14:42:06 -07001285
1286 // Remove any stale buffers that have been dropped during
1287 // updateTexImage
1288 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1289 mQueueItems.removeAt(0);
1290 android_atomic_dec(&mQueuedFrames);
1291 }
1292
1293 // Update the BufferQueue with our new shadow queue size, since we
1294 // have removed at least one item
Dan Stoza6b9454d2014-11-07 16:00:59 -08001295 mQueueItems.removeAt(0);
Dan Stozaecc50402015-04-28 14:42:06 -07001296 mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
Dan Stoza6b9454d2014-11-07 16:00:59 -08001297 }
1298
Dan Stozaecc50402015-04-28 14:42:06 -07001299
Andy McFadden1585c4d2013-06-28 13:52:40 -07001300 // Decrement the queued-frames count. Signal another event if we
1301 // have more frames pending.
1302 if (android_atomic_dec(&mQueuedFrames) > 1) {
1303 mFlinger->signalLayerUpdate();
1304 }
1305
1306 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001307 // something happened!
1308 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001309 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001310 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001311
Jamie Gennis351a5132011-09-14 18:23:37 -07001312 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001313 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001314 if (mActiveBuffer == NULL) {
1315 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001316 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001317 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001318
Mathias Agopian4824d402012-06-04 18:16:30 -07001319 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001320 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001321 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001322 // the first time we receive a buffer, we need to trigger a
1323 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001324 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001325 }
1326
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001327 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1328 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1329 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001330 if ((crop != mCurrentCrop) ||
1331 (transform != mCurrentTransform) ||
1332 (scalingMode != mCurrentScalingMode))
1333 {
1334 mCurrentCrop = crop;
1335 mCurrentTransform = transform;
1336 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001337 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001338 }
1339
1340 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001341 uint32_t bufWidth = mActiveBuffer->getWidth();
1342 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001343 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1344 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001345 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001346 }
1347 }
1348
1349 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001350 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001351 recomputeVisibleRegions = true;
1352 }
1353
Mathias Agopian4fec8732012-06-29 14:12:52 -07001354 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001355 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001356
1357 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001358 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001359 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001360 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001361}
1362
Mathias Agopiana67932f2011-04-20 14:20:59 -07001363uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001364{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001365 // TODO: should we do something special if mSecure is set?
1366 if (mProtectedByApp) {
1367 // need a hardware-protected path to external video sink
1368 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001369 }
Riley Andrews03414a12014-07-01 14:22:59 -07001370 if (mPotentialCursor) {
1371 usage |= GraphicBuffer::USAGE_CURSOR;
1372 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001373 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001374 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001375}
1376
Mathias Agopian84300952012-11-21 16:02:13 -08001377void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001378 uint32_t orientation = 0;
1379 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001380 // The transform hint is used to improve performance, but we can
1381 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001382 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001383 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001384 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001385 if (orientation & Transform::ROT_INVALID) {
1386 orientation = 0;
1387 }
1388 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001389 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001390}
1391
Mathias Agopian13127d82013-03-05 17:47:11 -08001392// ----------------------------------------------------------------------------
1393// debugging
1394// ----------------------------------------------------------------------------
1395
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001396void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001397{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001398 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001399
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001400 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001401 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001402 "+ %s %p (%s)\n",
1403 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001404 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001405
Mathias Agopian2ca79392013-04-02 18:30:32 -07001406 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001407 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001408 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001409 sp<Client> client(mClientRef.promote());
1410
Mathias Agopian74d211a2013-04-22 16:55:35 +02001411 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001412 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1413 "isOpaque=%1d, invalidate=%1d, "
1414 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1415 " client=%p\n",
1416 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1417 s.active.crop.left, s.active.crop.top,
1418 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001419 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001420 s.alpha, s.flags,
1421 s.transform[0][0], s.transform[0][1],
1422 s.transform[1][0], s.transform[1][1],
1423 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001424
1425 sp<const GraphicBuffer> buf0(mActiveBuffer);
1426 uint32_t w0=0, h0=0, s0=0, f0=0;
1427 if (buf0 != 0) {
1428 w0 = buf0->getWidth();
1429 h0 = buf0->getHeight();
1430 s0 = buf0->getStride();
1431 f0 = buf0->format;
1432 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001433 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001434 " "
1435 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1436 " queued-frames=%d, mRefreshPending=%d\n",
1437 mFormat, w0, h0, s0,f0,
1438 mQueuedFrames, mRefreshPending);
1439
Mathias Agopian13127d82013-03-05 17:47:11 -08001440 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001441 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001442 }
1443}
1444
Svetoslavd85084b2014-03-20 10:28:31 -07001445void Layer::dumpFrameStats(String8& result) const {
1446 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001447}
1448
Svetoslavd85084b2014-03-20 10:28:31 -07001449void Layer::clearFrameStats() {
1450 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001451}
1452
Jamie Gennis6547ff42013-07-16 20:12:42 -07001453void Layer::logFrameStats() {
1454 mFrameTracker.logAndResetStats(mName);
1455}
1456
Svetoslavd85084b2014-03-20 10:28:31 -07001457void Layer::getFrameStats(FrameStats* outStats) const {
1458 mFrameTracker.getStats(outStats);
1459}
1460
Mathias Agopian13127d82013-03-05 17:47:11 -08001461// ---------------------------------------------------------------------------
1462
1463Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1464 const sp<Layer>& layer)
1465 : mFlinger(flinger), mLayer(layer) {
1466}
1467
1468Layer::LayerCleaner::~LayerCleaner() {
1469 // destroy client resources
1470 mFlinger->onLayerDestroyed(mLayer);
1471}
1472
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001473// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001474}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001475
1476#if defined(__gl_h_)
1477#error "don't include gl/gl.h in this file"
1478#endif
1479
1480#if defined(__gl2_h_)
1481#error "don't include gl2/gl2.h in this file"
1482#endif