blob: 2944c63233c83b2f8de64ee8945be216ee71ee0a [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
Dan Stoza9e9b0442015-04-22 14:59:08 -0700921 if (resizePending && mSidebandStream == NULL) {
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.
Dan Stoza9e9b0442015-04-22 14:59:08 -0700930 //
931 // If a sideband stream is attached, however, we want to skip this
932 // optimization so that transactions aren't missed when a buffer
933 // never arrives
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700934
935 flags |= eDontUpdateGeometryState;
936 }
937 }
938
Mathias Agopian13127d82013-03-05 17:47:11 -0800939 // always set active to requested, unless we're asked not to
940 // this is used by Layer, which special cases resizes.
941 if (flags & eDontUpdateGeometryState) {
942 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700943 Layer::State& editCurrentState(getCurrentState());
944 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800945 }
946
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700947 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800948 // invalidate and recompute the visible regions if needed
949 flags |= Layer::eVisibleRegion;
950 }
951
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700952 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800953 // invalidate and recompute the visible regions if needed
954 flags |= eVisibleRegion;
955 this->contentDirty = true;
956
957 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700958 const uint8_t type = c.transform.getType();
959 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800960 (type >= Transform::SCALE));
961 }
962
963 // Commit the transaction
964 commitTransaction();
965 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800966}
967
Mathias Agopian13127d82013-03-05 17:47:11 -0800968void Layer::commitTransaction() {
969 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700970}
971
Mathias Agopian13127d82013-03-05 17:47:11 -0800972uint32_t Layer::getTransactionFlags(uint32_t flags) {
973 return android_atomic_and(~flags, &mTransactionFlags) & flags;
974}
975
976uint32_t Layer::setTransactionFlags(uint32_t flags) {
977 return android_atomic_or(flags, &mTransactionFlags);
978}
979
980bool Layer::setPosition(float x, float y) {
981 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
982 return false;
983 mCurrentState.sequence++;
984 mCurrentState.transform.set(x, y);
985 setTransactionFlags(eTransactionNeeded);
986 return true;
987}
988bool Layer::setLayer(uint32_t z) {
989 if (mCurrentState.z == z)
990 return false;
991 mCurrentState.sequence++;
992 mCurrentState.z = z;
993 setTransactionFlags(eTransactionNeeded);
994 return true;
995}
996bool Layer::setSize(uint32_t w, uint32_t h) {
997 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
998 return false;
999 mCurrentState.requested.w = w;
1000 mCurrentState.requested.h = h;
1001 setTransactionFlags(eTransactionNeeded);
1002 return true;
1003}
1004bool Layer::setAlpha(uint8_t alpha) {
1005 if (mCurrentState.alpha == alpha)
1006 return false;
1007 mCurrentState.sequence++;
1008 mCurrentState.alpha = alpha;
1009 setTransactionFlags(eTransactionNeeded);
1010 return true;
1011}
1012bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1013 mCurrentState.sequence++;
1014 mCurrentState.transform.set(
1015 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1016 setTransactionFlags(eTransactionNeeded);
1017 return true;
1018}
1019bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001020 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001021 setTransactionFlags(eTransactionNeeded);
1022 return true;
1023}
1024bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1025 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1026 if (mCurrentState.flags == newFlags)
1027 return false;
1028 mCurrentState.sequence++;
1029 mCurrentState.flags = newFlags;
1030 setTransactionFlags(eTransactionNeeded);
1031 return true;
1032}
1033bool Layer::setCrop(const Rect& crop) {
1034 if (mCurrentState.requested.crop == crop)
1035 return false;
1036 mCurrentState.sequence++;
1037 mCurrentState.requested.crop = crop;
1038 setTransactionFlags(eTransactionNeeded);
1039 return true;
1040}
1041
1042bool Layer::setLayerStack(uint32_t layerStack) {
1043 if (mCurrentState.layerStack == layerStack)
1044 return false;
1045 mCurrentState.sequence++;
1046 mCurrentState.layerStack = layerStack;
1047 setTransactionFlags(eTransactionNeeded);
1048 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001049}
1050
Dan Stozaee44edd2015-03-23 15:50:23 -07001051void Layer::useSurfaceDamage() {
1052 if (mFlinger->mForceFullDamage) {
1053 surfaceDamageRegion = Region::INVALID_REGION;
1054 } else {
1055 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1056 }
1057}
1058
1059void Layer::useEmptyDamage() {
1060 surfaceDamageRegion.clear();
1061}
1062
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001063// ----------------------------------------------------------------------------
1064// pageflip handling...
1065// ----------------------------------------------------------------------------
1066
Dan Stoza6b9454d2014-11-07 16:00:59 -08001067bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1068 Mutex::Autolock lock(mQueueItemLock);
1069 nsecs_t expectedPresent =
1070 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1071 return mQueueItems.empty() ?
1072 false : mQueueItems[0].mTimestamp < expectedPresent;
1073}
1074
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001075bool Layer::onPreComposition() {
1076 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001077 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001078}
1079
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001080void Layer::onPostComposition() {
1081 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001082 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001083 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1084
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001085 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001086 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001087 mFrameTracker.setFrameReadyFence(frameReadyFence);
1088 } else {
1089 // There was no fence for this frame, so assume that it was ready
1090 // to be presented at the desired present time.
1091 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1092 }
1093
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001094 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001095 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001096 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001097 mFrameTracker.setActualPresentFence(presentFence);
1098 } else {
1099 // The HWC doesn't support present fences, so use the refresh
1100 // timestamp instead.
1101 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1102 mFrameTracker.setActualPresentTime(presentTime);
1103 }
1104
1105 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001106 mFrameLatencyNeeded = false;
1107 }
1108}
1109
Mathias Agopianda27af92012-09-13 18:17:13 -07001110bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001111 const Layer::State& s(mDrawingState);
1112 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001113 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001114}
1115
Mathias Agopian4fec8732012-06-29 14:12:52 -07001116Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001117{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001118 ATRACE_CALL();
1119
Jesse Hall399184a2014-03-03 15:42:54 -08001120 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1121 // mSidebandStreamChanged was true
1122 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001123 recomputeVisibleRegions = true;
1124
1125 const State& s(getDrawingState());
1126 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001127 }
1128
Mathias Agopian4fec8732012-06-29 14:12:52 -07001129 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001130 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001131
1132 // if we've already called updateTexImage() without going through
1133 // a composition step, we have to skip this layer at this point
1134 // because we cannot call updateTeximage() without a corresponding
1135 // compositionComplete() call.
1136 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001137 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001138 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001139 }
1140
Jamie Gennis351a5132011-09-14 18:23:37 -07001141 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001142 const State& s(getDrawingState());
1143 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001144 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001145
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001146 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001147 Layer::State& front;
1148 Layer::State& current;
1149 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001150 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001151 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001152 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001153 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001154 recomputeVisibleRegions(recomputeVisibleRegions),
1155 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001156 }
1157
1158 virtual bool reject(const sp<GraphicBuffer>& buf,
Dan Stoza11611f92015-03-12 15:12:44 -07001159 const BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001160 if (buf == NULL) {
1161 return false;
1162 }
1163
1164 uint32_t bufWidth = buf->getWidth();
1165 uint32_t bufHeight = buf->getHeight();
1166
1167 // check that we received a buffer of the right size
1168 // (Take the buffer's orientation into account)
1169 if (item.mTransform & Transform::ROT_90) {
1170 swap(bufWidth, bufHeight);
1171 }
1172
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001173 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1174 if (front.active != front.requested) {
1175
1176 if (isFixedSize ||
1177 (bufWidth == front.requested.w &&
1178 bufHeight == front.requested.h))
1179 {
1180 // Here we pretend the transaction happened by updating the
1181 // current and drawing states. Drawing state is only accessed
1182 // in this thread, no need to have it locked
1183 front.active = front.requested;
1184
1185 // We also need to update the current state so that
1186 // we don't end-up overwriting the drawing state with
1187 // this stale current state during the next transaction
1188 //
1189 // NOTE: We don't need to hold the transaction lock here
1190 // because State::active is only accessed from this thread.
1191 current.active = front.active;
1192
1193 // recompute visible region
1194 recomputeVisibleRegions = true;
1195 }
1196
1197 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001198 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001199 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1200 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001201 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001202 front.active.w, front.active.h,
1203 front.active.crop.left,
1204 front.active.crop.top,
1205 front.active.crop.right,
1206 front.active.crop.bottom,
1207 front.active.crop.getWidth(),
1208 front.active.crop.getHeight(),
1209 front.requested.w, front.requested.h,
1210 front.requested.crop.left,
1211 front.requested.crop.top,
1212 front.requested.crop.right,
1213 front.requested.crop.bottom,
1214 front.requested.crop.getWidth(),
1215 front.requested.crop.getHeight());
1216 }
1217
Ruben Brunk1681d952014-06-27 15:51:55 -07001218 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001219 if (front.active.w != bufWidth ||
1220 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001221 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001222 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1223 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001224 return true;
1225 }
1226 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001227
1228 // if the transparent region has changed (this test is
1229 // conservative, but that's fine, worst case we're doing
1230 // a bit of extra work), we latch the new one and we
1231 // trigger a visible-region recompute.
1232 if (!front.activeTransparentRegion.isTriviallyEqual(
1233 front.requestedTransparentRegion)) {
1234 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001235
1236 // We also need to update the current state so that
1237 // we don't end-up overwriting the drawing state with
1238 // this stale current state during the next transaction
1239 //
1240 // NOTE: We don't need to hold the transaction lock here
1241 // because State::active is only accessed from this thread.
1242 current.activeTransparentRegion = front.activeTransparentRegion;
1243
1244 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001245 recomputeVisibleRegions = true;
1246 }
1247
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001248 return false;
1249 }
1250 };
1251
Ruben Brunk1681d952014-06-27 15:51:55 -07001252 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1253 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001254
Andy McFadden41d67d72014-04-25 16:58:34 -07001255 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1256 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001257 if (updateResult == BufferQueue::PRESENT_LATER) {
1258 // Producer doesn't want buffer to be displayed yet. Signal a
1259 // layer update so we check again at the next opportunity.
1260 mFlinger->signalLayerUpdate();
1261 return outDirtyRegion;
1262 }
1263
Dan Stoza6b9454d2014-11-07 16:00:59 -08001264 // Remove this buffer from our internal queue tracker
1265 { // Autolock scope
1266 Mutex::Autolock lock(mQueueItemLock);
1267 mQueueItems.removeAt(0);
1268 }
1269
Andy McFadden1585c4d2013-06-28 13:52:40 -07001270 // Decrement the queued-frames count. Signal another event if we
1271 // have more frames pending.
1272 if (android_atomic_dec(&mQueuedFrames) > 1) {
1273 mFlinger->signalLayerUpdate();
1274 }
1275
1276 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001277 // something happened!
1278 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001279 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001280 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001281
Jamie Gennis351a5132011-09-14 18:23:37 -07001282 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001283 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001284 if (mActiveBuffer == NULL) {
1285 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001286 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001287 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001288
Mathias Agopian4824d402012-06-04 18:16:30 -07001289 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001290 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001291 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001292 // the first time we receive a buffer, we need to trigger a
1293 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001294 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001295 }
1296
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001297 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1298 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1299 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001300 if ((crop != mCurrentCrop) ||
1301 (transform != mCurrentTransform) ||
1302 (scalingMode != mCurrentScalingMode))
1303 {
1304 mCurrentCrop = crop;
1305 mCurrentTransform = transform;
1306 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001307 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001308 }
1309
1310 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001311 uint32_t bufWidth = mActiveBuffer->getWidth();
1312 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001313 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1314 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001315 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001316 }
1317 }
1318
1319 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001320 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001321 recomputeVisibleRegions = true;
1322 }
1323
Mathias Agopian4fec8732012-06-29 14:12:52 -07001324 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001325 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001326
1327 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001328 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001329 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001330 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001331}
1332
Mathias Agopiana67932f2011-04-20 14:20:59 -07001333uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001334{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001335 // TODO: should we do something special if mSecure is set?
1336 if (mProtectedByApp) {
1337 // need a hardware-protected path to external video sink
1338 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001339 }
Riley Andrews03414a12014-07-01 14:22:59 -07001340 if (mPotentialCursor) {
1341 usage |= GraphicBuffer::USAGE_CURSOR;
1342 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001343 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001344 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001345}
1346
Mathias Agopian84300952012-11-21 16:02:13 -08001347void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001348 uint32_t orientation = 0;
1349 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001350 // The transform hint is used to improve performance, but we can
1351 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001352 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001353 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001354 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001355 if (orientation & Transform::ROT_INVALID) {
1356 orientation = 0;
1357 }
1358 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001359 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001360}
1361
Mathias Agopian13127d82013-03-05 17:47:11 -08001362// ----------------------------------------------------------------------------
1363// debugging
1364// ----------------------------------------------------------------------------
1365
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001366void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001367{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001368 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001369
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001370 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001371 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001372 "+ %s %p (%s)\n",
1373 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001374 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001375
Mathias Agopian2ca79392013-04-02 18:30:32 -07001376 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001377 visibleRegion.dump(result, "visibleRegion");
Dan Stozaee44edd2015-03-23 15:50:23 -07001378 surfaceDamageRegion.dump(result, "surfaceDamageRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001379 sp<Client> client(mClientRef.promote());
1380
Mathias Agopian74d211a2013-04-22 16:55:35 +02001381 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001382 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1383 "isOpaque=%1d, invalidate=%1d, "
1384 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1385 " client=%p\n",
1386 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1387 s.active.crop.left, s.active.crop.top,
1388 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001389 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001390 s.alpha, s.flags,
1391 s.transform[0][0], s.transform[0][1],
1392 s.transform[1][0], s.transform[1][1],
1393 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001394
1395 sp<const GraphicBuffer> buf0(mActiveBuffer);
1396 uint32_t w0=0, h0=0, s0=0, f0=0;
1397 if (buf0 != 0) {
1398 w0 = buf0->getWidth();
1399 h0 = buf0->getHeight();
1400 s0 = buf0->getStride();
1401 f0 = buf0->format;
1402 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001403 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001404 " "
1405 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1406 " queued-frames=%d, mRefreshPending=%d\n",
1407 mFormat, w0, h0, s0,f0,
1408 mQueuedFrames, mRefreshPending);
1409
Mathias Agopian13127d82013-03-05 17:47:11 -08001410 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001411 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001412 }
1413}
1414
Svetoslavd85084b2014-03-20 10:28:31 -07001415void Layer::dumpFrameStats(String8& result) const {
1416 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001417}
1418
Svetoslavd85084b2014-03-20 10:28:31 -07001419void Layer::clearFrameStats() {
1420 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001421}
1422
Jamie Gennis6547ff42013-07-16 20:12:42 -07001423void Layer::logFrameStats() {
1424 mFrameTracker.logAndResetStats(mName);
1425}
1426
Svetoslavd85084b2014-03-20 10:28:31 -07001427void Layer::getFrameStats(FrameStats* outStats) const {
1428 mFrameTracker.getStats(outStats);
1429}
1430
Mathias Agopian13127d82013-03-05 17:47:11 -08001431// ---------------------------------------------------------------------------
1432
1433Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1434 const sp<Layer>& layer)
1435 : mFlinger(flinger), mLayer(layer) {
1436}
1437
1438Layer::LayerCleaner::~LayerCleaner() {
1439 // destroy client resources
1440 mFlinger->onLayerDestroyed(mLayer);
1441}
1442
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001443// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001444}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001445
1446#if defined(__gl_h_)
1447#error "don't include gl/gl.h in this file"
1448#endif
1449
1450#if defined(__gl2_h_)
1451#error "don't include gl2/gl2.h in this file"
1452#endif