blob: c3e1a768e3e31d75281ed52570ed5ee3d0f719f8 [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
335 // paranoia: make sure the window-crop is constrained in the
336 // window's bounds
337 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
338
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700339 // subtract the transparent region and snap to the bounds
340 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
341
Mathias Agopian13127d82013-03-05 17:47:11 -0800342 if (!activeCrop.isEmpty()) {
343 // Transform the window crop to match the buffer coordinate system,
344 // which means using the inverse of the current transform set on the
345 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700346 uint32_t invTransform = mCurrentTransform;
Michael Lentinef7551402014-08-18 16:35:43 -0700347 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
348 /*
349 * the code below applies the display's inverse transform to the buffer
350 */
351 uint32_t invTransformOrient = hw->getOrientationTransform();
352 // calculate the inverse transform
353 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
354 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
355 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700356 // If the transform has been rotated the axis of flip has been swapped
357 // so we need to swap which flip operations we are performing
358 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
359 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
360 if (is_h_flipped != is_v_flipped) {
361 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
362 NATIVE_WINDOW_TRANSFORM_FLIP_H;
363 }
Michael Lentinef7551402014-08-18 16:35:43 -0700364 }
365 // and apply to the current transform
366 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
367 }
368
Mathias Agopian13127d82013-03-05 17:47:11 -0800369 int winWidth = s.active.w;
370 int winHeight = s.active.h;
371 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
Michael Lentine7b902582014-08-19 18:14:06 -0700372 // If the activeCrop has been rotate the ends are rotated but not
373 // the space itself so when transforming ends back we can't rely on
374 // a modification of the axes of rotation. To account for this we
375 // need to reorient the inverse rotation in terms of the current
376 // axes of rotation.
377 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
378 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
379 if (is_h_flipped == is_v_flipped) {
380 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
381 NATIVE_WINDOW_TRANSFORM_FLIP_H;
382 }
Mathias Agopian13127d82013-03-05 17:47:11 -0800383 winWidth = s.active.h;
384 winHeight = s.active.w;
385 }
386 const Rect winCrop = activeCrop.transform(
Michael Lentinef7551402014-08-18 16:35:43 -0700387 invTransform, s.active.w, s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800388
Mathias Agopian6b442672013-07-09 21:24:52 -0700389 // below, crop is intersected with winCrop expressed in crop's coordinate space
390 float xScale = crop.getWidth() / float(winWidth);
391 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800392
Michael Lentinef7551402014-08-18 16:35:43 -0700393 float insetL = winCrop.left * xScale;
394 float insetT = winCrop.top * yScale;
395 float insetR = (winWidth - winCrop.right ) * xScale;
396 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800397
398 crop.left += insetL;
399 crop.top += insetT;
400 crop.right -= insetR;
401 crop.bottom -= insetB;
402 }
403 return crop;
404}
405
Mathias Agopian4fec8732012-06-29 14:12:52 -0700406void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700407 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700408 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700409{
Mathias Agopian13127d82013-03-05 17:47:11 -0800410 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700411
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700412 // enable this layer
413 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700414
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700415 if (isSecure() && !hw->isSecure()) {
416 layer.setSkip(true);
417 }
418
Mathias Agopian13127d82013-03-05 17:47:11 -0800419 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700420 const State& s(getDrawingState());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800421 if (!isOpaque(s) || s.alpha != 0xFF) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800422 layer.setBlending(mPremultipliedAlpha ?
423 HWC_BLENDING_PREMULT :
424 HWC_BLENDING_COVERAGE);
425 }
426
427 // apply the layer's transform, followed by the display's global transform
428 // here we're guaranteed that the layer's transform preserves rects
Michael Lentine6c925ed2014-09-26 17:55:01 -0700429 Region activeTransparentRegion(s.activeTransparentRegion);
430 if (!s.active.crop.isEmpty()) {
431 Rect activeCrop(s.active.crop);
432 activeCrop = s.transform.transform(activeCrop);
433 activeCrop.intersect(hw->getViewport(), &activeCrop);
434 activeCrop = s.transform.inverse().transform(activeCrop);
435 // mark regions outside the crop as transparent
436 activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
437 activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
438 s.active.w, s.active.h));
439 activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
440 activeCrop.left, activeCrop.bottom));
441 activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
442 s.active.w, activeCrop.bottom));
443 }
444 Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
Mathias Agopian13127d82013-03-05 17:47:11 -0800445 frame.intersect(hw->getViewport(), &frame);
446 const Transform& tr(hw->getTransform());
447 layer.setFrame(tr.transform(frame));
448 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800449 layer.setPlaneAlpha(s.alpha);
450
Mathias Agopian29a367b2011-07-12 14:51:45 -0700451 /*
452 * Transformations are applied in this order:
453 * 1) buffer orientation/flip/mirror
454 * 2) state transformation (window manager)
455 * 3) layer orientation (screen orientation)
456 * (NOTE: the matrices are multiplied in reverse order)
457 */
458
459 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700460 Transform transform(tr * s.transform * bufferOrientation);
461
462 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
463 /*
464 * the code below applies the display's inverse transform to the buffer
465 */
466 uint32_t invTransform = hw->getOrientationTransform();
Michael Lentine14409632014-08-19 11:27:30 -0700467 uint32_t t_orientation = transform.getOrientation();
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700468 // calculate the inverse transform
469 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
470 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
471 NATIVE_WINDOW_TRANSFORM_FLIP_H;
Michael Lentine14409632014-08-19 11:27:30 -0700472 // If the transform has been rotated the axis of flip has been swapped
473 // so we need to swap which flip operations we are performing
474 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
475 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
476 if (is_h_flipped != is_v_flipped) {
477 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
478 NATIVE_WINDOW_TRANSFORM_FLIP_H;
479 }
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700480 }
481 // and apply to the current transform
Michael Lentine14409632014-08-19 11:27:30 -0700482 transform = Transform(t_orientation) * Transform(invTransform);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700483 }
Mathias Agopian29a367b2011-07-12 14:51:45 -0700484
485 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800486 const uint32_t orientation = transform.getOrientation();
487 if (orientation & Transform::ROT_INVALID) {
488 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700489 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700490 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800491 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700492 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700493}
494
Mathias Agopian42977342012-08-05 00:40:46 -0700495void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700496 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800497 // we have to set the visible region on every frame because
498 // we currently free it during onLayerDisplayed(), which is called
499 // after HWComposer::commit() -- every frame.
500 // Apply this display's projection's viewport to the visible region
501 // before giving it to the HWC HAL.
502 const Transform& tr = hw->getTransform();
503 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
504 layer.setVisibleRegionScreen(visible);
505
Jesse Hall399184a2014-03-03 15:42:54 -0800506 if (mSidebandStream.get()) {
507 layer.setSidebandStream(mSidebandStream);
508 } else {
509 // NOTE: buffer can be NULL if the client never drew into this
510 // layer yet, or if we ran out of memory
511 layer.setBuffer(mActiveBuffer);
512 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700513}
Jesse Halldc5b4852012-06-29 15:21:18 -0700514
Dan Stozac7014012014-02-14 15:03:43 -0800515void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700516 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700517 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700518
519 // TODO: there is a possible optimization here: we only need to set the
520 // acquire fence the first time a new buffer is acquired on EACH display.
521
Riley Andrews03414a12014-07-01 14:22:59 -0700522 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800523 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800524 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700525 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700526 if (fenceFd == -1) {
527 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
528 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700529 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700530 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700531 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700532}
533
Riley Andrews03414a12014-07-01 14:22:59 -0700534Rect Layer::getPosition(
535 const sp<const DisplayDevice>& hw)
536{
537 // this gives us only the "orientation" component of the transform
538 const State& s(getCurrentState());
539
540 // apply the layer's transform, followed by the display's global transform
541 // here we're guaranteed that the layer's transform preserves rects
542 Rect win(s.active.w, s.active.h);
543 if (!s.active.crop.isEmpty()) {
544 win.intersect(s.active.crop, &win);
545 }
546 // subtract the transparent region and snap to the bounds
547 Rect bounds = reduce(win, s.activeTransparentRegion);
548 Rect frame(s.transform.transform(bounds));
549 frame.intersect(hw->getViewport(), &frame);
550 const Transform& tr(hw->getTransform());
551 return Rect(tr.transform(frame));
552}
553
Mathias Agopian13127d82013-03-05 17:47:11 -0800554// ---------------------------------------------------------------------------
555// drawing...
556// ---------------------------------------------------------------------------
557
558void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
Dan Stozac7014012014-02-14 15:03:43 -0800559 onDraw(hw, clip, false);
Mathias Agopian13127d82013-03-05 17:47:11 -0800560}
561
Dan Stozac7014012014-02-14 15:03:43 -0800562void Layer::draw(const sp<const DisplayDevice>& hw,
563 bool useIdentityTransform) const {
564 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800565}
566
Dan Stozac7014012014-02-14 15:03:43 -0800567void Layer::draw(const sp<const DisplayDevice>& hw) const {
568 onDraw(hw, Region(hw->bounds()), false);
569}
570
571void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
572 bool useIdentityTransform) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800573{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800574 ATRACE_CALL();
575
Mathias Agopiana67932f2011-04-20 14:20:59 -0700576 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800577 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700578 // in fact never been drawn into. This happens frequently with
579 // SurfaceView because the WindowManager can't know when the client
580 // has drawn the first time.
581
582 // If there is nothing under us, we paint the screen in black, otherwise
583 // we just skip this update.
584
585 // figure out if there is something below us
586 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700587 const SurfaceFlinger::LayerVector& drawingLayers(
588 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700589 const size_t count = drawingLayers.size();
590 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800591 const sp<Layer>& layer(drawingLayers[i]);
592 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700593 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700594 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700595 }
596 // if not everything below us is covered, we plug the holes!
597 Region holes(clip.subtract(under));
598 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700599 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700600 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800601 return;
602 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700603
Andy McFadden97eba892012-12-11 15:21:45 -0800604 // Bind the current buffer to the GL texture, and wait for it to be
605 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800606 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
607 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800608 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700609 // Go ahead and draw the buffer anyway; no matter what we do the screen
610 // is probably going to have something visibly wrong.
611 }
612
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700613 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
614
Mathias Agopian875d8e12013-06-07 15:35:48 -0700615 RenderEngine& engine(mFlinger->getRenderEngine());
616
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700617 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700618 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700619 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700620
621 // Query the texture matrix given our current filtering mode.
622 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800623 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
624 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700625
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700626 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
627
628 /*
629 * the code below applies the display's inverse transform to the texture transform
630 */
631
632 // create a 4x4 transform matrix from the display transform flags
633 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
634 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
635 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
636
637 mat4 tr;
638 uint32_t transform = hw->getOrientationTransform();
639 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
640 tr = tr * rot90;
641 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
642 tr = tr * flipH;
643 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
644 tr = tr * flipV;
645
646 // calculate the inverse
647 tr = inverse(tr);
648
649 // and finally apply it to the original texture matrix
650 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
651 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
652 }
653
Jamie Genniscbb1a952012-05-08 17:05:52 -0700654 // Set things up for texturing.
Mathias Agopian49457ac2013-08-14 18:20:17 -0700655 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
656 mTexture.setFiltering(useFiltering);
657 mTexture.setMatrix(textureMatrix);
658
659 engine.setupLayerTexturing(mTexture);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700660 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700661 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700662 }
Dan Stozac7014012014-02-14 15:03:43 -0800663 drawWithOpenGL(hw, clip, useIdentityTransform);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700664 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800665}
666
Mathias Agopian13127d82013-03-05 17:47:11 -0800667
Dan Stozac7014012014-02-14 15:03:43 -0800668void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
669 const Region& /* clip */, float red, float green, float blue,
670 float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800671{
Mathias Agopian19733a32013-08-28 18:13:56 -0700672 RenderEngine& engine(mFlinger->getRenderEngine());
Dan Stozac7014012014-02-14 15:03:43 -0800673 computeGeometry(hw, mMesh, false);
Mathias Agopian19733a32013-08-28 18:13:56 -0700674 engine.setupFillWithColor(red, green, blue, alpha);
675 engine.drawMesh(mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800676}
677
678void Layer::clearWithOpenGL(
679 const sp<const DisplayDevice>& hw, const Region& clip) const {
680 clearWithOpenGL(hw, clip, 0,0,0,0);
681}
682
Dan Stozac7014012014-02-14 15:03:43 -0800683void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
684 const Region& /* clip */, bool useIdentityTransform) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800685 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700686 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800687
Dan Stozac7014012014-02-14 15:03:43 -0800688 computeGeometry(hw, mMesh, useIdentityTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800689
Mathias Agopian13127d82013-03-05 17:47:11 -0800690 /*
691 * NOTE: the way we compute the texture coordinates here produces
692 * different results than when we take the HWC path -- in the later case
693 * the "source crop" is rounded to texel boundaries.
694 * This can produce significantly different results when the texture
695 * is scaled by a large amount.
696 *
697 * The GL code below is more logical (imho), and the difference with
698 * HWC is due to a limitation of the HWC API to integers -- a question
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700699 * is suspend is whether we should ignore this problem or revert to
Mathias Agopian13127d82013-03-05 17:47:11 -0800700 * GL composition when a buffer scaling is applied (maybe with some
701 * minimal value)? Or, we could make GL behave like HWC -- but this feel
702 * like more of a hack.
703 */
704 const Rect win(computeBounds());
705
Mathias Agopian3f844832013-08-07 21:24:32 -0700706 float left = float(win.left) / float(s.active.w);
707 float top = float(win.top) / float(s.active.h);
708 float right = float(win.right) / float(s.active.w);
709 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800710
Mathias Agopian875d8e12013-06-07 15:35:48 -0700711 // TODO: we probably want to generate the texture coords with the mesh
712 // here we assume that we only have 4 vertices
Mathias Agopianff2ed702013-09-01 21:36:12 -0700713 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
714 texCoords[0] = vec2(left, 1.0f - top);
715 texCoords[1] = vec2(left, 1.0f - bottom);
716 texCoords[2] = vec2(right, 1.0f - bottom);
717 texCoords[3] = vec2(right, 1.0f - top);
Mathias Agopian13127d82013-03-05 17:47:11 -0800718
Mathias Agopian875d8e12013-06-07 15:35:48 -0700719 RenderEngine& engine(mFlinger->getRenderEngine());
Andy McFadden4125a4f2014-01-29 17:17:11 -0800720 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700721 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700722 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800723}
724
Ruben Brunk1681d952014-06-27 15:51:55 -0700725uint32_t Layer::getProducerStickyTransform() const {
726 int producerStickyTransform = 0;
727 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
728 if (ret != OK) {
729 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
730 strerror(-ret), ret);
731 return 0;
732 }
733 return static_cast<uint32_t>(producerStickyTransform);
734}
735
Mathias Agopian13127d82013-03-05 17:47:11 -0800736void Layer::setFiltering(bool filtering) {
737 mFiltering = filtering;
738}
739
740bool Layer::getFiltering() const {
741 return mFiltering;
742}
743
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800744// As documented in libhardware header, formats in the range
745// 0x100 - 0x1FF are specific to the HAL implementation, and
746// are known to have no alpha channel
747// TODO: move definition for device-specific range into
748// hardware.h, instead of using hard-coded values here.
749#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
750
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700751bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700752 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
753 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800754 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700755 switch (format) {
756 case HAL_PIXEL_FORMAT_RGBA_8888:
757 case HAL_PIXEL_FORMAT_BGRA_8888:
Jesse Hallc2e41222013-08-08 13:40:22 -0700758 case HAL_PIXEL_FORMAT_sRGB_A_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700759 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700760 }
761 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700762 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800763}
764
Mathias Agopian13127d82013-03-05 17:47:11 -0800765// ----------------------------------------------------------------------------
766// local state
767// ----------------------------------------------------------------------------
768
Dan Stozac7014012014-02-14 15:03:43 -0800769void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
770 bool useIdentityTransform) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800771{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700772 const Layer::State& s(getDrawingState());
Dan Stozac7014012014-02-14 15:03:43 -0800773 const Transform tr(useIdentityTransform ?
774 hw->getTransform() : hw->getTransform() * s.transform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800775 const uint32_t hw_h = hw->getHeight();
776 Rect win(s.active.w, s.active.h);
777 if (!s.active.crop.isEmpty()) {
778 win.intersect(s.active.crop, &win);
779 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700780 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700781 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700782
Mathias Agopianff2ed702013-09-01 21:36:12 -0700783 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
784 position[0] = tr.transform(win.left, win.top);
785 position[1] = tr.transform(win.left, win.bottom);
786 position[2] = tr.transform(win.right, win.bottom);
787 position[3] = tr.transform(win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700788 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700789 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800790 }
791}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800792
Andy McFadden4125a4f2014-01-29 17:17:11 -0800793bool Layer::isOpaque(const Layer::State& s) const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700794{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700795 // if we don't have a buffer yet, we're translucent regardless of the
796 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700797 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700798 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700799 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700800
801 // if the layer has the opaque flag, then we're always opaque,
802 // otherwise we use the current buffer's format.
Andy McFadden4125a4f2014-01-29 17:17:11 -0800803 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700804}
805
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800806bool Layer::isProtected() const
807{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700808 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800809 return (activeBuffer != 0) &&
810 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
811}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700812
Mathias Agopian13127d82013-03-05 17:47:11 -0800813bool Layer::isFixedSize() const {
814 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
815}
816
817bool Layer::isCropped() const {
818 return !mCurrentCrop.isEmpty();
819}
820
821bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
822 return mNeedsFiltering || hw->needsFiltering();
823}
824
825void Layer::setVisibleRegion(const Region& visibleRegion) {
826 // always called from main thread
827 this->visibleRegion = visibleRegion;
828}
829
830void Layer::setCoveredRegion(const Region& coveredRegion) {
831 // always called from main thread
832 this->coveredRegion = coveredRegion;
833}
834
835void Layer::setVisibleNonTransparentRegion(const Region&
836 setVisibleNonTransparentRegion) {
837 // always called from main thread
838 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
839}
840
841// ----------------------------------------------------------------------------
842// transaction
843// ----------------------------------------------------------------------------
844
845uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800846 ATRACE_CALL();
847
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700848 const Layer::State& s(getDrawingState());
849 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800850
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700851 const bool sizeChanged = (c.requested.w != s.requested.w) ||
852 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700853
854 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700855 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000856 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700857 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700858 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
859 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
860 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
861 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700862 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
863 c.active.w, c.active.h,
864 c.active.crop.left,
865 c.active.crop.top,
866 c.active.crop.right,
867 c.active.crop.bottom,
868 c.active.crop.getWidth(),
869 c.active.crop.getHeight(),
870 c.requested.w, c.requested.h,
871 c.requested.crop.left,
872 c.requested.crop.top,
873 c.requested.crop.right,
874 c.requested.crop.bottom,
875 c.requested.crop.getWidth(),
876 c.requested.crop.getHeight(),
877 s.active.w, s.active.h,
878 s.active.crop.left,
879 s.active.crop.top,
880 s.active.crop.right,
881 s.active.crop.bottom,
882 s.active.crop.getWidth(),
883 s.active.crop.getHeight(),
884 s.requested.w, s.requested.h,
885 s.requested.crop.left,
886 s.requested.crop.top,
887 s.requested.crop.right,
888 s.requested.crop.bottom,
889 s.requested.crop.getWidth(),
890 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800891
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700892 // record the new size, form this point on, when the client request
893 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800894 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700895 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800896 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700897
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700898 if (!isFixedSize()) {
899
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700900 const bool resizePending = (c.requested.w != c.active.w) ||
901 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700902
903 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800904 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700905 // if we have a pending resize, unless we are in fixed-size mode.
906 // the drawing state will be updated only once we receive a buffer
907 // with the correct size.
908 //
909 // in particular, we want to make sure the clip (which is part
910 // of the geometry state) is latched together with the size but is
911 // latched immediately when no resizing is involved.
912
913 flags |= eDontUpdateGeometryState;
914 }
915 }
916
Mathias Agopian13127d82013-03-05 17:47:11 -0800917 // always set active to requested, unless we're asked not to
918 // this is used by Layer, which special cases resizes.
919 if (flags & eDontUpdateGeometryState) {
920 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700921 Layer::State& editCurrentState(getCurrentState());
922 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800923 }
924
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700925 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800926 // invalidate and recompute the visible regions if needed
927 flags |= Layer::eVisibleRegion;
928 }
929
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700930 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800931 // invalidate and recompute the visible regions if needed
932 flags |= eVisibleRegion;
933 this->contentDirty = true;
934
935 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700936 const uint8_t type = c.transform.getType();
937 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800938 (type >= Transform::SCALE));
939 }
940
941 // Commit the transaction
942 commitTransaction();
943 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800944}
945
Mathias Agopian13127d82013-03-05 17:47:11 -0800946void Layer::commitTransaction() {
947 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700948}
949
Mathias Agopian13127d82013-03-05 17:47:11 -0800950uint32_t Layer::getTransactionFlags(uint32_t flags) {
951 return android_atomic_and(~flags, &mTransactionFlags) & flags;
952}
953
954uint32_t Layer::setTransactionFlags(uint32_t flags) {
955 return android_atomic_or(flags, &mTransactionFlags);
956}
957
958bool Layer::setPosition(float x, float y) {
959 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
960 return false;
961 mCurrentState.sequence++;
962 mCurrentState.transform.set(x, y);
963 setTransactionFlags(eTransactionNeeded);
964 return true;
965}
966bool Layer::setLayer(uint32_t z) {
967 if (mCurrentState.z == z)
968 return false;
969 mCurrentState.sequence++;
970 mCurrentState.z = z;
971 setTransactionFlags(eTransactionNeeded);
972 return true;
973}
974bool Layer::setSize(uint32_t w, uint32_t h) {
975 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
976 return false;
977 mCurrentState.requested.w = w;
978 mCurrentState.requested.h = h;
979 setTransactionFlags(eTransactionNeeded);
980 return true;
981}
982bool Layer::setAlpha(uint8_t alpha) {
983 if (mCurrentState.alpha == alpha)
984 return false;
985 mCurrentState.sequence++;
986 mCurrentState.alpha = alpha;
987 setTransactionFlags(eTransactionNeeded);
988 return true;
989}
990bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
991 mCurrentState.sequence++;
992 mCurrentState.transform.set(
993 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
994 setTransactionFlags(eTransactionNeeded);
995 return true;
996}
997bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700998 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800999 setTransactionFlags(eTransactionNeeded);
1000 return true;
1001}
1002bool Layer::setFlags(uint8_t flags, uint8_t mask) {
1003 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
1004 if (mCurrentState.flags == newFlags)
1005 return false;
1006 mCurrentState.sequence++;
1007 mCurrentState.flags = newFlags;
1008 setTransactionFlags(eTransactionNeeded);
1009 return true;
1010}
1011bool Layer::setCrop(const Rect& crop) {
1012 if (mCurrentState.requested.crop == crop)
1013 return false;
1014 mCurrentState.sequence++;
1015 mCurrentState.requested.crop = crop;
1016 setTransactionFlags(eTransactionNeeded);
1017 return true;
1018}
1019
1020bool Layer::setLayerStack(uint32_t layerStack) {
1021 if (mCurrentState.layerStack == layerStack)
1022 return false;
1023 mCurrentState.sequence++;
1024 mCurrentState.layerStack = layerStack;
1025 setTransactionFlags(eTransactionNeeded);
1026 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001027}
1028
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001029// ----------------------------------------------------------------------------
1030// pageflip handling...
1031// ----------------------------------------------------------------------------
1032
Dan Stoza6b9454d2014-11-07 16:00:59 -08001033bool Layer::shouldPresentNow(const DispSync& dispSync) const {
1034 Mutex::Autolock lock(mQueueItemLock);
1035 nsecs_t expectedPresent =
1036 mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
1037 return mQueueItems.empty() ?
1038 false : mQueueItems[0].mTimestamp < expectedPresent;
1039}
1040
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001041bool Layer::onPreComposition() {
1042 mRefreshPending = false;
Jesse Hall399184a2014-03-03 15:42:54 -08001043 return mQueuedFrames > 0 || mSidebandStreamChanged;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001044}
1045
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001046void Layer::onPostComposition() {
1047 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001048 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001049 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1050
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001051 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -08001052 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001053 mFrameTracker.setFrameReadyFence(frameReadyFence);
1054 } else {
1055 // There was no fence for this frame, so assume that it was ready
1056 // to be presented at the desired present time.
1057 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1058 }
1059
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001060 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -08001061 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -08001062 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -08001063 mFrameTracker.setActualPresentFence(presentFence);
1064 } else {
1065 // The HWC doesn't support present fences, so use the refresh
1066 // timestamp instead.
1067 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1068 mFrameTracker.setActualPresentTime(presentTime);
1069 }
1070
1071 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -07001072 mFrameLatencyNeeded = false;
1073 }
1074}
1075
Mathias Agopianda27af92012-09-13 18:17:13 -07001076bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001077 const Layer::State& s(mDrawingState);
1078 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
Wonsik Kimafe30812014-03-31 23:16:08 +09001079 && (mActiveBuffer != NULL || mSidebandStream != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -07001080}
1081
Mathias Agopian4fec8732012-06-29 14:12:52 -07001082Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001083{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -08001084 ATRACE_CALL();
1085
Jesse Hall399184a2014-03-03 15:42:54 -08001086 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1087 // mSidebandStreamChanged was true
1088 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
Jesse Hall5bf786d2014-09-30 10:35:11 -07001089 recomputeVisibleRegions = true;
1090
1091 const State& s(getDrawingState());
1092 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
Jesse Hall399184a2014-03-03 15:42:54 -08001093 }
1094
Mathias Agopian4fec8732012-06-29 14:12:52 -07001095 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -07001096 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001097
1098 // if we've already called updateTexImage() without going through
1099 // a composition step, we have to skip this layer at this point
1100 // because we cannot call updateTeximage() without a corresponding
1101 // compositionComplete() call.
1102 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -08001103 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -07001104 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -08001105 }
1106
Jamie Gennis351a5132011-09-14 18:23:37 -07001107 // Capture the old state of the layer for comparisons later
Andy McFadden4125a4f2014-01-29 17:17:11 -08001108 const State& s(getDrawingState());
1109 const bool oldOpacity = isOpaque(s);
Jamie Gennis351a5132011-09-14 18:23:37 -07001110 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -07001111
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001112 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001113 Layer::State& front;
1114 Layer::State& current;
1115 bool& recomputeVisibleRegions;
Ruben Brunk1681d952014-06-27 15:51:55 -07001116 bool stickyTransformSet;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001117 Reject(Layer::State& front, Layer::State& current,
Ruben Brunk1681d952014-06-27 15:51:55 -07001118 bool& recomputeVisibleRegions, bool stickySet)
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001119 : front(front), current(current),
Ruben Brunk1681d952014-06-27 15:51:55 -07001120 recomputeVisibleRegions(recomputeVisibleRegions),
1121 stickyTransformSet(stickySet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001122 }
1123
1124 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -07001125 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001126 if (buf == NULL) {
1127 return false;
1128 }
1129
1130 uint32_t bufWidth = buf->getWidth();
1131 uint32_t bufHeight = buf->getHeight();
1132
1133 // check that we received a buffer of the right size
1134 // (Take the buffer's orientation into account)
1135 if (item.mTransform & Transform::ROT_90) {
1136 swap(bufWidth, bufHeight);
1137 }
1138
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001139 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1140 if (front.active != front.requested) {
1141
1142 if (isFixedSize ||
1143 (bufWidth == front.requested.w &&
1144 bufHeight == front.requested.h))
1145 {
1146 // Here we pretend the transaction happened by updating the
1147 // current and drawing states. Drawing state is only accessed
1148 // in this thread, no need to have it locked
1149 front.active = front.requested;
1150
1151 // We also need to update the current state so that
1152 // we don't end-up overwriting the drawing state with
1153 // this stale current state during the next transaction
1154 //
1155 // NOTE: We don't need to hold the transaction lock here
1156 // because State::active is only accessed from this thread.
1157 current.active = front.active;
1158
1159 // recompute visible region
1160 recomputeVisibleRegions = true;
1161 }
1162
1163 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001164 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001165 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1166 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001167 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001168 front.active.w, front.active.h,
1169 front.active.crop.left,
1170 front.active.crop.top,
1171 front.active.crop.right,
1172 front.active.crop.bottom,
1173 front.active.crop.getWidth(),
1174 front.active.crop.getHeight(),
1175 front.requested.w, front.requested.h,
1176 front.requested.crop.left,
1177 front.requested.crop.top,
1178 front.requested.crop.right,
1179 front.requested.crop.bottom,
1180 front.requested.crop.getWidth(),
1181 front.requested.crop.getHeight());
1182 }
1183
Ruben Brunk1681d952014-06-27 15:51:55 -07001184 if (!isFixedSize && !stickyTransformSet) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001185 if (front.active.w != bufWidth ||
1186 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001187 // reject this buffer
Ruben Brunk1681d952014-06-27 15:51:55 -07001188 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1189 bufWidth, bufHeight, front.active.w, front.active.h);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001190 return true;
1191 }
1192 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001193
1194 // if the transparent region has changed (this test is
1195 // conservative, but that's fine, worst case we're doing
1196 // a bit of extra work), we latch the new one and we
1197 // trigger a visible-region recompute.
1198 if (!front.activeTransparentRegion.isTriviallyEqual(
1199 front.requestedTransparentRegion)) {
1200 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001201
1202 // We also need to update the current state so that
1203 // we don't end-up overwriting the drawing state with
1204 // this stale current state during the next transaction
1205 //
1206 // NOTE: We don't need to hold the transaction lock here
1207 // because State::active is only accessed from this thread.
1208 current.activeTransparentRegion = front.activeTransparentRegion;
1209
1210 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001211 recomputeVisibleRegions = true;
1212 }
1213
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001214 return false;
1215 }
1216 };
1217
Ruben Brunk1681d952014-06-27 15:51:55 -07001218 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1219 getProducerStickyTransform() != 0);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001220
Andy McFadden41d67d72014-04-25 16:58:34 -07001221 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1222 mFlinger->mPrimaryDispSync);
Andy McFadden1585c4d2013-06-28 13:52:40 -07001223 if (updateResult == BufferQueue::PRESENT_LATER) {
1224 // Producer doesn't want buffer to be displayed yet. Signal a
1225 // layer update so we check again at the next opportunity.
1226 mFlinger->signalLayerUpdate();
1227 return outDirtyRegion;
1228 }
1229
Dan Stoza6b9454d2014-11-07 16:00:59 -08001230 // Remove this buffer from our internal queue tracker
1231 { // Autolock scope
1232 Mutex::Autolock lock(mQueueItemLock);
1233 mQueueItems.removeAt(0);
1234 }
1235
Andy McFadden1585c4d2013-06-28 13:52:40 -07001236 // Decrement the queued-frames count. Signal another event if we
1237 // have more frames pending.
1238 if (android_atomic_dec(&mQueuedFrames) > 1) {
1239 mFlinger->signalLayerUpdate();
1240 }
1241
1242 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001243 // something happened!
1244 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001245 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001246 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001247
Jamie Gennis351a5132011-09-14 18:23:37 -07001248 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001249 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001250 if (mActiveBuffer == NULL) {
1251 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001252 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001253 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001254
Mathias Agopian4824d402012-06-04 18:16:30 -07001255 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001256 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001257 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001258 // the first time we receive a buffer, we need to trigger a
1259 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001260 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001261 }
1262
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001263 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1264 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1265 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001266 if ((crop != mCurrentCrop) ||
1267 (transform != mCurrentTransform) ||
1268 (scalingMode != mCurrentScalingMode))
1269 {
1270 mCurrentCrop = crop;
1271 mCurrentTransform = transform;
1272 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001273 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001274 }
1275
1276 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001277 uint32_t bufWidth = mActiveBuffer->getWidth();
1278 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001279 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1280 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001281 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001282 }
1283 }
1284
1285 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
Andy McFadden4125a4f2014-01-29 17:17:11 -08001286 if (oldOpacity != isOpaque(s)) {
Mathias Agopian702634a2012-05-23 17:50:31 -07001287 recomputeVisibleRegions = true;
1288 }
1289
Mathias Agopian4fec8732012-06-29 14:12:52 -07001290 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001291 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001292
1293 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001294 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001295 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001296 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001297}
1298
Mathias Agopiana67932f2011-04-20 14:20:59 -07001299uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001300{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001301 // TODO: should we do something special if mSecure is set?
1302 if (mProtectedByApp) {
1303 // need a hardware-protected path to external video sink
1304 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001305 }
Riley Andrews03414a12014-07-01 14:22:59 -07001306 if (mPotentialCursor) {
1307 usage |= GraphicBuffer::USAGE_CURSOR;
1308 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001309 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001310 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001311}
1312
Mathias Agopian84300952012-11-21 16:02:13 -08001313void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001314 uint32_t orientation = 0;
1315 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001316 // The transform hint is used to improve performance, but we can
1317 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001318 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001319 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001320 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001321 if (orientation & Transform::ROT_INVALID) {
1322 orientation = 0;
1323 }
1324 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001325 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001326}
1327
Mathias Agopian13127d82013-03-05 17:47:11 -08001328// ----------------------------------------------------------------------------
1329// debugging
1330// ----------------------------------------------------------------------------
1331
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001332void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001333{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001334 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001335
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001336 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001337 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001338 "+ %s %p (%s)\n",
1339 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001340 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001341
Mathias Agopian2ca79392013-04-02 18:30:32 -07001342 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001343 visibleRegion.dump(result, "visibleRegion");
1344 sp<Client> client(mClientRef.promote());
1345
Mathias Agopian74d211a2013-04-22 16:55:35 +02001346 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001347 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1348 "isOpaque=%1d, invalidate=%1d, "
1349 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1350 " client=%p\n",
1351 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1352 s.active.crop.left, s.active.crop.top,
1353 s.active.crop.right, s.active.crop.bottom,
Andy McFadden4125a4f2014-01-29 17:17:11 -08001354 isOpaque(s), contentDirty,
Mathias Agopian13127d82013-03-05 17:47:11 -08001355 s.alpha, s.flags,
1356 s.transform[0][0], s.transform[0][1],
1357 s.transform[1][0], s.transform[1][1],
1358 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001359
1360 sp<const GraphicBuffer> buf0(mActiveBuffer);
1361 uint32_t w0=0, h0=0, s0=0, f0=0;
1362 if (buf0 != 0) {
1363 w0 = buf0->getWidth();
1364 h0 = buf0->getHeight();
1365 s0 = buf0->getStride();
1366 f0 = buf0->format;
1367 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001368 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001369 " "
1370 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1371 " queued-frames=%d, mRefreshPending=%d\n",
1372 mFormat, w0, h0, s0,f0,
1373 mQueuedFrames, mRefreshPending);
1374
Mathias Agopian13127d82013-03-05 17:47:11 -08001375 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001376 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001377 }
1378}
1379
Svetoslavd85084b2014-03-20 10:28:31 -07001380void Layer::dumpFrameStats(String8& result) const {
1381 mFrameTracker.dumpStats(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001382}
1383
Svetoslavd85084b2014-03-20 10:28:31 -07001384void Layer::clearFrameStats() {
1385 mFrameTracker.clearStats();
Mathias Agopian13127d82013-03-05 17:47:11 -08001386}
1387
Jamie Gennis6547ff42013-07-16 20:12:42 -07001388void Layer::logFrameStats() {
1389 mFrameTracker.logAndResetStats(mName);
1390}
1391
Svetoslavd85084b2014-03-20 10:28:31 -07001392void Layer::getFrameStats(FrameStats* outStats) const {
1393 mFrameTracker.getStats(outStats);
1394}
1395
Mathias Agopian13127d82013-03-05 17:47:11 -08001396// ---------------------------------------------------------------------------
1397
1398Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1399 const sp<Layer>& layer)
1400 : mFlinger(flinger), mLayer(layer) {
1401}
1402
1403Layer::LayerCleaner::~LayerCleaner() {
1404 // destroy client resources
1405 mFlinger->onLayerDestroyed(mLayer);
1406}
1407
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001408// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001409}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001410
1411#if defined(__gl_h_)
1412#error "don't include gl/gl.h in this file"
1413#endif
1414
1415#if defined(__gl2_h_)
1416#error "don't include gl2/gl2.h in this file"
1417#endif