blob: 9da1efd970a77b9232e0278e221ba759676a95a8 [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
Jesse Hall399184a2014-03-03 15:42:54 -0800516 if (mSidebandStream.get()) {
517 layer.setSidebandStream(mSidebandStream);
518 } else {
519 // NOTE: buffer can be NULL if the client never drew into this
520 // layer yet, or if we ran out of memory
521 layer.setBuffer(mActiveBuffer);
522 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700523}
Jesse Halldc5b4852012-06-29 15:21:18 -0700524
Dan Stozac7014012014-02-14 15:03:43 -0800525void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700526 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700527 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700528
529 // TODO: there is a possible optimization here: we only need to set the
530 // acquire fence the first time a new buffer is acquired on EACH display.
531
Riley Andrews03414a12014-07-01 14:22:59 -0700532 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800533 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800534 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700535 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700536 if (fenceFd == -1) {
537 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
538 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700539 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700540 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700541 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700542}
543
Riley Andrews03414a12014-07-01 14:22:59 -0700544Rect Layer::getPosition(
545 const sp<const DisplayDevice>& hw)
546{
547 // this gives us only the "orientation" component of the transform
548 const State& s(getCurrentState());
549
550 // apply the layer's transform, followed by the display's global transform
551 // here we're guaranteed that the layer's transform preserves rects
552 Rect win(s.active.w, s.active.h);
553 if (!s.active.crop.isEmpty()) {
554 win.intersect(s.active.crop, &win);
555 }
556 // subtract the transparent region and snap to the bounds
557 Rect bounds = reduce(win, s.activeTransparentRegion);
558 Rect frame(s.transform.transform(bounds));
559 frame.intersect(hw->getViewport(), &frame);
560 const Transform& tr(hw->getTransform());
561 return Rect(tr.transform(frame));
562}
563
Mathias Agopian13127d82013-03-05 17:47:11 -0800564// ---------------------------------------------------------------------------
565// drawing...
566// ---------------------------------------------------------------------------
567
568void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800569 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800570}
571
Dan Stozac7014012014-02-14 15:03:43 -0800572void Layer::draw(const sp<const DisplayDevice>& hw,
573 bool useIdentityTransform) const {
574 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800575}
576
Dan Stozac7014012014-02-14 15:03:43 -0800577void Layer::draw(const sp<const DisplayDevice>& hw) const {
578 onDraw(hw, Region(hw->bounds()), false);
579}
580
581void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
582 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800583{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800584 ATRACE_CALL();
585
Mathias Agopiana67932f2011-04-20 14:20:59 -0700586 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800587 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700588 // in fact never been drawn into. This happens frequently with
589 // SurfaceView because the WindowManager can't know when the client
590 // has drawn the first time.
591
592 // If there is nothing under us, we paint the screen in black, otherwise
593 // we just skip this update.
594
595 // figure out if there is something below us
596 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700597 const SurfaceFlinger::LayerVector& drawingLayers(
598 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700599 const size_t count = drawingLayers.size();
600 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800601 const sp<Layer>& layer(drawingLayers[i]);
602 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700603 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700604 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700605 }
606 // if not everything below us is covered, we plug the holes!
607 Region holes(clip.subtract(under));
608 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700609 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700610 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800611 return;
612 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700613
Andy McFadden97eba892012-12-11 15:21:45 -0800614 // Bind the current buffer to the GL texture, and wait for it to be
615 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800616 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
617 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800618 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700619 // Go ahead and draw the buffer anyway; no matter what we do the screen
620 // is probably going to have something visibly wrong.
621 }
622
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700623 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
624
Mathias Agopian875d8e12013-06-07 15:35:48 -0700625 RenderEngine& engine(mFlinger->getRenderEngine());
626
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700627 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700628 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700629 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700630
631 // Query the texture matrix given our current filtering mode.
632 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800633 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
634 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700635
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700636 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
637
638 /*
639 * the code below applies the display's inverse transform to the texture transform
640 */
641
642 // create a 4x4 transform matrix from the display transform flags
643 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
644 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
645 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
646
647 mat4 tr;
648 uint32_t transform = hw->getOrientationTransform();
649 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
650 tr = tr * rot90;
651 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
652 tr = tr * flipH;
653 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
654 tr = tr * flipV;
655
656 // calculate the inverse
657 tr = inverse(tr);
658
659 // and finally apply it to the original texture matrix
660 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
661 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
662 }
663
Jamie Genniscbb1a952012-05-08 17:05:52 -0700664 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700665 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
666 mTexture.setFiltering(useFiltering);
667 mTexture.setMatrix(textureMatrix);
668
669 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700670 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700671 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700672 }
Dan Stozac7014012014-02-14 15:03:43 -0800673 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700674 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800675}
676
Mathias Agopian13127d82013-03-05 17:47:11 -0800677
Dan Stozac7014012014-02-14 15:03:43 -0800678void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
679 const Region& /* clip */, float red, float green, float blue,
680 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800681{
Mathias Agopian19733a32013-08-28 18:13:56 -0700682 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800683 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700684 engine.setupFillWithColor(red, green, blue, alpha);
685 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800686}
687
688void Layer::clearWithOpenGL(
689 const sp<const DisplayDevice>& hw, const Region& clip) const {
690 clearWithOpenGL(hw, clip, 0,0,0,0);
691}
692
Dan Stozac7014012014-02-14 15:03:43 -0800693void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
694 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700695 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800696
Dan Stozac7014012014-02-14 15:03:43 -0800697 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800698
Mathias Agopian13127d82013-03-05 17:47:11 -0800699 /*
700 * NOTE: the way we compute the texture coordinates here produces
701 * different results than when we take the HWC path -- in the later case
702 * the "source crop" is rounded to texel boundaries.
703 * This can produce significantly different results when the texture
704 * is scaled by a large amount.
705 *
706 * The GL code below is more logical (imho), and the difference with
707 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700708 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800709 * GL composition when a buffer scaling is applied (maybe with some
710 * minimal value)? Or, we could make GL behave like HWC -- but this feel
711 * like more of a hack.
712 */
713 const Rect win(computeBounds());
714
Mathias Agopian3f844832013-08-07 21:24:32 -0700715 float left = float(win.left) / float(s.active.w);
716 float top = float(win.top) / float(s.active.h);
717 float right = float(win.right) / float(s.active.w);
718 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800719
Mathias Agopian875d8e12013-06-07 15:35:48 -0700720 // TODO: we probably want to generate the texture coords with the mesh
721 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700722 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
723 texCoords[0] = vec2(left, 1.0f - top);
724 texCoords[1] = vec2(left, 1.0f - bottom);
725 texCoords[2] = vec2(right, 1.0f - bottom);
726 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800727
Mathias Agopian875d8e12013-06-07 15:35:48 -0700728 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800729 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700730 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700731 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800732}
733
Ruben Brunk1681d952014-06-27 15:51:55 -0700734uint32_t Layer::getProducerStickyTransform() const {
735 int producerStickyTransform = 0;
736 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
737 if (ret != OK) {
738 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
739 strerror(-ret), ret);
740 return 0;
741 }
742 return static_cast<uint32_t>(producerStickyTransform);
743}
744
Mathias Agopian13127d82013-03-05 17:47:11 -0800745void Layer::setFiltering(bool filtering) {
746 mFiltering = filtering;
747}
748
749bool Layer::getFiltering() const {
750 return mFiltering;
751}
752
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800753// As documented in libhardware header, formats in the range
754// 0x100 - 0x1FF are specific to the HAL implementation, and
755// are known to have no alpha channel
756// TODO: move definition for device-specific range into
757// hardware.h, instead of using hard-coded values here.
758#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
759
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700760bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700761 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
762 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800763 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700764 switch (format) {
765 case HAL_PIXEL_FORMAT_RGBA_8888:
766 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700767 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700768 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700769 }
770 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700771 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800772}
773
Mathias Agopian13127d82013-03-05 17:47:11 -0800774// ----------------------------------------------------------------------------
775// local state
776// ----------------------------------------------------------------------------
777
Dan Stozac7014012014-02-14 15:03:43 -0800778void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
779 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800780{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700781 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800782 const Transform tr(useIdentityTransform ?
783 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800784 const uint32_t hw_h = hw->getHeight();
785 Rect win(s.active.w, s.active.h);
786 if (!s.active.crop.isEmpty()) {
787 win.intersect(s.active.crop, &win);
788 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700789 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700790 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700791
Mathias Agopianff2ed702013-09-01 21:36:12 -0700792 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
793 position[0] = tr.transform(win.left, win.top);
794 position[1] = tr.transform(win.left, win.bottom);
795 position[2] = tr.transform(win.right, win.bottom);
796 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700797 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700798 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800799 }
800}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800801
Andy McFadden4125a4f2014-01-29 17:17:11 -0800802bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700803{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700804 // if we don't have a buffer yet, we're translucent regardless of the
805 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700806 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700807 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700808 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700809
810 // if the layer has the opaque flag, then we're always opaque,
811 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800812 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700813}
814
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800815bool Layer::isProtected() const
816{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700817 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800818 return (activeBuffer != 0) &&
819 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
820}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700821
Mathias Agopian13127d82013-03-05 17:47:11 -0800822bool Layer::isFixedSize() const {
823 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
824}
825
826bool Layer::isCropped() const {
827 return !mCurrentCrop.isEmpty();
828}
829
830bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
831 return mNeedsFiltering || hw->needsFiltering();
832}
833
834void Layer::setVisibleRegion(const Region& visibleRegion) {
835 // always called from main thread
836 this->visibleRegion = visibleRegion;
837}
838
839void Layer::setCoveredRegion(const Region& coveredRegion) {
840 // always called from main thread
841 this->coveredRegion = coveredRegion;
842}
843
844void Layer::setVisibleNonTransparentRegion(const Region&
845 setVisibleNonTransparentRegion) {
846 // always called from main thread
847 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
848}
849
850// ----------------------------------------------------------------------------
851// transaction
852// ----------------------------------------------------------------------------
853
854uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800855 ATRACE_CALL();
856
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700857 const Layer::State& s(getDrawingState());
858 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800859
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700860 const bool sizeChanged = (c.requested.w != s.requested.w) ||
861 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700862
863 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700864 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000865 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700866 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700867 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
868 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
869 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
870 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700871 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
872 c.active.w, c.active.h,
873 c.active.crop.left,
874 c.active.crop.top,
875 c.active.crop.right,
876 c.active.crop.bottom,
877 c.active.crop.getWidth(),
878 c.active.crop.getHeight(),
879 c.requested.w, c.requested.h,
880 c.requested.crop.left,
881 c.requested.crop.top,
882 c.requested.crop.right,
883 c.requested.crop.bottom,
884 c.requested.crop.getWidth(),
885 c.requested.crop.getHeight(),
886 s.active.w, s.active.h,
887 s.active.crop.left,
888 s.active.crop.top,
889 s.active.crop.right,
890 s.active.crop.bottom,
891 s.active.crop.getWidth(),
892 s.active.crop.getHeight(),
893 s.requested.w, s.requested.h,
894 s.requested.crop.left,
895 s.requested.crop.top,
896 s.requested.crop.right,
897 s.requested.crop.bottom,
898 s.requested.crop.getWidth(),
899 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800900
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700901 // record the new size, form this point on, when the client request
902 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800903 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700904 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800905 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700906
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700907 if (!isFixedSize()) {
908
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700909 const bool resizePending = (c.requested.w != c.active.w) ||
910 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700911
912 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800913 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700914 // if we have a pending resize, unless we are in fixed-size mode.
915 // the drawing state will be updated only once we receive a buffer
916 // with the correct size.
917 //
918 // in particular, we want to make sure the clip (which is part
919 // of the geometry state) is latched together with the size but is
920 // latched immediately when no resizing is involved.
921
922 flags |= eDontUpdateGeometryState;
923 }
924 }
925
Mathias Agopian13127d82013-03-05 17:47:11 -0800926 // always set active to requested, unless we're asked not to
927 // this is used by Layer, which special cases resizes.
928 if (flags & eDontUpdateGeometryState) {
929 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700930 Layer::State& editCurrentState(getCurrentState());
931 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800932 }
933
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700934 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800935 // invalidate and recompute the visible regions if needed
936 flags |= Layer::eVisibleRegion;
937 }
938
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700939 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800940 // invalidate and recompute the visible regions if needed
941 flags |= eVisibleRegion;
942 this->contentDirty = true;
943
944 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700945 const uint8_t type = c.transform.getType();
946 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800947 (type >= Transform::SCALE));
948 }
949
950 // Commit the transaction
951 commitTransaction();
952 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800953}
954
Mathias Agopian13127d82013-03-05 17:47:11 -0800955void Layer::commitTransaction() {
956 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700957}
958
Mathias Agopian13127d82013-03-05 17:47:11 -0800959uint32_t Layer::getTransactionFlags(uint32_t flags) {
960 return android_atomic_and(~flags, &mTransactionFlags) & flags;
961}
962
963uint32_t Layer::setTransactionFlags(uint32_t flags) {
964 return android_atomic_or(flags, &mTransactionFlags);
965}
966
967bool Layer::setPosition(float x, float y) {
968 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
969 return false;
970 mCurrentState.sequence++;
971 mCurrentState.transform.set(x, y);
972 setTransactionFlags(eTransactionNeeded);
973 return true;
974}
975bool Layer::setLayer(uint32_t z) {
976 if (mCurrentState.z == z)
977 return false;
978 mCurrentState.sequence++;
979 mCurrentState.z = z;
980 setTransactionFlags(eTransactionNeeded);
981 return true;
982}
983bool Layer::setSize(uint32_t w, uint32_t h) {
984 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
985 return false;
986 mCurrentState.requested.w = w;
987 mCurrentState.requested.h = h;
988 setTransactionFlags(eTransactionNeeded);
989 return true;
990}
991bool Layer::setAlpha(uint8_t alpha) {
992 if (mCurrentState.alpha == alpha)
993 return false;
994 mCurrentState.sequence++;
995 mCurrentState.alpha = alpha;
996 setTransactionFlags(eTransactionNeeded);
997 return true;
998}
999bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1000 mCurrentState.sequence++;
1001 mCurrentState.transform.set(
1002 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1003 setTransactionFlags(eTransactionNeeded);
1004 return true;
1005}
1006bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001007 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001008 setTransactionFlags(eTransactionNeeded);
1009 return true;
1010}
1011bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1012 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1013 if (mCurrentState.flags == newFlags)
1014 return false;
1015 mCurrentState.sequence++;
1016 mCurrentState.flags = newFlags;
1017 setTransactionFlags(eTransactionNeeded);
1018 return true;
1019}
1020bool Layer::setCrop(const Rect& crop) {
1021 if (mCurrentState.requested.crop == crop)
1022 return false;
1023 mCurrentState.sequence++;
1024 mCurrentState.requested.crop = crop;
1025 setTransactionFlags(eTransactionNeeded);
1026 return true;
1027}
1028
1029bool Layer::setLayerStack(uint32_t layerStack) {
1030 if (mCurrentState.layerStack == layerStack)
1031 return false;
1032 mCurrentState.sequence++;
1033 mCurrentState.layerStack = layerStack;
1034 setTransactionFlags(eTransactionNeeded);
1035 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001036}
1037
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001038// ----------------------------------------------------------------------------
1039// pageflip handling...
1040// ----------------------------------------------------------------------------
1041
Dan Stoza6b9454d2014-11-07 16:00:59 -08001042bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1043 Mutex::Autolock lock(mQueueItemLock);
1044 nsecs_t expectedPresent =
1045 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1046 return mQueueItems.empty() ?
1047 false : mQueueItems[0].mTimestamp < expectedPresent;
1048}
1049
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001050bool Layer::onPreComposition() {
1051 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001052 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001053}
1054
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001055void Layer::onPostComposition() {
1056 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001057 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001058 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1059
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001060 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001061 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001062 mFrameTracker.setFrameReadyFence(frameReadyFence);
1063 } else {
1064 // There was no fence for this frame, so assume that it was ready
1065 // to be presented at the desired present time.
1066 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1067 }
1068
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001069 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001070 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001071 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001072 mFrameTracker.setActualPresentFence(presentFence);
1073 } else {
1074 // The HWC doesn't support present fences, so use the refresh
1075 // timestamp instead.
1076 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1077 mFrameTracker.setActualPresentTime(presentTime);
1078 }
1079
1080 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001081 mFrameLatencyNeeded = false;
1082 }
1083}
1084
Mathias Agopianda27af92012-09-13 18:17:13 -07001085bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001086 const Layer::State& s(mDrawingState);
1087 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001088 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001089}
1090
Mathias Agopian4fec8732012-06-29 14:12:52 -07001091Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001092{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001093 ATRACE_CALL();
1094
Jesse Hall399184a2014-03-03 15:42:54 -08001095 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1096 // mSidebandStreamChanged was true
1097 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001098 recomputeVisibleRegions = true;
1099
1100 const State& s(getDrawingState());
1101 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001102 }
1103
Mathias Agopian4fec8732012-06-29 14:12:52 -07001104 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001105 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001106
1107 // if we've already called updateTexImage() without going through
1108 // a composition step, we have to skip this layer at this point
1109 // because we cannot call updateTeximage() without a corresponding
1110 // compositionComplete() call.
1111 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001112 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001113 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001114 }
1115
Jamie Gennis351a5132011-09-14 18:23:37 -07001116 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001117 const State& s(getDrawingState());
1118 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001119 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001120
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001121 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001122 Layer::State& front;
1123 Layer::State& current;
1124 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001125 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001126 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001127 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001128 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001129 recomputeVisibleRegions(recomputeVisibleRegions),
1130 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001131 }
1132
1133 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001134 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001135 if (buf == NULL) {
1136 return false;
1137 }
1138
1139 uint32_t bufWidth = buf->getWidth();
1140 uint32_t bufHeight = buf->getHeight();
1141
1142 // check that we received a buffer of the right size
1143 // (Take the buffer's orientation into account)
1144 if (item.mTransform & Transform::ROT_90) {
1145 swap(bufWidth, bufHeight);
1146 }
1147
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001148 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1149 if (front.active != front.requested) {
1150
1151 if (isFixedSize ||
1152 (bufWidth == front.requested.w &&
1153 bufHeight == front.requested.h))
1154 {
1155 // Here we pretend the transaction happened by updating the
1156 // current and drawing states. Drawing state is only accessed
1157 // in this thread, no need to have it locked
1158 front.active = front.requested;
1159
1160 // We also need to update the current state so that
1161 // we don't end-up overwriting the drawing state with
1162 // this stale current state during the next transaction
1163 //
1164 // NOTE: We don't need to hold the transaction lock here
1165 // because State::active is only accessed from this thread.
1166 current.active = front.active;
1167
1168 // recompute visible region
1169 recomputeVisibleRegions = true;
1170 }
1171
1172 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001173 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001174 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1175 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001176 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001177 front.active.w, front.active.h,
1178 front.active.crop.left,
1179 front.active.crop.top,
1180 front.active.crop.right,
1181 front.active.crop.bottom,
1182 front.active.crop.getWidth(),
1183 front.active.crop.getHeight(),
1184 front.requested.w, front.requested.h,
1185 front.requested.crop.left,
1186 front.requested.crop.top,
1187 front.requested.crop.right,
1188 front.requested.crop.bottom,
1189 front.requested.crop.getWidth(),
1190 front.requested.crop.getHeight());
1191 }
1192
Ruben Brunk1681d952014-06-27 15:51:55 -07001193 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001194 if (front.active.w != bufWidth ||
1195 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001196 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001197 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1198 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001199 return true;
1200 }
1201 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001202
1203 // if the transparent region has changed (this test is
1204 // conservative, but that's fine, worst case we're doing
1205 // a bit of extra work), we latch the new one and we
1206 // trigger a visible-region recompute.
1207 if (!front.activeTransparentRegion.isTriviallyEqual(
1208 front.requestedTransparentRegion)) {
1209 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001210
1211 // We also need to update the current state so that
1212 // we don't end-up overwriting the drawing state with
1213 // this stale current state during the next transaction
1214 //
1215 // NOTE: We don't need to hold the transaction lock here
1216 // because State::active is only accessed from this thread.
1217 current.activeTransparentRegion = front.activeTransparentRegion;
1218
1219 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001220 recomputeVisibleRegions = true;
1221 }
1222
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001223 return false;
1224 }
1225 };
1226
Ruben Brunk1681d952014-06-27 15:51:55 -07001227 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1228 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001229
Andy McFadden41d67d72014-04-25 16:58:34 -07001230 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1231 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001232 if (updateResult == BufferQueue::PRESENT_LATER) {
1233 // Producer doesn't want buffer to be displayed yet. Signal a
1234 // layer update so we check again at the next opportunity.
1235 mFlinger->signalLayerUpdate();
1236 return outDirtyRegion;
1237 }
1238
Dan Stoza6b9454d2014-11-07 16:00:59 -08001239 // Remove this buffer from our internal queue tracker
1240 { // Autolock scope
1241 Mutex::Autolock lock(mQueueItemLock);
1242 mQueueItems.removeAt(0);
1243 }
1244
Andy McFadden1585c4d2013-06-28 13:52:40 -07001245 // Decrement the queued-frames count. Signal another event if we
1246 // have more frames pending.
1247 if (android_atomic_dec(&mQueuedFrames) > 1) {
1248 mFlinger->signalLayerUpdate();
1249 }
1250
1251 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001252 // something happened!
1253 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001254 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001255 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001256
Jamie Gennis351a5132011-09-14 18:23:37 -07001257 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001258 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001259 if (mActiveBuffer == NULL) {
1260 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001261 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001262 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001263
Mathias Agopian4824d402012-06-04 18:16:30 -07001264 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001265 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001266 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001267 // the first time we receive a buffer, we need to trigger a
1268 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001269 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001270 }
1271
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001272 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1273 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1274 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001275 if ((crop != mCurrentCrop) ||
1276 (transform != mCurrentTransform) ||
1277 (scalingMode != mCurrentScalingMode))
1278 {
1279 mCurrentCrop = crop;
1280 mCurrentTransform = transform;
1281 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001282 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001283 }
1284
1285 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001286 uint32_t bufWidth = mActiveBuffer->getWidth();
1287 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001288 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1289 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001290 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001291 }
1292 }
1293
1294 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001295 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001296 recomputeVisibleRegions = true;
1297 }
1298
Mathias Agopian4fec8732012-06-29 14:12:52 -07001299 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001300 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001301
1302 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001303 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001304 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001305 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001306}
1307
Mathias Agopiana67932f2011-04-20 14:20:59 -07001308uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001309{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001310 // TODO: should we do something special if mSecure is set?
1311 if (mProtectedByApp) {
1312 // need a hardware-protected path to external video sink
1313 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001314 }
Riley Andrews03414a12014-07-01 14:22:59 -07001315 if (mPotentialCursor) {
1316 usage |= GraphicBuffer::USAGE_CURSOR;
1317 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001318 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001319 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001320}
1321
Mathias Agopian84300952012-11-21 16:02:13 -08001322void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001323 uint32_t orientation = 0;
1324 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001325 // The transform hint is used to improve performance, but we can
1326 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001327 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001328 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001329 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001330 if (orientation & Transform::ROT_INVALID) {
1331 orientation = 0;
1332 }
1333 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001334 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001335}
1336
Mathias Agopian13127d82013-03-05 17:47:11 -08001337// ----------------------------------------------------------------------------
1338// debugging
1339// ----------------------------------------------------------------------------
1340
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001341void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001342{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001343 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001344
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001345 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001346 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001347 "+ %s %p (%s)\n",
1348 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001349 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001350
Mathias Agopian2ca79392013-04-02 18:30:32 -07001351 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001352 visibleRegion.dump(result, "visibleRegion");
1353 sp<Client> client(mClientRef.promote());
1354
Mathias Agopian74d211a2013-04-22 16:55:35 +02001355 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001356 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1357 "isOpaque=%1d, invalidate=%1d, "
1358 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1359 " client=%p\n",
1360 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1361 s.active.crop.left, s.active.crop.top,
1362 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001363 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001364 s.alpha, s.flags,
1365 s.transform[0][0], s.transform[0][1],
1366 s.transform[1][0], s.transform[1][1],
1367 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001368
1369 sp<const GraphicBuffer> buf0(mActiveBuffer);
1370 uint32_t w0=0, h0=0, s0=0, f0=0;
1371 if (buf0 != 0) {
1372 w0 = buf0->getWidth();
1373 h0 = buf0->getHeight();
1374 s0 = buf0->getStride();
1375 f0 = buf0->format;
1376 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001377 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001378 " "
1379 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1380 " queued-frames=%d, mRefreshPending=%d\n",
1381 mFormat, w0, h0, s0,f0,
1382 mQueuedFrames, mRefreshPending);
1383
Mathias Agopian13127d82013-03-05 17:47:11 -08001384 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001385 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001386 }
1387}
1388
Svetoslavd85084b2014-03-20 10:28:31 -07001389void Layer::dumpFrameStats(String8& result) const {
1390 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001391}
1392
Svetoslavd85084b2014-03-20 10:28:31 -07001393void Layer::clearFrameStats() {
1394 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001395}
1396
Jamie Gennis6547ff42013-07-16 20:12:42 -07001397void Layer::logFrameStats() {
1398 mFrameTracker.logAndResetStats(mName);
1399}
1400
Svetoslavd85084b2014-03-20 10:28:31 -07001401void Layer::getFrameStats(FrameStats* outStats) const {
1402 mFrameTracker.getStats(outStats);
1403}
1404
Mathias Agopian13127d82013-03-05 17:47:11 -08001405// ---------------------------------------------------------------------------
1406
1407Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1408 const sp<Layer>& layer)
1409 : mFlinger(flinger), mLayer(layer) {
1410}
1411
1412Layer::LayerCleaner::~LayerCleaner() {
1413 // destroy client resources
1414 mFlinger->onLayerDestroyed(mLayer);
1415}
1416
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001417// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001418}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001419
1420#if defined(__gl_h_)
1421#error "don't include gl/gl.h in this file"
1422#endif
1423
1424#if defined(__gl2_h_)
1425#error "don't include gl2/gl2.h in this file"
1426#endif