blob: a63a80a29b3c1f40b9f62cccb84c6924c9d963d4 [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>
30#include <utils/StopWatch.h>
Jamie Gennis1c8e95c2012-02-23 19:27:23 -080031#include <utils/Trace.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080032
Mathias Agopian3330b202009-10-05 17:07:12 -070033#include <ui/GraphicBuffer.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include <ui/PixelFormat.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080035
Mathias Agopian90ac7992012-02-25 18:48:35 -080036#include <gui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080037
38#include "clz.h"
Mathias Agopian3e25fd82013-04-22 17:52:16 +020039#include "Colorizer.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070040#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080041#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "SurfaceFlinger.h"
Mathias Agopiana67932f2011-04-20 14:20:59 -070043#include "SurfaceTextureLayer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080044
Mathias Agopian1b031492012-06-20 17:51:20 -070045#include "DisplayHardware/HWComposer.h"
46
Mathias Agopian875d8e12013-06-07 15:35:48 -070047#include "RenderEngine/RenderEngine.h"
48
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049#define DEBUG_RESIZE 0
50
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080051namespace android {
52
53// ---------------------------------------------------------------------------
54
Mathias Agopian13127d82013-03-05 17:47:11 -080055int32_t Layer::sSequence = 1;
56
Mathias Agopian4d9b8222013-03-12 17:11:48 -070057Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
58 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080059 : contentDirty(false),
60 sequence(uint32_t(android_atomic_inc(&sSequence))),
61 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070062 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080063 mPremultipliedAlpha(true),
64 mName("unnamed"),
65 mDebug(false),
66 mFormat(PIXEL_FORMAT_NONE),
Mathias Agopian13127d82013-03-05 17:47:11 -080067 mOpaqueLayer(true),
68 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070069 mQueuedFrames(0),
70 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070071 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070072 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080073 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080074 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080075 mFiltering(false),
76 mNeedsFiltering(false),
Mathias Agopian5cdc8992013-08-13 20:51:23 -070077 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070078 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080079 mProtectedByApp(false),
80 mHasSurface(false),
81 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080082{
Mathias Agopiana67932f2011-04-20 14:20:59 -070083 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070084 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070085
86 uint32_t layerFlags = 0;
87 if (flags & ISurfaceComposerClient::eHidden)
88 layerFlags = layer_state_t::eLayerHidden;
89
90 if (flags & ISurfaceComposerClient::eNonPremultiplied)
91 mPremultipliedAlpha = false;
92
93 mName = name;
94
95 mCurrentState.active.w = w;
96 mCurrentState.active.h = h;
97 mCurrentState.active.crop.makeInvalid();
98 mCurrentState.z = 0;
99 mCurrentState.alpha = 0xFF;
100 mCurrentState.layerStack = 0;
101 mCurrentState.flags = layerFlags;
102 mCurrentState.sequence = 0;
103 mCurrentState.transform.set(0, 0);
104 mCurrentState.requested = mCurrentState.active;
105
106 // drawing state & current state are identical
107 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700108
109 nsecs_t displayPeriod =
110 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
111 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800112}
113
Mathias Agopian3f844832013-08-07 21:24:32 -0700114void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800115 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700116 mBufferQueue = new SurfaceTextureLayer(mFlinger);
Mathias Agopian3f844832013-08-07 21:24:32 -0700117 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800118 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
119 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700120 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800121
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700122#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
123#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800124 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700125#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800126 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800127#endif
Andy McFadden69052052012-09-14 16:10:11 -0700128
Mathias Agopian84300952012-11-21 16:02:13 -0800129 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
130 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700131}
132
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700133Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800134 sp<Client> c(mClientRef.promote());
135 if (c != 0) {
136 c->detachLayer(this);
137 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700138 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700139 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700140}
141
Mathias Agopian13127d82013-03-05 17:47:11 -0800142// ---------------------------------------------------------------------------
143// callbacks
144// ---------------------------------------------------------------------------
145
146void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
147 HWComposer::HWCLayerInterface* layer) {
148 if (layer) {
149 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700150 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800151 }
152}
153
Igor Murashkina4a31492012-10-29 13:36:11 -0700154void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700155 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800156 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700157}
158
Mathias Agopian67106042013-03-14 19:18:13 -0700159// called with SurfaceFlinger::mStateLock from the drawing thread after
160// the layer has been remove from the current state list (and just before
161// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800162void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800163 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700164}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700165
Mathias Agopian13127d82013-03-05 17:47:11 -0800166// ---------------------------------------------------------------------------
167// set-up
168// ---------------------------------------------------------------------------
169
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700170const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800171 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800172}
173
Mathias Agopianf9d93272009-06-19 17:00:27 -0700174status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800175 PixelFormat format, uint32_t flags)
176{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700177 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700178 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700179
180 // never allow a surface larger than what our underlying GL implementation
181 // can handle.
182 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800183 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700184 return BAD_VALUE;
185 }
186
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700187 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700188
Mathias Agopian3165cc22012-08-08 19:42:09 -0700189 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
190 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
191 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700192 mCurrentOpacity = getOpacityForFormat(format);
193
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800194 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
195 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
196 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700197
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800198 return NO_ERROR;
199}
200
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700201sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800202 Mutex::Autolock _l(mLock);
203
204 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700205 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800206
207 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700208
209 /*
210 * The layer handle is just a BBinder object passed to the client
211 * (remote process) -- we don't keep any reference on our side such that
212 * the dtor is called when the remote side let go of its reference.
213 *
214 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
215 * this layer when the handle is destroyed.
216 */
217
218 class Handle : public BBinder, public LayerCleaner {
219 wp<const Layer> mOwner;
220 public:
221 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
222 : LayerCleaner(flinger, layer), mOwner(layer) {
223 }
224 };
225
226 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800227}
228
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700229sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
230 return mBufferQueue;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700231}
232
Mathias Agopian13127d82013-03-05 17:47:11 -0800233// ---------------------------------------------------------------------------
234// h/w composer set-up
235// ---------------------------------------------------------------------------
236
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800237Rect Layer::getContentCrop() const {
238 // this is the crop rectangle that applies to the buffer
239 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700240 Rect crop;
241 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800242 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700243 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800244 } else if (mActiveBuffer != NULL) {
245 // otherwise we use the whole buffer
246 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700247 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800248 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700249 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700250 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700251 return crop;
252}
253
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700254static Rect reduce(const Rect& win, const Region& exclude) {
255 if (CC_LIKELY(exclude.isEmpty())) {
256 return win;
257 }
258 if (exclude.isRect()) {
259 return win.reduce(exclude.getBounds());
260 }
261 return Region(win).subtract(exclude).getBounds();
262}
263
Mathias Agopian13127d82013-03-05 17:47:11 -0800264Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700265 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800266 Rect win(s.active.w, s.active.h);
267 if (!s.active.crop.isEmpty()) {
268 win.intersect(s.active.crop, &win);
269 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700270 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700271 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800272}
273
Mathias Agopian6b442672013-07-09 21:24:52 -0700274FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800275 // the content crop is the area of the content that gets scaled to the
276 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700277 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800278
279 // the active.crop is the area of the window that gets cropped, but not
280 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700281 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800282
283 // apply the projection's clipping to the window crop in
284 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700285 // if there are no window scaling involved, this operation will map to full
286 // pixels in the buffer.
287 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
288 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian13127d82013-03-05 17:47:11 -0800289 Rect activeCrop(s.transform.transform(s.active.crop));
290 activeCrop.intersect(hw->getViewport(), &activeCrop);
291 activeCrop = s.transform.inverse().transform(activeCrop);
292
293 // paranoia: make sure the window-crop is constrained in the
294 // window's bounds
295 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
296
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700297 // subtract the transparent region and snap to the bounds
298 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
299
Mathias Agopian13127d82013-03-05 17:47:11 -0800300 if (!activeCrop.isEmpty()) {
301 // Transform the window crop to match the buffer coordinate system,
302 // which means using the inverse of the current transform set on the
303 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700304 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800305 int winWidth = s.active.w;
306 int winHeight = s.active.h;
307 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
308 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
309 NATIVE_WINDOW_TRANSFORM_FLIP_H;
310 winWidth = s.active.h;
311 winHeight = s.active.w;
312 }
313 const Rect winCrop = activeCrop.transform(
314 invTransform, s.active.w, s.active.h);
315
Mathias Agopian6b442672013-07-09 21:24:52 -0700316 // below, crop is intersected with winCrop expressed in crop's coordinate space
317 float xScale = crop.getWidth() / float(winWidth);
318 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800319
Mathias Agopian6b442672013-07-09 21:24:52 -0700320 float insetL = winCrop.left * xScale;
321 float insetT = winCrop.top * yScale;
322 float insetR = (winWidth - winCrop.right ) * xScale;
323 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800324
325 crop.left += insetL;
326 crop.top += insetT;
327 crop.right -= insetR;
328 crop.bottom -= insetB;
329 }
330 return crop;
331}
332
Mathias Agopian4fec8732012-06-29 14:12:52 -0700333void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700334 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700335 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700336{
Mathias Agopian13127d82013-03-05 17:47:11 -0800337 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700338
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700339 // enable this layer
340 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700341
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700342 if (isSecure() && !hw->isSecure()) {
343 layer.setSkip(true);
344 }
345
Mathias Agopian13127d82013-03-05 17:47:11 -0800346 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700347 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800348 if (!isOpaque() || s.alpha != 0xFF) {
349 layer.setBlending(mPremultipliedAlpha ?
350 HWC_BLENDING_PREMULT :
351 HWC_BLENDING_COVERAGE);
352 }
353
354 // apply the layer's transform, followed by the display's global transform
355 // here we're guaranteed that the layer's transform preserves rects
356 Rect frame(s.transform.transform(computeBounds()));
357 frame.intersect(hw->getViewport(), &frame);
358 const Transform& tr(hw->getTransform());
359 layer.setFrame(tr.transform(frame));
360 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800361 layer.setPlaneAlpha(s.alpha);
362
Mathias Agopian29a367b2011-07-12 14:51:45 -0700363 /*
364 * Transformations are applied in this order:
365 * 1) buffer orientation/flip/mirror
366 * 2) state transformation (window manager)
367 * 3) layer orientation (screen orientation)
368 * (NOTE: the matrices are multiplied in reverse order)
369 */
370
371 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800372 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700373
374 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800375 const uint32_t orientation = transform.getOrientation();
376 if (orientation & Transform::ROT_INVALID) {
377 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700378 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700379 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800380 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700381 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700382}
383
Mathias Agopian42977342012-08-05 00:40:46 -0700384void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700385 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800386 // we have to set the visible region on every frame because
387 // we currently free it during onLayerDisplayed(), which is called
388 // after HWComposer::commit() -- every frame.
389 // Apply this display's projection's viewport to the visible region
390 // before giving it to the HWC HAL.
391 const Transform& tr = hw->getTransform();
392 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
393 layer.setVisibleRegionScreen(visible);
394
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700395 // NOTE: buffer can be NULL if the client never drew into this
396 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700397 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700398}
Jesse Halldc5b4852012-06-29 15:21:18 -0700399
Mathias Agopian42977342012-08-05 00:40:46 -0700400void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700401 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700402 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700403
404 // TODO: there is a possible optimization here: we only need to set the
405 // acquire fence the first time a new buffer is acquired on EACH display.
406
407 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800408 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800409 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700410 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700411 if (fenceFd == -1) {
412 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
413 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700414 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700415 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700416 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700417}
418
Mathias Agopian13127d82013-03-05 17:47:11 -0800419// ---------------------------------------------------------------------------
420// drawing...
421// ---------------------------------------------------------------------------
422
423void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
424 onDraw(hw, clip);
425}
426
427void Layer::draw(const sp<const DisplayDevice>& hw) {
428 onDraw( hw, Region(hw->bounds()) );
429}
430
Mathias Agopian42977342012-08-05 00:40:46 -0700431void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800432{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800433 ATRACE_CALL();
434
Mathias Agopiana67932f2011-04-20 14:20:59 -0700435 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800436 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700437 // in fact never been drawn into. This happens frequently with
438 // SurfaceView because the WindowManager can't know when the client
439 // has drawn the first time.
440
441 // If there is nothing under us, we paint the screen in black, otherwise
442 // we just skip this update.
443
444 // figure out if there is something below us
445 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700446 const SurfaceFlinger::LayerVector& drawingLayers(
447 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700448 const size_t count = drawingLayers.size();
449 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800450 const sp<Layer>& layer(drawingLayers[i]);
451 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700452 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700453 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700454 }
455 // if not everything below us is covered, we plug the holes!
456 Region holes(clip.subtract(under));
457 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700458 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700459 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800460 return;
461 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700462
Andy McFadden97eba892012-12-11 15:21:45 -0800463 // Bind the current buffer to the GL texture, and wait for it to be
464 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800465 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
466 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800467 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700468 // Go ahead and draw the buffer anyway; no matter what we do the screen
469 // is probably going to have something visibly wrong.
470 }
471
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700472 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
473
Mathias Agopian875d8e12013-06-07 15:35:48 -0700474 RenderEngine& engine(mFlinger->getRenderEngine());
475
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700476 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700477 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700478 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700479
480 // Query the texture matrix given our current filtering mode.
481 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800482 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
483 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700484
485 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700486 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700487 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700488 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700489 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700490 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700491 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800492}
493
Mathias Agopian13127d82013-03-05 17:47:11 -0800494
495void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
Mathias Agopian3f844832013-08-07 21:24:32 -0700496 float red, float green, float blue, float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800497{
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700498 computeGeometry(hw, mMesh);
499 mFlinger->getRenderEngine().fillWithColor(mMesh, red, green, blue, alpha);
Mathias Agopian13127d82013-03-05 17:47:11 -0800500}
501
502void Layer::clearWithOpenGL(
503 const sp<const DisplayDevice>& hw, const Region& clip) const {
504 clearWithOpenGL(hw, clip, 0,0,0,0);
505}
506
507void Layer::drawWithOpenGL(
508 const sp<const DisplayDevice>& hw, const Region& clip) const {
509 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700510 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800511
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700512 computeGeometry(hw, mMesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800513
Mathias Agopian13127d82013-03-05 17:47:11 -0800514 /*
515 * NOTE: the way we compute the texture coordinates here produces
516 * different results than when we take the HWC path -- in the later case
517 * the "source crop" is rounded to texel boundaries.
518 * This can produce significantly different results when the texture
519 * is scaled by a large amount.
520 *
521 * The GL code below is more logical (imho), and the difference with
522 * HWC is due to a limitation of the HWC API to integers -- a question
523 * is suspend is wether we should ignore this problem or revert to
524 * GL composition when a buffer scaling is applied (maybe with some
525 * minimal value)? Or, we could make GL behave like HWC -- but this feel
526 * like more of a hack.
527 */
528 const Rect win(computeBounds());
529
Mathias Agopian3f844832013-08-07 21:24:32 -0700530 float left = float(win.left) / float(s.active.w);
531 float top = float(win.top) / float(s.active.h);
532 float right = float(win.right) / float(s.active.w);
533 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800534
Mathias Agopian875d8e12013-06-07 15:35:48 -0700535 // TODO: we probably want to generate the texture coords with the mesh
536 // here we assume that we only have 4 vertices
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700537 Mesh::VertexArray texCoords(mMesh.getTexCoordArray());
538 texCoords[0].s = left;
539 texCoords[0].t = 1.0f - top;
540 texCoords[1].s = left;
541 texCoords[1].t = 1.0f - bottom;
542 texCoords[2].s = right;
543 texCoords[2].t = 1.0f - bottom;
544 texCoords[3].s = right;
545 texCoords[3].t = 1.0f - top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800546
Mathias Agopian875d8e12013-06-07 15:35:48 -0700547 RenderEngine& engine(mFlinger->getRenderEngine());
548 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700549 engine.drawMesh(mMesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700550 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800551}
552
553void Layer::setFiltering(bool filtering) {
554 mFiltering = filtering;
555}
556
557bool Layer::getFiltering() const {
558 return mFiltering;
559}
560
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800561// As documented in libhardware header, formats in the range
562// 0x100 - 0x1FF are specific to the HAL implementation, and
563// are known to have no alpha channel
564// TODO: move definition for device-specific range into
565// hardware.h, instead of using hard-coded values here.
566#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
567
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700568bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700569 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
570 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800571 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700572 switch (format) {
573 case HAL_PIXEL_FORMAT_RGBA_8888:
574 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700575 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700576 }
577 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700578 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800579}
580
Mathias Agopian13127d82013-03-05 17:47:11 -0800581// ----------------------------------------------------------------------------
582// local state
583// ----------------------------------------------------------------------------
584
Mathias Agopian3f844832013-08-07 21:24:32 -0700585void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800586{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700587 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800588 const Transform tr(hw->getTransform() * s.transform);
589 const uint32_t hw_h = hw->getHeight();
590 Rect win(s.active.w, s.active.h);
591 if (!s.active.crop.isEmpty()) {
592 win.intersect(s.active.crop, &win);
593 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700594 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700595 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700596
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700597 Mesh::VertexArray position(mesh.getPositionArray());
598 tr.transform(position[0], win.left, win.top);
599 tr.transform(position[1], win.left, win.bottom);
600 tr.transform(position[2], win.right, win.bottom);
601 tr.transform(position[3], win.right, win.top);
Mathias Agopian3f844832013-08-07 21:24:32 -0700602 for (size_t i=0 ; i<4 ; i++) {
Mathias Agopian5cdc8992013-08-13 20:51:23 -0700603 position[i].y = hw_h - position[i].y;
Mathias Agopian13127d82013-03-05 17:47:11 -0800604 }
605}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800606
Mathias Agopiana67932f2011-04-20 14:20:59 -0700607bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700608{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700609 // if we don't have a buffer yet, we're translucent regardless of the
610 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700611 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700612 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700613 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700614
615 // if the layer has the opaque flag, then we're always opaque,
616 // otherwise we use the current buffer's format.
617 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700618}
619
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800620bool Layer::isProtected() const
621{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700622 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800623 return (activeBuffer != 0) &&
624 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
625}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700626
Mathias Agopian13127d82013-03-05 17:47:11 -0800627bool Layer::isFixedSize() const {
628 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
629}
630
631bool Layer::isCropped() const {
632 return !mCurrentCrop.isEmpty();
633}
634
635bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
636 return mNeedsFiltering || hw->needsFiltering();
637}
638
639void Layer::setVisibleRegion(const Region& visibleRegion) {
640 // always called from main thread
641 this->visibleRegion = visibleRegion;
642}
643
644void Layer::setCoveredRegion(const Region& coveredRegion) {
645 // always called from main thread
646 this->coveredRegion = coveredRegion;
647}
648
649void Layer::setVisibleNonTransparentRegion(const Region&
650 setVisibleNonTransparentRegion) {
651 // always called from main thread
652 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
653}
654
655// ----------------------------------------------------------------------------
656// transaction
657// ----------------------------------------------------------------------------
658
659uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800660 ATRACE_CALL();
661
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700662 const Layer::State& s(getDrawingState());
663 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800664
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700665 const bool sizeChanged = (c.requested.w != s.requested.w) ||
666 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700667
668 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700669 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000670 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700671 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700672 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
673 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
674 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
675 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700676 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
677 c.active.w, c.active.h,
678 c.active.crop.left,
679 c.active.crop.top,
680 c.active.crop.right,
681 c.active.crop.bottom,
682 c.active.crop.getWidth(),
683 c.active.crop.getHeight(),
684 c.requested.w, c.requested.h,
685 c.requested.crop.left,
686 c.requested.crop.top,
687 c.requested.crop.right,
688 c.requested.crop.bottom,
689 c.requested.crop.getWidth(),
690 c.requested.crop.getHeight(),
691 s.active.w, s.active.h,
692 s.active.crop.left,
693 s.active.crop.top,
694 s.active.crop.right,
695 s.active.crop.bottom,
696 s.active.crop.getWidth(),
697 s.active.crop.getHeight(),
698 s.requested.w, s.requested.h,
699 s.requested.crop.left,
700 s.requested.crop.top,
701 s.requested.crop.right,
702 s.requested.crop.bottom,
703 s.requested.crop.getWidth(),
704 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800705
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700706 // record the new size, form this point on, when the client request
707 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800708 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700709 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800710 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700711
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700712 if (!isFixedSize()) {
713
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700714 const bool resizePending = (c.requested.w != c.active.w) ||
715 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700716
717 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800718 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700719 // if we have a pending resize, unless we are in fixed-size mode.
720 // the drawing state will be updated only once we receive a buffer
721 // with the correct size.
722 //
723 // in particular, we want to make sure the clip (which is part
724 // of the geometry state) is latched together with the size but is
725 // latched immediately when no resizing is involved.
726
727 flags |= eDontUpdateGeometryState;
728 }
729 }
730
Mathias Agopian13127d82013-03-05 17:47:11 -0800731 // always set active to requested, unless we're asked not to
732 // this is used by Layer, which special cases resizes.
733 if (flags & eDontUpdateGeometryState) {
734 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700735 Layer::State& editCurrentState(getCurrentState());
736 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800737 }
738
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700739 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800740 // invalidate and recompute the visible regions if needed
741 flags |= Layer::eVisibleRegion;
742 }
743
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700744 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800745 // invalidate and recompute the visible regions if needed
746 flags |= eVisibleRegion;
747 this->contentDirty = true;
748
749 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700750 const uint8_t type = c.transform.getType();
751 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800752 (type >= Transform::SCALE));
753 }
754
755 // Commit the transaction
756 commitTransaction();
757 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800758}
759
Mathias Agopian13127d82013-03-05 17:47:11 -0800760void Layer::commitTransaction() {
761 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700762}
763
Mathias Agopian13127d82013-03-05 17:47:11 -0800764uint32_t Layer::getTransactionFlags(uint32_t flags) {
765 return android_atomic_and(~flags, &mTransactionFlags) & flags;
766}
767
768uint32_t Layer::setTransactionFlags(uint32_t flags) {
769 return android_atomic_or(flags, &mTransactionFlags);
770}
771
772bool Layer::setPosition(float x, float y) {
773 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
774 return false;
775 mCurrentState.sequence++;
776 mCurrentState.transform.set(x, y);
777 setTransactionFlags(eTransactionNeeded);
778 return true;
779}
780bool Layer::setLayer(uint32_t z) {
781 if (mCurrentState.z == z)
782 return false;
783 mCurrentState.sequence++;
784 mCurrentState.z = z;
785 setTransactionFlags(eTransactionNeeded);
786 return true;
787}
788bool Layer::setSize(uint32_t w, uint32_t h) {
789 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
790 return false;
791 mCurrentState.requested.w = w;
792 mCurrentState.requested.h = h;
793 setTransactionFlags(eTransactionNeeded);
794 return true;
795}
796bool Layer::setAlpha(uint8_t alpha) {
797 if (mCurrentState.alpha == alpha)
798 return false;
799 mCurrentState.sequence++;
800 mCurrentState.alpha = alpha;
801 setTransactionFlags(eTransactionNeeded);
802 return true;
803}
804bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
805 mCurrentState.sequence++;
806 mCurrentState.transform.set(
807 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
808 setTransactionFlags(eTransactionNeeded);
809 return true;
810}
811bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700812 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800813 setTransactionFlags(eTransactionNeeded);
814 return true;
815}
816bool Layer::setFlags(uint8_t flags, uint8_t mask) {
817 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
818 if (mCurrentState.flags == newFlags)
819 return false;
820 mCurrentState.sequence++;
821 mCurrentState.flags = newFlags;
822 setTransactionFlags(eTransactionNeeded);
823 return true;
824}
825bool Layer::setCrop(const Rect& crop) {
826 if (mCurrentState.requested.crop == crop)
827 return false;
828 mCurrentState.sequence++;
829 mCurrentState.requested.crop = crop;
830 setTransactionFlags(eTransactionNeeded);
831 return true;
832}
833
834bool Layer::setLayerStack(uint32_t layerStack) {
835 if (mCurrentState.layerStack == layerStack)
836 return false;
837 mCurrentState.sequence++;
838 mCurrentState.layerStack = layerStack;
839 setTransactionFlags(eTransactionNeeded);
840 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700841}
842
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800843// ----------------------------------------------------------------------------
844// pageflip handling...
845// ----------------------------------------------------------------------------
846
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800847bool Layer::onPreComposition() {
848 mRefreshPending = false;
849 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800850}
851
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700852void Layer::onPostComposition() {
853 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800854 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800855 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
856
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800857 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800858 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800859 mFrameTracker.setFrameReadyFence(frameReadyFence);
860 } else {
861 // There was no fence for this frame, so assume that it was ready
862 // to be presented at the desired present time.
863 mFrameTracker.setFrameReadyTime(desiredPresentTime);
864 }
865
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700866 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800867 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800868 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800869 mFrameTracker.setActualPresentFence(presentFence);
870 } else {
871 // The HWC doesn't support present fences, so use the refresh
872 // timestamp instead.
873 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
874 mFrameTracker.setActualPresentTime(presentTime);
875 }
876
877 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700878 mFrameLatencyNeeded = false;
879 }
880}
881
Mathias Agopianda27af92012-09-13 18:17:13 -0700882bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800883 const Layer::State& s(mDrawingState);
884 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
885 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700886}
887
Mathias Agopian4fec8732012-06-29 14:12:52 -0700888Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800889{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800890 ATRACE_CALL();
891
Mathias Agopian4fec8732012-06-29 14:12:52 -0700892 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700893 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800894
895 // if we've already called updateTexImage() without going through
896 // a composition step, we have to skip this layer at this point
897 // because we cannot call updateTeximage() without a corresponding
898 // compositionComplete() call.
899 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800900 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700901 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800902 }
903
Jamie Gennis351a5132011-09-14 18:23:37 -0700904 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700905 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700906 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700907
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800908 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700909 Layer::State& front;
910 Layer::State& current;
911 bool& recomputeVisibleRegions;
912 Reject(Layer::State& front, Layer::State& current,
913 bool& recomputeVisibleRegions)
914 : front(front), current(current),
915 recomputeVisibleRegions(recomputeVisibleRegions) {
916 }
917
918 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700919 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700920 if (buf == NULL) {
921 return false;
922 }
923
924 uint32_t bufWidth = buf->getWidth();
925 uint32_t bufHeight = buf->getHeight();
926
927 // check that we received a buffer of the right size
928 // (Take the buffer's orientation into account)
929 if (item.mTransform & Transform::ROT_90) {
930 swap(bufWidth, bufHeight);
931 }
932
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700933 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
934 if (front.active != front.requested) {
935
936 if (isFixedSize ||
937 (bufWidth == front.requested.w &&
938 bufHeight == front.requested.h))
939 {
940 // Here we pretend the transaction happened by updating the
941 // current and drawing states. Drawing state is only accessed
942 // in this thread, no need to have it locked
943 front.active = front.requested;
944
945 // We also need to update the current state so that
946 // we don't end-up overwriting the drawing state with
947 // this stale current state during the next transaction
948 //
949 // NOTE: We don't need to hold the transaction lock here
950 // because State::active is only accessed from this thread.
951 current.active = front.active;
952
953 // recompute visible region
954 recomputeVisibleRegions = true;
955 }
956
957 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700958 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700959 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
960 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700961 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700962 front.active.w, front.active.h,
963 front.active.crop.left,
964 front.active.crop.top,
965 front.active.crop.right,
966 front.active.crop.bottom,
967 front.active.crop.getWidth(),
968 front.active.crop.getHeight(),
969 front.requested.w, front.requested.h,
970 front.requested.crop.left,
971 front.requested.crop.top,
972 front.requested.crop.right,
973 front.requested.crop.bottom,
974 front.requested.crop.getWidth(),
975 front.requested.crop.getHeight());
976 }
977
978 if (!isFixedSize) {
979 if (front.active.w != bufWidth ||
980 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -0700981 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700982 return true;
983 }
984 }
Mathias Agopian2ca79392013-04-02 18:30:32 -0700985
986 // if the transparent region has changed (this test is
987 // conservative, but that's fine, worst case we're doing
988 // a bit of extra work), we latch the new one and we
989 // trigger a visible-region recompute.
990 if (!front.activeTransparentRegion.isTriviallyEqual(
991 front.requestedTransparentRegion)) {
992 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -0700993
994 // We also need to update the current state so that
995 // we don't end-up overwriting the drawing state with
996 // this stale current state during the next transaction
997 //
998 // NOTE: We don't need to hold the transaction lock here
999 // because State::active is only accessed from this thread.
1000 current.activeTransparentRegion = front.activeTransparentRegion;
1001
1002 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001003 recomputeVisibleRegions = true;
1004 }
1005
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001006 return false;
1007 }
1008 };
1009
1010
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001011 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001012
Andy McFadden1585c4d2013-06-28 13:52:40 -07001013 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1014 if (updateResult == BufferQueue::PRESENT_LATER) {
1015 // Producer doesn't want buffer to be displayed yet. Signal a
1016 // layer update so we check again at the next opportunity.
1017 mFlinger->signalLayerUpdate();
1018 return outDirtyRegion;
1019 }
1020
1021 // Decrement the queued-frames count. Signal another event if we
1022 // have more frames pending.
1023 if (android_atomic_dec(&mQueuedFrames) > 1) {
1024 mFlinger->signalLayerUpdate();
1025 }
1026
1027 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001028 // something happened!
1029 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001030 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001031 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001032
Jamie Gennis351a5132011-09-14 18:23:37 -07001033 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001034 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001035 if (mActiveBuffer == NULL) {
1036 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001037 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001038 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001039
Mathias Agopian4824d402012-06-04 18:16:30 -07001040 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001041 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001042 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001043 // the first time we receive a buffer, we need to trigger a
1044 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001045 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001046 }
1047
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001048 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1049 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1050 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001051 if ((crop != mCurrentCrop) ||
1052 (transform != mCurrentTransform) ||
1053 (scalingMode != mCurrentScalingMode))
1054 {
1055 mCurrentCrop = crop;
1056 mCurrentTransform = transform;
1057 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001058 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001059 }
1060
1061 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001062 uint32_t bufWidth = mActiveBuffer->getWidth();
1063 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001064 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1065 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001066 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001067 }
1068 }
1069
1070 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1071 if (oldOpacity != isOpaque()) {
1072 recomputeVisibleRegions = true;
1073 }
1074
Mathias Agopian4fec8732012-06-29 14:12:52 -07001075 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001076 const Layer::State& s(getDrawingState());
1077 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001078
1079 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001080 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001081 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001082 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001083}
1084
Mathias Agopiana67932f2011-04-20 14:20:59 -07001085uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001086{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001087 // TODO: should we do something special if mSecure is set?
1088 if (mProtectedByApp) {
1089 // need a hardware-protected path to external video sink
1090 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001091 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001092 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001093 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001094}
1095
Mathias Agopian84300952012-11-21 16:02:13 -08001096void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001097 uint32_t orientation = 0;
1098 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001099 // The transform hint is used to improve performance, but we can
1100 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001101 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001102 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001103 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001104 if (orientation & Transform::ROT_INVALID) {
1105 orientation = 0;
1106 }
1107 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001108 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001109}
1110
Mathias Agopian13127d82013-03-05 17:47:11 -08001111// ----------------------------------------------------------------------------
1112// debugging
1113// ----------------------------------------------------------------------------
1114
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001115void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001116{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001117 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001118
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001119 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001120 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001121 "+ %s %p (%s)\n",
1122 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001123 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001124
Mathias Agopian2ca79392013-04-02 18:30:32 -07001125 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001126 visibleRegion.dump(result, "visibleRegion");
1127 sp<Client> client(mClientRef.promote());
1128
Mathias Agopian74d211a2013-04-22 16:55:35 +02001129 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001130 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1131 "isOpaque=%1d, invalidate=%1d, "
1132 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1133 " client=%p\n",
1134 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1135 s.active.crop.left, s.active.crop.top,
1136 s.active.crop.right, s.active.crop.bottom,
1137 isOpaque(), contentDirty,
1138 s.alpha, s.flags,
1139 s.transform[0][0], s.transform[0][1],
1140 s.transform[1][0], s.transform[1][1],
1141 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001142
1143 sp<const GraphicBuffer> buf0(mActiveBuffer);
1144 uint32_t w0=0, h0=0, s0=0, f0=0;
1145 if (buf0 != 0) {
1146 w0 = buf0->getWidth();
1147 h0 = buf0->getHeight();
1148 s0 = buf0->getStride();
1149 f0 = buf0->format;
1150 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001151 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001152 " "
1153 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1154 " queued-frames=%d, mRefreshPending=%d\n",
1155 mFormat, w0, h0, s0,f0,
1156 mQueuedFrames, mRefreshPending);
1157
Mathias Agopian13127d82013-03-05 17:47:11 -08001158 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001159 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001160 }
1161}
1162
Mathias Agopian74d211a2013-04-22 16:55:35 +02001163void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001164 mFrameTracker.dump(result);
1165}
1166
1167void Layer::clearStats() {
1168 mFrameTracker.clear();
1169}
1170
Jamie Gennis6547ff42013-07-16 20:12:42 -07001171void Layer::logFrameStats() {
1172 mFrameTracker.logAndResetStats(mName);
1173}
1174
Mathias Agopian13127d82013-03-05 17:47:11 -08001175// ---------------------------------------------------------------------------
1176
1177Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1178 const sp<Layer>& layer)
1179 : mFlinger(flinger), mLayer(layer) {
1180}
1181
1182Layer::LayerCleaner::~LayerCleaner() {
1183 // destroy client resources
1184 mFlinger->onLayerDestroyed(mLayer);
1185}
1186
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001187// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001188}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001189
1190#if defined(__gl_h_)
1191#error "don't include gl/gl.h in this file"
1192#endif
1193
1194#if defined(__gl2_h_)
1195#error "don't include gl2/gl2.h in this file"
1196#endif