blob: 5e3dfabb3984b9be8ad4aa3a0f64828f2e60f408 [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"),
67 mDebug(false),
68 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080069 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070070 mQueuedFrames(0),
Jesse Hall399184a2014-03-03 15:42:54 -080071 mSidebandStreamChanged(false),
Mathias Agopiana67932f2011-04-20 14:20:59 -070072 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070073 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070074 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080075 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080076 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080077 mFiltering(false),
78 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070079 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070080 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080081 mProtectedByApp(false),
82 mHasSurface(false),
Riley Andrews03414a12014-07-01 14:22:59 -070083 mClientRef(client),
84 mPotentialCursor(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080085{
Mathias Agopiana67932f2011-04-20 14:20:59 -070086 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070087 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian49457ac2013-08-14 18:20:17 -070088 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070089
90 uint32_t layerFlags = 0;
91 if (flags & ISurfaceComposerClient::eHidden)
Andy McFadden4125a4f2014-01-29 17:17:11 -080092 layerFlags |= layer_state_t::eLayerHidden;
93 if (flags & ISurfaceComposerClient::eOpaque)
94 layerFlags |= layer_state_t::eLayerOpaque;
Mathias Agopian4d9b8222013-03-12 17:11:48 -070095
96 if (flags & ISurfaceComposerClient::eNonPremultiplied)
97 mPremultipliedAlpha = false;
98
99 mName = name;
100
101 mCurrentState.active.w = w;
102 mCurrentState.active.h = h;
103 mCurrentState.active.crop.makeInvalid();
104 mCurrentState.z = 0;
105 mCurrentState.alpha = 0xFF;
106 mCurrentState.layerStack = 0;
107 mCurrentState.flags = layerFlags;
108 mCurrentState.sequence = 0;
109 mCurrentState.transform.set(0, 0);
110 mCurrentState.requested = mCurrentState.active;
111
112 // drawing state & current state are identical
113 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700114
115 nsecs_t displayPeriod =
116 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
117 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800118}
119
Mathias Agopian3f844832013-08-07 21:24:32 -0700120void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800121 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700122 sp<IGraphicBufferProducer> producer;
123 sp<IGraphicBufferConsumer> consumer;
Dan Stozab9b08832014-03-13 11:55:57 -0700124 BufferQueue::createBufferQueue(&producer, &consumer);
125 mProducer = new MonitoredProducer(producer, mFlinger);
126 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800127 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Jesse Hall399184a2014-03-03 15:42:54 -0800128 mSurfaceFlingerConsumer->setContentsChangedListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700129 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800130
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700131#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
132#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800133 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700134#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800135 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800136#endif
Andy McFadden69052052012-09-14 16:10:11 -0700137
Mathias Agopian84300952012-11-21 16:02:13 -0800138 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
139 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700140}
141
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700142Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800143 sp<Client> c(mClientRef.promote());
144 if (c != 0) {
145 c->detachLayer(this);
146 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700147 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700148 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700149}
150
Mathias Agopian13127d82013-03-05 17:47:11 -0800151// ---------------------------------------------------------------------------
152// callbacks
153// ---------------------------------------------------------------------------
154
Dan Stozac7014012014-02-14 15:03:43 -0800155void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
Mathias Agopian13127d82013-03-05 17:47:11 -0800156 HWComposer::HWCLayerInterface* layer) {
157 if (layer) {
158 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700159 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800160 }
161}
162
Dan Stoza6b9454d2014-11-07 16:00:59 -0800163void Layer::onFrameAvailable(const BufferItem& item) {
164 // Add this buffer from our internal queue tracker
165 { // Autolock scope
166 Mutex::Autolock lock(mQueueItemLock);
167 mQueueItems.push_back(item);
168 }
169
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700170 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800171 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700172}
173
Dan Stoza6b9454d2014-11-07 16:00:59 -0800174void Layer::onFrameReplaced(const BufferItem& item) {
175 Mutex::Autolock lock(mQueueItemLock);
176 if (mQueueItems.empty()) {
177 ALOGE("Can't replace a frame on an empty queue");
178 return;
179 }
180 mQueueItems.editItemAt(0) = item;
181}
182
Jesse Hall399184a2014-03-03 15:42:54 -0800183void Layer::onSidebandStreamChanged() {
184 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
185 // mSidebandStreamChanged was false
186 mFlinger->signalLayerUpdate();
187 }
188}
189
Mathias Agopian67106042013-03-14 19:18:13 -0700190// called with SurfaceFlinger::mStateLock from the drawing thread after
191// the layer has been remove from the current state list (and just before
192// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800193void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800194 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700195}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700196
Mathias Agopian13127d82013-03-05 17:47:11 -0800197// ---------------------------------------------------------------------------
198// set-up
199// ---------------------------------------------------------------------------
200
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700201const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800202 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800203}
204
Mathias Agopianf9d93272009-06-19 17:00:27 -0700205status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800206 PixelFormat format, uint32_t flags)
207{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700208 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700209 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700210
211 // never allow a surface larger than what our underlying GL implementation
212 // can handle.
213 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800214 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700215 return BAD_VALUE;
216 }
217
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700218 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700219
Riley Andrews03414a12014-07-01 14:22:59 -0700220 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700221 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
222 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700223 mCurrentOpacity = getOpacityForFormat(format);
224
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800225 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
226 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
227 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700228
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800229 return NO_ERROR;
230}
231
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700232sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800233 Mutex::Autolock _l(mLock);
234
235 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700236 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800237
238 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700239
240 /*
241 * The layer handle is just a BBinder object passed to the client
242 * (remote process) -- we don't keep any reference on our side such that
243 * the dtor is called when the remote side let go of its reference.
244 *
245 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
246 * this layer when the handle is destroyed.
247 */
248
249 class Handle : public BBinder, public LayerCleaner {
250 wp<const Layer> mOwner;
251 public:
252 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
253 : LayerCleaner(flinger, layer), mOwner(layer) {
254 }
255 };
256
257 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800258}
259
Dan Stozab9b08832014-03-13 11:55:57 -0700260sp<IGraphicBufferProducer> Layer::getProducer() const {
261 return mProducer;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700262}
263
Mathias Agopian13127d82013-03-05 17:47:11 -0800264// ---------------------------------------------------------------------------
265// h/w composer set-up
266// ---------------------------------------------------------------------------
267
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800268Rect Layer::getContentCrop() const {
269 // this is the crop rectangle that applies to the buffer
270 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700271 Rect crop;
272 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800273 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700274 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800275 } else if (mActiveBuffer != NULL) {
276 // otherwise we use the whole buffer
277 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700278 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800279 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700280 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700281 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700282 return crop;
283}
284
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700285static Rect reduce(const Rect& win, const Region& exclude) {
286 if (CC_LIKELY(exclude.isEmpty())) {
287 return win;
288 }
289 if (exclude.isRect()) {
290 return win.reduce(exclude.getBounds());
291 }
292 return Region(win).subtract(exclude).getBounds();
293}
294
Mathias Agopian13127d82013-03-05 17:47:11 -0800295Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700296 const Layer::State& s(getDrawingState());
Michael Lentine6c925ed2014-09-26 17:55:01 -0700297 return computeBounds(s.activeTransparentRegion);
298}
299
300Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
301 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800302 Rect win(s.active.w, s.active.h);
303 if (!s.active.crop.isEmpty()) {
304 win.intersect(s.active.crop, &win);
305 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700306 // subtract the transparent region and snap to the bounds
Michael Lentine6c925ed2014-09-26 17:55:01 -0700307 return reduce(win, activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800308}
309
Mathias Agopian6b442672013-07-09 21:24:52 -0700310FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800311 // the content crop is the area of the content that gets scaled to the
312 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700313 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800314
315 // the active.crop is the area of the window that gets cropped, but not
316 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700317 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800318
319 // apply the projection's clipping to the window crop in
320 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700321 // if there are no window scaling involved, this operation will map to full
322 // pixels in the buffer.
323 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
324 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian0e8f1442013-08-20 21:41:07 -0700325
326 Rect activeCrop(s.active.w, s.active.h);
327 if (!s.active.crop.isEmpty()) {
328 activeCrop = s.active.crop;
329 }
330
331 activeCrop = s.transform.transform(activeCrop);
Mathias Agopian13127d82013-03-05 17:47:11 -0800332 activeCrop.intersect(hw->getViewport(), &activeCrop);
333 activeCrop = s.transform.inverse().transform(activeCrop);
334
Michael Lentine28ea2172014-11-19 18:32:37 -0800335 // This needs to be here as transform.transform(Rect) computes the
336 // transformed rect and then takes the bounding box of the result before
337 // returning. This means
338 // transform.inverse().transform(transform.transform(Rect)) != Rect
339 // in which case we need to make sure the final rect is clipped to the
340 // display bounds.
Mathias Agopian13127d82013-03-05 17:47:11 -0800341 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
342
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700343 // subtract the transparent region and snap to the bounds
344 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
345
Mathias Agopian13127d82013-03-05 17:47:11 -0800346 if (!activeCrop.isEmpty()) {
347 // Transform the window crop to match the buffer coordinate system,
348 // which means using the inverse of the current transform set on the
349 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700350 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700351 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
352 /*
353 * the code below applies the display's inverse transform to the buffer
354 */
355 uint32_t invTransformOrient = hw->getOrientationTransform();
356 // calculate the inverse transform
357 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
358 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
359 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700360 // If the transform has been rotated the axis of flip has been swapped
361 // so we need to swap which flip operations we are performing
362 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
363 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
364 if (is_h_flipped != is_v_flipped) {
365 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
366 NATIVE_WINDOW_TRANSFORM_FLIP_H;
367 }
Michael Lentinef7551402014-08-18 16:35:43 -0700368 }
369 // and apply to the current transform
370 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
371 }
372
Mathias Agopian13127d82013-03-05 17:47:11 -0800373 int winWidth = s.active.w;
374 int winHeight = s.active.h;
375 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700376 // If the activeCrop has been rotate the ends are rotated but not
377 // the space itself so when transforming ends back we can't rely on
378 // a modification of the axes of rotation. To account for this we
379 // need to reorient the inverse rotation in terms of the current
380 // axes of rotation.
381 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
382 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
383 if (is_h_flipped == is_v_flipped) {
384 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
385 NATIVE_WINDOW_TRANSFORM_FLIP_H;
386 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800387 winWidth = s.active.h;
388 winHeight = s.active.w;
389 }
390 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700391 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800392
Mathias Agopian6b442672013-07-09 21:24:52 -0700393 // below, crop is intersected with winCrop expressed in crop's coordinate space
394 float xScale = crop.getWidth() / float(winWidth);
395 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800396
Michael Lentinef7551402014-08-18 16:35:43 -0700397 float insetL = winCrop.left * xScale;
398 float insetT = winCrop.top * yScale;
399 float insetR = (winWidth - winCrop.right ) * xScale;
400 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800401
402 crop.left += insetL;
403 crop.top += insetT;
404 crop.right -= insetR;
405 crop.bottom -= insetB;
406 }
407 return crop;
408}
409
Mathias Agopian4fec8732012-06-29 14:12:52 -0700410void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700411 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700412 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700413{
Mathias Agopian13127d82013-03-05 17:47:11 -0800414 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700415
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700416 // enable this layer
417 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700418
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700419 if (isSecure() && !hw->isSecure()) {
420 layer.setSkip(true);
421 }
422
Mathias Agopian13127d82013-03-05 17:47:11 -0800423 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700424 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800425 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800426 layer.setBlending(mPremultipliedAlpha ?
427 HWC_BLENDING_PREMULT :
428 HWC_BLENDING_COVERAGE);
429 }
430
431 // apply the layer's transform, followed by the display's global transform
432 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700433 Region activeTransparentRegion(s.activeTransparentRegion);
434 if (!s.active.crop.isEmpty()) {
435 Rect activeCrop(s.active.crop);
436 activeCrop = s.transform.transform(activeCrop);
437 activeCrop.intersect(hw->getViewport(), &activeCrop);
438 activeCrop = s.transform.inverse().transform(activeCrop);
Michael Lentine28ea2172014-11-19 18:32:37 -0800439 // This needs to be here as transform.transform(Rect) computes the
440 // transformed rect and then takes the bounding box of the result before
441 // returning. This means
442 // transform.inverse().transform(transform.transform(Rect)) != Rect
443 // in which case we need to make sure the final rect is clipped to the
444 // display bounds.
445 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
Michael Lentine6c925ed2014-09-26 17:55:01 -0700446 // mark regions outside the crop as transparent
447 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
448 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
449 s.active.w, s.active.h));
450 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
451 activeCrop.left, activeCrop.bottom));
452 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
453 s.active.w, activeCrop.bottom));
454 }
455 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800456 frame.intersect(hw->getViewport(), &frame);
457 const Transform& tr(hw->getTransform());
458 layer.setFrame(tr.transform(frame));
459 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800460 layer.setPlaneAlpha(s.alpha);
461
Mathias Agopian29a367b2011-07-12 14:51:45 -0700462 /*
463 * Transformations are applied in this order:
464 * 1) buffer orientation/flip/mirror
465 * 2) state transformation (window manager)
466 * 3) layer orientation (screen orientation)
467 * (NOTE: the matrices are multiplied in reverse order)
468 */
469
470 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700471 Transform transform(tr * s.transform * bufferOrientation);
472
473 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
474 /*
475 * the code below applies the display's inverse transform to the buffer
476 */
477 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700478 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700479 // calculate the inverse transform
480 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
481 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
482 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700483 // If the transform has been rotated the axis of flip has been swapped
484 // so we need to swap which flip operations we are performing
485 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
486 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
487 if (is_h_flipped != is_v_flipped) {
488 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
489 NATIVE_WINDOW_TRANSFORM_FLIP_H;
490 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700491 }
492 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700493 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700494 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700495
496 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800497 const uint32_t orientation = transform.getOrientation();
498 if (orientation & Transform::ROT_INVALID) {
499 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700500 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700501 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800502 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700503 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700504}
505
Mathias Agopian42977342012-08-05 00:40:46 -0700506void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700507 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800508 // we have to set the visible region on every frame because
509 // we currently free it during onLayerDisplayed(), which is called
510 // after HWComposer::commit() -- every frame.
511 // Apply this display's projection's viewport to the visible region
512 // before giving it to the HWC HAL.
513 const Transform& tr = hw->getTransform();
514 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
515 layer.setVisibleRegionScreen(visible);
516
Jesse Hall399184a2014-03-03 15:42:54 -0800517 if (mSidebandStream.get()) {
518 layer.setSidebandStream(mSidebandStream);
519 } else {
520 // NOTE: buffer can be NULL if the client never drew into this
521 // layer yet, or if we ran out of memory
522 layer.setBuffer(mActiveBuffer);
523 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700524}
Jesse Halldc5b4852012-06-29 15:21:18 -0700525
Dan Stozac7014012014-02-14 15:03:43 -0800526void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700527 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700528 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700529
530 // TODO: there is a possible optimization here: we only need to set the
531 // acquire fence the first time a new buffer is acquired on EACH display.
532
Riley Andrews03414a12014-07-01 14:22:59 -0700533 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800534 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800535 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700536 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700537 if (fenceFd == -1) {
538 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
539 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700540 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700541 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700542 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700543}
544
Riley Andrews03414a12014-07-01 14:22:59 -0700545Rect Layer::getPosition(
546 const sp<const DisplayDevice>& hw)
547{
548 // this gives us only the "orientation" component of the transform
549 const State& s(getCurrentState());
550
551 // apply the layer's transform, followed by the display's global transform
552 // here we're guaranteed that the layer's transform preserves rects
553 Rect win(s.active.w, s.active.h);
554 if (!s.active.crop.isEmpty()) {
555 win.intersect(s.active.crop, &win);
556 }
557 // subtract the transparent region and snap to the bounds
558 Rect bounds = reduce(win, s.activeTransparentRegion);
559 Rect frame(s.transform.transform(bounds));
560 frame.intersect(hw->getViewport(), &frame);
561 const Transform& tr(hw->getTransform());
562 return Rect(tr.transform(frame));
563}
564
Mathias Agopian13127d82013-03-05 17:47:11 -0800565// ---------------------------------------------------------------------------
566// drawing...
567// ---------------------------------------------------------------------------
568
569void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800570 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800571}
572
Dan Stozac7014012014-02-14 15:03:43 -0800573void Layer::draw(const sp<const DisplayDevice>& hw,
574 bool useIdentityTransform) const {
575 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800576}
577
Dan Stozac7014012014-02-14 15:03:43 -0800578void Layer::draw(const sp<const DisplayDevice>& hw) const {
579 onDraw(hw, Region(hw->bounds()), false);
580}
581
582void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
583 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800584{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800585 ATRACE_CALL();
586
Mathias Agopiana67932f2011-04-20 14:20:59 -0700587 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800588 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700589 // in fact never been drawn into. This happens frequently with
590 // SurfaceView because the WindowManager can't know when the client
591 // has drawn the first time.
592
593 // If there is nothing under us, we paint the screen in black, otherwise
594 // we just skip this update.
595
596 // figure out if there is something below us
597 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700598 const SurfaceFlinger::LayerVector& drawingLayers(
599 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700600 const size_t count = drawingLayers.size();
601 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800602 const sp<Layer>& layer(drawingLayers[i]);
603 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700604 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700605 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700606 }
607 // if not everything below us is covered, we plug the holes!
608 Region holes(clip.subtract(under));
609 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700610 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700611 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800612 return;
613 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700614
Andy McFadden97eba892012-12-11 15:21:45 -0800615 // Bind the current buffer to the GL texture, and wait for it to be
616 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800617 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
618 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800619 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700620 // Go ahead and draw the buffer anyway; no matter what we do the screen
621 // is probably going to have something visibly wrong.
622 }
623
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700624 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
625
Mathias Agopian875d8e12013-06-07 15:35:48 -0700626 RenderEngine& engine(mFlinger->getRenderEngine());
627
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700628 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700629 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700630 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700631
632 // Query the texture matrix given our current filtering mode.
633 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800634 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
635 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700636
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700637 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
638
639 /*
640 * the code below applies the display's inverse transform to the texture transform
641 */
642
643 // create a 4x4 transform matrix from the display transform flags
644 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
645 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
646 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
647
648 mat4 tr;
649 uint32_t transform = hw->getOrientationTransform();
650 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
651 tr = tr * rot90;
652 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
653 tr = tr * flipH;
654 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
655 tr = tr * flipV;
656
657 // calculate the inverse
658 tr = inverse(tr);
659
660 // and finally apply it to the original texture matrix
661 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
662 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
663 }
664
Jamie Genniscbb1a952012-05-08 17:05:52 -0700665 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700666 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
667 mTexture.setFiltering(useFiltering);
668 mTexture.setMatrix(textureMatrix);
669
670 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700671 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700672 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700673 }
Dan Stozac7014012014-02-14 15:03:43 -0800674 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700675 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800676}
677
Mathias Agopian13127d82013-03-05 17:47:11 -0800678
Dan Stozac7014012014-02-14 15:03:43 -0800679void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
680 const Region& /* clip */, float red, float green, float blue,
681 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800682{
Mathias Agopian19733a32013-08-28 18:13:56 -0700683 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800684 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700685 engine.setupFillWithColor(red, green, blue, alpha);
686 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800687}
688
689void Layer::clearWithOpenGL(
690 const sp<const DisplayDevice>& hw, const Region& clip) const {
691 clearWithOpenGL(hw, clip, 0,0,0,0);
692}
693
Dan Stozac7014012014-02-14 15:03:43 -0800694void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
695 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800696 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700697 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800698
Dan Stozac7014012014-02-14 15:03:43 -0800699 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800700
Mathias Agopian13127d82013-03-05 17:47:11 -0800701 /*
702 * NOTE: the way we compute the texture coordinates here produces
703 * different results than when we take the HWC path -- in the later case
704 * the "source crop" is rounded to texel boundaries.
705 * This can produce significantly different results when the texture
706 * is scaled by a large amount.
707 *
708 * The GL code below is more logical (imho), and the difference with
709 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700710 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800711 * GL composition when a buffer scaling is applied (maybe with some
712 * minimal value)? Or, we could make GL behave like HWC -- but this feel
713 * like more of a hack.
714 */
715 const Rect win(computeBounds());
716
Mathias Agopian3f844832013-08-07 21:24:32 -0700717 float left = float(win.left) / float(s.active.w);
718 float top = float(win.top) / float(s.active.h);
719 float right = float(win.right) / float(s.active.w);
720 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800721
Mathias Agopian875d8e12013-06-07 15:35:48 -0700722 // TODO: we probably want to generate the texture coords with the mesh
723 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700724 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
725 texCoords[0] = vec2(left, 1.0f - top);
726 texCoords[1] = vec2(left, 1.0f - bottom);
727 texCoords[2] = vec2(right, 1.0f - bottom);
728 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800729
Mathias Agopian875d8e12013-06-07 15:35:48 -0700730 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800731 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700732 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700733 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800734}
735
Ruben Brunk1681d952014-06-27 15:51:55 -0700736uint32_t Layer::getProducerStickyTransform() const {
737 int producerStickyTransform = 0;
738 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
739 if (ret != OK) {
740 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
741 strerror(-ret), ret);
742 return 0;
743 }
744 return static_cast<uint32_t>(producerStickyTransform);
745}
746
Mathias Agopian13127d82013-03-05 17:47:11 -0800747void Layer::setFiltering(bool filtering) {
748 mFiltering = filtering;
749}
750
751bool Layer::getFiltering() const {
752 return mFiltering;
753}
754
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800755// As documented in libhardware header, formats in the range
756// 0x100 - 0x1FF are specific to the HAL implementation, and
757// are known to have no alpha channel
758// TODO: move definition for device-specific range into
759// hardware.h, instead of using hard-coded values here.
760#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
761
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700762bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700763 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
764 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800765 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700766 switch (format) {
767 case HAL_PIXEL_FORMAT_RGBA_8888:
768 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700769 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700770 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700771 }
772 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700773 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800774}
775
Mathias Agopian13127d82013-03-05 17:47:11 -0800776// ----------------------------------------------------------------------------
777// local state
778// ----------------------------------------------------------------------------
779
Dan Stozac7014012014-02-14 15:03:43 -0800780void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
781 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800782{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700783 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800784 const Transform tr(useIdentityTransform ?
785 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800786 const uint32_t hw_h = hw->getHeight();
787 Rect win(s.active.w, s.active.h);
788 if (!s.active.crop.isEmpty()) {
789 win.intersect(s.active.crop, &win);
790 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700791 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700792 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700793
Mathias Agopianff2ed702013-09-01 21:36:12 -0700794 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
795 position[0] = tr.transform(win.left, win.top);
796 position[1] = tr.transform(win.left, win.bottom);
797 position[2] = tr.transform(win.right, win.bottom);
798 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700799 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700800 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800801 }
802}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800803
Andy McFadden4125a4f2014-01-29 17:17:11 -0800804bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700805{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700806 // if we don't have a buffer yet, we're translucent regardless of the
807 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700808 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700809 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700810 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700811
812 // if the layer has the opaque flag, then we're always opaque,
813 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800814 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700815}
816
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800817bool Layer::isProtected() const
818{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700819 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800820 return (activeBuffer != 0) &&
821 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
822}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700823
Mathias Agopian13127d82013-03-05 17:47:11 -0800824bool Layer::isFixedSize() const {
825 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
826}
827
828bool Layer::isCropped() const {
829 return !mCurrentCrop.isEmpty();
830}
831
832bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
833 return mNeedsFiltering || hw->needsFiltering();
834}
835
836void Layer::setVisibleRegion(const Region& visibleRegion) {
837 // always called from main thread
838 this->visibleRegion = visibleRegion;
839}
840
841void Layer::setCoveredRegion(const Region& coveredRegion) {
842 // always called from main thread
843 this->coveredRegion = coveredRegion;
844}
845
846void Layer::setVisibleNonTransparentRegion(const Region&
847 setVisibleNonTransparentRegion) {
848 // always called from main thread
849 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
850}
851
852// ----------------------------------------------------------------------------
853// transaction
854// ----------------------------------------------------------------------------
855
856uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800857 ATRACE_CALL();
858
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700859 const Layer::State& s(getDrawingState());
860 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800861
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700862 const bool sizeChanged = (c.requested.w != s.requested.w) ||
863 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700864
865 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700866 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000867 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700868 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700869 " current={ 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"
871 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
872 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700873 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
874 c.active.w, c.active.h,
875 c.active.crop.left,
876 c.active.crop.top,
877 c.active.crop.right,
878 c.active.crop.bottom,
879 c.active.crop.getWidth(),
880 c.active.crop.getHeight(),
881 c.requested.w, c.requested.h,
882 c.requested.crop.left,
883 c.requested.crop.top,
884 c.requested.crop.right,
885 c.requested.crop.bottom,
886 c.requested.crop.getWidth(),
887 c.requested.crop.getHeight(),
888 s.active.w, s.active.h,
889 s.active.crop.left,
890 s.active.crop.top,
891 s.active.crop.right,
892 s.active.crop.bottom,
893 s.active.crop.getWidth(),
894 s.active.crop.getHeight(),
895 s.requested.w, s.requested.h,
896 s.requested.crop.left,
897 s.requested.crop.top,
898 s.requested.crop.right,
899 s.requested.crop.bottom,
900 s.requested.crop.getWidth(),
901 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800902
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700903 // record the new size, form this point on, when the client request
904 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800905 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700906 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800907 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700908
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700909 if (!isFixedSize()) {
910
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700911 const bool resizePending = (c.requested.w != c.active.w) ||
912 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700913
914 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800915 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700916 // if we have a pending resize, unless we are in fixed-size mode.
917 // the drawing state will be updated only once we receive a buffer
918 // with the correct size.
919 //
920 // in particular, we want to make sure the clip (which is part
921 // of the geometry state) is latched together with the size but is
922 // latched immediately when no resizing is involved.
923
924 flags |= eDontUpdateGeometryState;
925 }
926 }
927
Mathias Agopian13127d82013-03-05 17:47:11 -0800928 // always set active to requested, unless we're asked not to
929 // this is used by Layer, which special cases resizes.
930 if (flags & eDontUpdateGeometryState) {
931 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700932 Layer::State& editCurrentState(getCurrentState());
933 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800934 }
935
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700936 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800937 // invalidate and recompute the visible regions if needed
938 flags |= Layer::eVisibleRegion;
939 }
940
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700941 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800942 // invalidate and recompute the visible regions if needed
943 flags |= eVisibleRegion;
944 this->contentDirty = true;
945
946 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700947 const uint8_t type = c.transform.getType();
948 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800949 (type >= Transform::SCALE));
950 }
951
952 // Commit the transaction
953 commitTransaction();
954 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800955}
956
Mathias Agopian13127d82013-03-05 17:47:11 -0800957void Layer::commitTransaction() {
958 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700959}
960
Mathias Agopian13127d82013-03-05 17:47:11 -0800961uint32_t Layer::getTransactionFlags(uint32_t flags) {
962 return android_atomic_and(~flags, &mTransactionFlags) & flags;
963}
964
965uint32_t Layer::setTransactionFlags(uint32_t flags) {
966 return android_atomic_or(flags, &mTransactionFlags);
967}
968
969bool Layer::setPosition(float x, float y) {
970 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
971 return false;
972 mCurrentState.sequence++;
973 mCurrentState.transform.set(x, y);
974 setTransactionFlags(eTransactionNeeded);
975 return true;
976}
977bool Layer::setLayer(uint32_t z) {
978 if (mCurrentState.z == z)
979 return false;
980 mCurrentState.sequence++;
981 mCurrentState.z = z;
982 setTransactionFlags(eTransactionNeeded);
983 return true;
984}
985bool Layer::setSize(uint32_t w, uint32_t h) {
986 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
987 return false;
988 mCurrentState.requested.w = w;
989 mCurrentState.requested.h = h;
990 setTransactionFlags(eTransactionNeeded);
991 return true;
992}
993bool Layer::setAlpha(uint8_t alpha) {
994 if (mCurrentState.alpha == alpha)
995 return false;
996 mCurrentState.sequence++;
997 mCurrentState.alpha = alpha;
998 setTransactionFlags(eTransactionNeeded);
999 return true;
1000}
1001bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
1002 mCurrentState.sequence++;
1003 mCurrentState.transform.set(
1004 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
1005 setTransactionFlags(eTransactionNeeded);
1006 return true;
1007}
1008bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -07001009 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -08001010 setTransactionFlags(eTransactionNeeded);
1011 return true;
1012}
1013bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1014 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1015 if (mCurrentState.flags == newFlags)
1016 return false;
1017 mCurrentState.sequence++;
1018 mCurrentState.flags = newFlags;
1019 setTransactionFlags(eTransactionNeeded);
1020 return true;
1021}
1022bool Layer::setCrop(const Rect& crop) {
1023 if (mCurrentState.requested.crop == crop)
1024 return false;
1025 mCurrentState.sequence++;
1026 mCurrentState.requested.crop = crop;
1027 setTransactionFlags(eTransactionNeeded);
1028 return true;
1029}
1030
1031bool Layer::setLayerStack(uint32_t layerStack) {
1032 if (mCurrentState.layerStack == layerStack)
1033 return false;
1034 mCurrentState.sequence++;
1035 mCurrentState.layerStack = layerStack;
1036 setTransactionFlags(eTransactionNeeded);
1037 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001038}
1039
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001040// ----------------------------------------------------------------------------
1041// pageflip handling...
1042// ----------------------------------------------------------------------------
1043
Dan Stoza6b9454d2014-11-07 16:00:59 -08001044bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1045 Mutex::Autolock lock(mQueueItemLock);
1046 nsecs_t expectedPresent =
1047 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1048 return mQueueItems.empty() ?
1049 false : mQueueItems[0].mTimestamp < expectedPresent;
1050}
1051
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001052bool Layer::onPreComposition() {
1053 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001054 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001055}
1056
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001057void Layer::onPostComposition() {
1058 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001059 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001060 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1061
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001062 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001063 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001064 mFrameTracker.setFrameReadyFence(frameReadyFence);
1065 } else {
1066 // There was no fence for this frame, so assume that it was ready
1067 // to be presented at the desired present time.
1068 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1069 }
1070
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001071 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001072 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001073 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001074 mFrameTracker.setActualPresentFence(presentFence);
1075 } else {
1076 // The HWC doesn't support present fences, so use the refresh
1077 // timestamp instead.
1078 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1079 mFrameTracker.setActualPresentTime(presentTime);
1080 }
1081
1082 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001083 mFrameLatencyNeeded = false;
1084 }
1085}
1086
Mathias Agopianda27af92012-09-13 18:17:13 -07001087bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001088 const Layer::State& s(mDrawingState);
1089 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001090 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001091}
1092
Mathias Agopian4fec8732012-06-29 14:12:52 -07001093Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001094{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001095 ATRACE_CALL();
1096
Jesse Hall399184a2014-03-03 15:42:54 -08001097 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1098 // mSidebandStreamChanged was true
1099 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001100 recomputeVisibleRegions = true;
1101
1102 const State& s(getDrawingState());
1103 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001104 }
1105
Mathias Agopian4fec8732012-06-29 14:12:52 -07001106 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001107 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001108
1109 // if we've already called updateTexImage() without going through
1110 // a composition step, we have to skip this layer at this point
1111 // because we cannot call updateTeximage() without a corresponding
1112 // compositionComplete() call.
1113 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001114 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001115 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001116 }
1117
Jamie Gennis351a5132011-09-14 18:23:37 -07001118 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001119 const State& s(getDrawingState());
1120 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001121 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001122
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001123 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001124 Layer::State& front;
1125 Layer::State& current;
1126 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001127 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001128 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001129 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001130 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001131 recomputeVisibleRegions(recomputeVisibleRegions),
1132 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001133 }
1134
1135 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001136 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001137 if (buf == NULL) {
1138 return false;
1139 }
1140
1141 uint32_t bufWidth = buf->getWidth();
1142 uint32_t bufHeight = buf->getHeight();
1143
1144 // check that we received a buffer of the right size
1145 // (Take the buffer's orientation into account)
1146 if (item.mTransform & Transform::ROT_90) {
1147 swap(bufWidth, bufHeight);
1148 }
1149
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001150 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1151 if (front.active != front.requested) {
1152
1153 if (isFixedSize ||
1154 (bufWidth == front.requested.w &&
1155 bufHeight == front.requested.h))
1156 {
1157 // Here we pretend the transaction happened by updating the
1158 // current and drawing states. Drawing state is only accessed
1159 // in this thread, no need to have it locked
1160 front.active = front.requested;
1161
1162 // We also need to update the current state so that
1163 // we don't end-up overwriting the drawing state with
1164 // this stale current state during the next transaction
1165 //
1166 // NOTE: We don't need to hold the transaction lock here
1167 // because State::active is only accessed from this thread.
1168 current.active = front.active;
1169
1170 // recompute visible region
1171 recomputeVisibleRegions = true;
1172 }
1173
1174 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001175 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001176 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1177 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001178 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001179 front.active.w, front.active.h,
1180 front.active.crop.left,
1181 front.active.crop.top,
1182 front.active.crop.right,
1183 front.active.crop.bottom,
1184 front.active.crop.getWidth(),
1185 front.active.crop.getHeight(),
1186 front.requested.w, front.requested.h,
1187 front.requested.crop.left,
1188 front.requested.crop.top,
1189 front.requested.crop.right,
1190 front.requested.crop.bottom,
1191 front.requested.crop.getWidth(),
1192 front.requested.crop.getHeight());
1193 }
1194
Ruben Brunk1681d952014-06-27 15:51:55 -07001195 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001196 if (front.active.w != bufWidth ||
1197 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001198 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001199 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1200 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001201 return true;
1202 }
1203 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001204
1205 // if the transparent region has changed (this test is
1206 // conservative, but that's fine, worst case we're doing
1207 // a bit of extra work), we latch the new one and we
1208 // trigger a visible-region recompute.
1209 if (!front.activeTransparentRegion.isTriviallyEqual(
1210 front.requestedTransparentRegion)) {
1211 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001212
1213 // We also need to update the current state so that
1214 // we don't end-up overwriting the drawing state with
1215 // this stale current state during the next transaction
1216 //
1217 // NOTE: We don't need to hold the transaction lock here
1218 // because State::active is only accessed from this thread.
1219 current.activeTransparentRegion = front.activeTransparentRegion;
1220
1221 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001222 recomputeVisibleRegions = true;
1223 }
1224
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001225 return false;
1226 }
1227 };
1228
Ruben Brunk1681d952014-06-27 15:51:55 -07001229 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1230 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001231
Andy McFadden41d67d72014-04-25 16:58:34 -07001232 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1233 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001234 if (updateResult == BufferQueue::PRESENT_LATER) {
1235 // Producer doesn't want buffer to be displayed yet. Signal a
1236 // layer update so we check again at the next opportunity.
1237 mFlinger->signalLayerUpdate();
1238 return outDirtyRegion;
1239 }
1240
Dan Stoza6b9454d2014-11-07 16:00:59 -08001241 // Remove this buffer from our internal queue tracker
1242 { // Autolock scope
1243 Mutex::Autolock lock(mQueueItemLock);
1244 mQueueItems.removeAt(0);
1245 }
1246
Andy McFadden1585c4d2013-06-28 13:52:40 -07001247 // Decrement the queued-frames count. Signal another event if we
1248 // have more frames pending.
1249 if (android_atomic_dec(&mQueuedFrames) > 1) {
1250 mFlinger->signalLayerUpdate();
1251 }
1252
1253 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001254 // something happened!
1255 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001256 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001257 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001258
Jamie Gennis351a5132011-09-14 18:23:37 -07001259 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001260 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001261 if (mActiveBuffer == NULL) {
1262 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001263 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001264 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001265
Mathias Agopian4824d402012-06-04 18:16:30 -07001266 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001267 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001268 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001269 // the first time we receive a buffer, we need to trigger a
1270 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001271 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001272 }
1273
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001274 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1275 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1276 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001277 if ((crop != mCurrentCrop) ||
1278 (transform != mCurrentTransform) ||
1279 (scalingMode != mCurrentScalingMode))
1280 {
1281 mCurrentCrop = crop;
1282 mCurrentTransform = transform;
1283 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001284 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001285 }
1286
1287 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001288 uint32_t bufWidth = mActiveBuffer->getWidth();
1289 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001290 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1291 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001292 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001293 }
1294 }
1295
1296 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001297 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001298 recomputeVisibleRegions = true;
1299 }
1300
Mathias Agopian4fec8732012-06-29 14:12:52 -07001301 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001302 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001303
1304 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001305 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001306 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001307 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001308}
1309
Mathias Agopiana67932f2011-04-20 14:20:59 -07001310uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001311{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001312 // TODO: should we do something special if mSecure is set?
1313 if (mProtectedByApp) {
1314 // need a hardware-protected path to external video sink
1315 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001316 }
Riley Andrews03414a12014-07-01 14:22:59 -07001317 if (mPotentialCursor) {
1318 usage |= GraphicBuffer::USAGE_CURSOR;
1319 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001320 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001321 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001322}
1323
Mathias Agopian84300952012-11-21 16:02:13 -08001324void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001325 uint32_t orientation = 0;
1326 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001327 // The transform hint is used to improve performance, but we can
1328 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001329 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001330 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001331 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001332 if (orientation & Transform::ROT_INVALID) {
1333 orientation = 0;
1334 }
1335 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001336 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001337}
1338
Mathias Agopian13127d82013-03-05 17:47:11 -08001339// ----------------------------------------------------------------------------
1340// debugging
1341// ----------------------------------------------------------------------------
1342
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001343void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001344{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001345 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001346
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001347 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001348 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001349 "+ %s %p (%s)\n",
1350 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001351 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001352
Mathias Agopian2ca79392013-04-02 18:30:32 -07001353 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001354 visibleRegion.dump(result, "visibleRegion");
1355 sp<Client> client(mClientRef.promote());
1356
Mathias Agopian74d211a2013-04-22 16:55:35 +02001357 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001358 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1359 "isOpaque=%1d, invalidate=%1d, "
1360 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1361 " client=%p\n",
1362 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1363 s.active.crop.left, s.active.crop.top,
1364 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001365 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001366 s.alpha, s.flags,
1367 s.transform[0][0], s.transform[0][1],
1368 s.transform[1][0], s.transform[1][1],
1369 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001370
1371 sp<const GraphicBuffer> buf0(mActiveBuffer);
1372 uint32_t w0=0, h0=0, s0=0, f0=0;
1373 if (buf0 != 0) {
1374 w0 = buf0->getWidth();
1375 h0 = buf0->getHeight();
1376 s0 = buf0->getStride();
1377 f0 = buf0->format;
1378 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001379 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001380 " "
1381 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1382 " queued-frames=%d, mRefreshPending=%d\n",
1383 mFormat, w0, h0, s0,f0,
1384 mQueuedFrames, mRefreshPending);
1385
Mathias Agopian13127d82013-03-05 17:47:11 -08001386 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001387 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001388 }
1389}
1390
Svetoslavd85084b2014-03-20 10:28:31 -07001391void Layer::dumpFrameStats(String8& result) const {
1392 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001393}
1394
Svetoslavd85084b2014-03-20 10:28:31 -07001395void Layer::clearFrameStats() {
1396 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001397}
1398
Jamie Gennis6547ff42013-07-16 20:12:42 -07001399void Layer::logFrameStats() {
1400 mFrameTracker.logAndResetStats(mName);
1401}
1402
Svetoslavd85084b2014-03-20 10:28:31 -07001403void Layer::getFrameStats(FrameStats* outStats) const {
1404 mFrameTracker.getStats(outStats);
1405}
1406
Mathias Agopian13127d82013-03-05 17:47:11 -08001407// ---------------------------------------------------------------------------
1408
1409Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1410 const sp<Layer>& layer)
1411 : mFlinger(flinger), mLayer(layer) {
1412}
1413
1414Layer::LayerCleaner::~LayerCleaner() {
1415 // destroy client resources
1416 mFlinger->onLayerDestroyed(mLayer);
1417}
1418
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001419// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001420}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001421
1422#if defined(__gl_h_)
1423#error "don't include gl/gl.h in this file"
1424#endif
1425
1426#if defined(__gl2_h_)
1427#error "don't include gl2/gl2.h in this file"
1428#endif