blob: cf4ec57ebd4f39a4d1615d108b38b6c37a0b9b36 [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 Agopianb7e930d2010-06-01 15:12:58 -070077 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080078 mProtectedByApp(false),
79 mHasSurface(false),
80 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080081{
Mathias Agopiana67932f2011-04-20 14:20:59 -070082 mCurrentCrop.makeInvalid();
Mathias Agopian3f844832013-08-07 21:24:32 -070083 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070084
85 uint32_t layerFlags = 0;
86 if (flags & ISurfaceComposerClient::eHidden)
87 layerFlags = layer_state_t::eLayerHidden;
88
89 if (flags & ISurfaceComposerClient::eNonPremultiplied)
90 mPremultipliedAlpha = false;
91
92 mName = name;
93
94 mCurrentState.active.w = w;
95 mCurrentState.active.h = h;
96 mCurrentState.active.crop.makeInvalid();
97 mCurrentState.z = 0;
98 mCurrentState.alpha = 0xFF;
99 mCurrentState.layerStack = 0;
100 mCurrentState.flags = layerFlags;
101 mCurrentState.sequence = 0;
102 mCurrentState.transform.set(0, 0);
103 mCurrentState.requested = mCurrentState.active;
104
105 // drawing state & current state are identical
106 mDrawingState = mCurrentState;
Jamie Gennis6547ff42013-07-16 20:12:42 -0700107
108 nsecs_t displayPeriod =
109 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
110 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
Jamie Gennise8696a42012-01-15 18:54:57 -0800111}
112
Mathias Agopian3f844832013-08-07 21:24:32 -0700113void Layer::onFirstRef() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800114 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700115 mBufferQueue = new SurfaceTextureLayer(mFlinger);
Mathias Agopian3f844832013-08-07 21:24:32 -0700116 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800117 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
118 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700119 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800120
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700121#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
122#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800123 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700124#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800126#endif
Andy McFadden69052052012-09-14 16:10:11 -0700127
Mathias Agopian84300952012-11-21 16:02:13 -0800128 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
129 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700130}
131
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700132Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800133 sp<Client> c(mClientRef.promote());
134 if (c != 0) {
135 c->detachLayer(this);
136 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700137 mFlinger->deleteTextureAsync(mTextureName);
Jamie Gennis6547ff42013-07-16 20:12:42 -0700138 mFrameTracker.logAndResetStats(mName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700139}
140
Mathias Agopian13127d82013-03-05 17:47:11 -0800141// ---------------------------------------------------------------------------
142// callbacks
143// ---------------------------------------------------------------------------
144
145void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
146 HWComposer::HWCLayerInterface* layer) {
147 if (layer) {
148 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700149 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800150 }
151}
152
Igor Murashkina4a31492012-10-29 13:36:11 -0700153void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700154 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800155 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700156}
157
Mathias Agopian67106042013-03-14 19:18:13 -0700158// called with SurfaceFlinger::mStateLock from the drawing thread after
159// the layer has been remove from the current state list (and just before
160// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800161void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800162 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700163}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700164
Mathias Agopian13127d82013-03-05 17:47:11 -0800165// ---------------------------------------------------------------------------
166// set-up
167// ---------------------------------------------------------------------------
168
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700169const String8& Layer::getName() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800170 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800171}
172
Mathias Agopianf9d93272009-06-19 17:00:27 -0700173status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800174 PixelFormat format, uint32_t flags)
175{
Mathias Agopianca99fb82010-04-14 16:43:44 -0700176 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700177 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700178
179 // never allow a surface larger than what our underlying GL implementation
180 // can handle.
181 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800182 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700183 return BAD_VALUE;
184 }
185
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700186 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700187
Mathias Agopian3165cc22012-08-08 19:42:09 -0700188 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
189 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
190 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700191 mCurrentOpacity = getOpacityForFormat(format);
192
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800193 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
194 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
195 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700196
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800197 return NO_ERROR;
198}
199
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700200sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800201 Mutex::Autolock _l(mLock);
202
203 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700204 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800205
206 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700207
208 /*
209 * The layer handle is just a BBinder object passed to the client
210 * (remote process) -- we don't keep any reference on our side such that
211 * the dtor is called when the remote side let go of its reference.
212 *
213 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
214 * this layer when the handle is destroyed.
215 */
216
217 class Handle : public BBinder, public LayerCleaner {
218 wp<const Layer> mOwner;
219 public:
220 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
221 : LayerCleaner(flinger, layer), mOwner(layer) {
222 }
223 };
224
225 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800226}
227
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700228sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
229 return mBufferQueue;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700230}
231
Mathias Agopian13127d82013-03-05 17:47:11 -0800232// ---------------------------------------------------------------------------
233// h/w composer set-up
234// ---------------------------------------------------------------------------
235
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800236Rect Layer::getContentCrop() const {
237 // this is the crop rectangle that applies to the buffer
238 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700239 Rect crop;
240 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800241 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700242 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800243 } else if (mActiveBuffer != NULL) {
244 // otherwise we use the whole buffer
245 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700246 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800247 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700248 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700249 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700250 return crop;
251}
252
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700253static Rect reduce(const Rect& win, const Region& exclude) {
254 if (CC_LIKELY(exclude.isEmpty())) {
255 return win;
256 }
257 if (exclude.isRect()) {
258 return win.reduce(exclude.getBounds());
259 }
260 return Region(win).subtract(exclude).getBounds();
261}
262
Mathias Agopian13127d82013-03-05 17:47:11 -0800263Rect Layer::computeBounds() const {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700264 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800265 Rect win(s.active.w, s.active.h);
266 if (!s.active.crop.isEmpty()) {
267 win.intersect(s.active.crop, &win);
268 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700269 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700270 return reduce(win, s.activeTransparentRegion);
Mathias Agopian13127d82013-03-05 17:47:11 -0800271}
272
Mathias Agopian6b442672013-07-09 21:24:52 -0700273FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800274 // the content crop is the area of the content that gets scaled to the
275 // layer's size.
Mathias Agopian6b442672013-07-09 21:24:52 -0700276 FloatRect crop(getContentCrop());
Mathias Agopian13127d82013-03-05 17:47:11 -0800277
278 // the active.crop is the area of the window that gets cropped, but not
279 // scaled in any ways.
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700280 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800281
282 // apply the projection's clipping to the window crop in
283 // layerstack space, and convert-back to layer space.
Mathias Agopian6b442672013-07-09 21:24:52 -0700284 // if there are no window scaling involved, this operation will map to full
285 // pixels in the buffer.
286 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
287 // a viewport clipping and a window transform. we should use floating point to fix this.
Mathias Agopian13127d82013-03-05 17:47:11 -0800288 Rect activeCrop(s.transform.transform(s.active.crop));
289 activeCrop.intersect(hw->getViewport(), &activeCrop);
290 activeCrop = s.transform.inverse().transform(activeCrop);
291
292 // paranoia: make sure the window-crop is constrained in the
293 // window's bounds
294 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
295
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700296 // subtract the transparent region and snap to the bounds
297 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
298
Mathias Agopian13127d82013-03-05 17:47:11 -0800299 if (!activeCrop.isEmpty()) {
300 // Transform the window crop to match the buffer coordinate system,
301 // which means using the inverse of the current transform set on the
302 // SurfaceFlingerConsumer.
Mathias Agopian6b442672013-07-09 21:24:52 -0700303 uint32_t invTransform = mCurrentTransform;
Mathias Agopian13127d82013-03-05 17:47:11 -0800304 int winWidth = s.active.w;
305 int winHeight = s.active.h;
306 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
307 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
308 NATIVE_WINDOW_TRANSFORM_FLIP_H;
309 winWidth = s.active.h;
310 winHeight = s.active.w;
311 }
312 const Rect winCrop = activeCrop.transform(
313 invTransform, s.active.w, s.active.h);
314
Mathias Agopian6b442672013-07-09 21:24:52 -0700315 // below, crop is intersected with winCrop expressed in crop's coordinate space
316 float xScale = crop.getWidth() / float(winWidth);
317 float yScale = crop.getHeight() / float(winHeight);
Mathias Agopian13127d82013-03-05 17:47:11 -0800318
Mathias Agopian6b442672013-07-09 21:24:52 -0700319 float insetL = winCrop.left * xScale;
320 float insetT = winCrop.top * yScale;
321 float insetR = (winWidth - winCrop.right ) * xScale;
322 float insetB = (winHeight - winCrop.bottom) * yScale;
Mathias Agopian13127d82013-03-05 17:47:11 -0800323
324 crop.left += insetL;
325 crop.top += insetT;
326 crop.right -= insetR;
327 crop.bottom -= insetB;
328 }
329 return crop;
330}
331
Mathias Agopian4fec8732012-06-29 14:12:52 -0700332void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700333 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700334 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700335{
Mathias Agopian13127d82013-03-05 17:47:11 -0800336 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700337
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700338 // enable this layer
339 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700340
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700341 if (isSecure() && !hw->isSecure()) {
342 layer.setSkip(true);
343 }
344
Mathias Agopian13127d82013-03-05 17:47:11 -0800345 // this gives us only the "orientation" component of the transform
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700346 const State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800347 if (!isOpaque() || s.alpha != 0xFF) {
348 layer.setBlending(mPremultipliedAlpha ?
349 HWC_BLENDING_PREMULT :
350 HWC_BLENDING_COVERAGE);
351 }
352
353 // apply the layer's transform, followed by the display's global transform
354 // here we're guaranteed that the layer's transform preserves rects
355 Rect frame(s.transform.transform(computeBounds()));
356 frame.intersect(hw->getViewport(), &frame);
357 const Transform& tr(hw->getTransform());
358 layer.setFrame(tr.transform(frame));
359 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800360 layer.setPlaneAlpha(s.alpha);
361
Mathias Agopian29a367b2011-07-12 14:51:45 -0700362 /*
363 * Transformations are applied in this order:
364 * 1) buffer orientation/flip/mirror
365 * 2) state transformation (window manager)
366 * 3) layer orientation (screen orientation)
367 * (NOTE: the matrices are multiplied in reverse order)
368 */
369
370 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800371 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700372
373 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800374 const uint32_t orientation = transform.getOrientation();
375 if (orientation & Transform::ROT_INVALID) {
376 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700377 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700378 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800379 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700380 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700381}
382
Mathias Agopian42977342012-08-05 00:40:46 -0700383void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700384 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800385 // we have to set the visible region on every frame because
386 // we currently free it during onLayerDisplayed(), which is called
387 // after HWComposer::commit() -- every frame.
388 // Apply this display's projection's viewport to the visible region
389 // before giving it to the HWC HAL.
390 const Transform& tr = hw->getTransform();
391 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
392 layer.setVisibleRegionScreen(visible);
393
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700394 // NOTE: buffer can be NULL if the client never drew into this
395 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700396 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700397}
Jesse Halldc5b4852012-06-29 15:21:18 -0700398
Mathias Agopian42977342012-08-05 00:40:46 -0700399void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700400 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700401 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700402
403 // TODO: there is a possible optimization here: we only need to set the
404 // acquire fence the first time a new buffer is acquired on EACH display.
405
406 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800407 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800408 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700409 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700410 if (fenceFd == -1) {
411 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
412 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700413 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700414 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700415 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700416}
417
Mathias Agopian13127d82013-03-05 17:47:11 -0800418// ---------------------------------------------------------------------------
419// drawing...
420// ---------------------------------------------------------------------------
421
422void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
423 onDraw(hw, clip);
424}
425
426void Layer::draw(const sp<const DisplayDevice>& hw) {
427 onDraw( hw, Region(hw->bounds()) );
428}
429
Mathias Agopian42977342012-08-05 00:40:46 -0700430void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800431{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800432 ATRACE_CALL();
433
Mathias Agopiana67932f2011-04-20 14:20:59 -0700434 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800435 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700436 // in fact never been drawn into. This happens frequently with
437 // SurfaceView because the WindowManager can't know when the client
438 // has drawn the first time.
439
440 // If there is nothing under us, we paint the screen in black, otherwise
441 // we just skip this update.
442
443 // figure out if there is something below us
444 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700445 const SurfaceFlinger::LayerVector& drawingLayers(
446 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700447 const size_t count = drawingLayers.size();
448 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800449 const sp<Layer>& layer(drawingLayers[i]);
450 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700451 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700452 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700453 }
454 // if not everything below us is covered, we plug the holes!
455 Region holes(clip.subtract(under));
456 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700457 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700458 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800459 return;
460 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700461
Andy McFadden97eba892012-12-11 15:21:45 -0800462 // Bind the current buffer to the GL texture, and wait for it to be
463 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800464 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
465 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800466 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700467 // Go ahead and draw the buffer anyway; no matter what we do the screen
468 // is probably going to have something visibly wrong.
469 }
470
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700471 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
472
Mathias Agopian875d8e12013-06-07 15:35:48 -0700473 RenderEngine& engine(mFlinger->getRenderEngine());
474
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700475 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700476 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700477 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700478
479 // Query the texture matrix given our current filtering mode.
480 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800481 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
482 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700483
484 // Set things up for texturing.
Mathias Agopian875d8e12013-06-07 15:35:48 -0700485 engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700486 } else {
Mathias Agopian875d8e12013-06-07 15:35:48 -0700487 engine.setupLayerBlackedOut();
Mathias Agopiana67932f2011-04-20 14:20:59 -0700488 }
Mathias Agopian1b031492012-06-20 17:51:20 -0700489 drawWithOpenGL(hw, clip);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700490 engine.disableTexturing();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800491}
492
Mathias Agopian13127d82013-03-05 17:47:11 -0800493
494void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
Mathias Agopian3f844832013-08-07 21:24:32 -0700495 float red, float green, float blue, float alpha) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800496{
Mathias Agopian3f844832013-08-07 21:24:32 -0700497 Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
498 computeGeometry(hw, mesh);
499 mFlinger->getRenderEngine().fillWithColor(mesh, 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 Agopian3f844832013-08-07 21:24:32 -0700512 Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
513 computeGeometry(hw, mesh);
Mathias Agopian13127d82013-03-05 17:47:11 -0800514
Mathias Agopian13127d82013-03-05 17:47:11 -0800515 /*
516 * NOTE: the way we compute the texture coordinates here produces
517 * different results than when we take the HWC path -- in the later case
518 * the "source crop" is rounded to texel boundaries.
519 * This can produce significantly different results when the texture
520 * is scaled by a large amount.
521 *
522 * The GL code below is more logical (imho), and the difference with
523 * HWC is due to a limitation of the HWC API to integers -- a question
524 * is suspend is wether we should ignore this problem or revert to
525 * GL composition when a buffer scaling is applied (maybe with some
526 * minimal value)? Or, we could make GL behave like HWC -- but this feel
527 * like more of a hack.
528 */
529 const Rect win(computeBounds());
530
Mathias Agopian3f844832013-08-07 21:24:32 -0700531 float left = float(win.left) / float(s.active.w);
532 float top = float(win.top) / float(s.active.h);
533 float right = float(win.right) / float(s.active.w);
534 float bottom = float(win.bottom) / float(s.active.h);
Mathias Agopian13127d82013-03-05 17:47:11 -0800535
Mathias Agopian875d8e12013-06-07 15:35:48 -0700536 // TODO: we probably want to generate the texture coords with the mesh
537 // here we assume that we only have 4 vertices
Mathias Agopian3f844832013-08-07 21:24:32 -0700538 size_t stride = mesh.getStride();
539 float* base = mesh.getTexCoords();
540 base[stride*0 + 0] = left;
541 base[stride*0 + 1] = 1.0f - top;
542 base[stride*1 + 0] = left;
543 base[stride*1 + 1] = 1.0f - bottom;
544 base[stride*2 + 0] = right;
545 base[stride*2 + 1] = 1.0f - bottom;
546 base[stride*3 + 0] = right;
547 base[stride*3 + 1] = 1.0f - top;
Mathias Agopian13127d82013-03-05 17:47:11 -0800548
Mathias Agopian875d8e12013-06-07 15:35:48 -0700549 RenderEngine& engine(mFlinger->getRenderEngine());
550 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
Mathias Agopian3f844832013-08-07 21:24:32 -0700551 engine.drawMesh(mesh);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700552 engine.disableBlending();
Mathias Agopian13127d82013-03-05 17:47:11 -0800553}
554
555void Layer::setFiltering(bool filtering) {
556 mFiltering = filtering;
557}
558
559bool Layer::getFiltering() const {
560 return mFiltering;
561}
562
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800563// As documented in libhardware header, formats in the range
564// 0x100 - 0x1FF are specific to the HAL implementation, and
565// are known to have no alpha channel
566// TODO: move definition for device-specific range into
567// hardware.h, instead of using hard-coded values here.
568#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
569
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700570bool Layer::getOpacityForFormat(uint32_t format) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700571 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
572 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800573 }
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700574 switch (format) {
575 case HAL_PIXEL_FORMAT_RGBA_8888:
576 case HAL_PIXEL_FORMAT_BGRA_8888:
Mathias Agopiandd533712013-07-26 15:31:39 -0700577 return false;
Mathias Agopian5773d3f2013-07-25 19:24:31 -0700578 }
579 // in all other case, we have no blending (also for unknown formats)
Mathias Agopiandd533712013-07-26 15:31:39 -0700580 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800581}
582
Mathias Agopian13127d82013-03-05 17:47:11 -0800583// ----------------------------------------------------------------------------
584// local state
585// ----------------------------------------------------------------------------
586
Mathias Agopian3f844832013-08-07 21:24:32 -0700587void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
Mathias Agopian13127d82013-03-05 17:47:11 -0800588{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700589 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800590 const Transform tr(hw->getTransform() * s.transform);
591 const uint32_t hw_h = hw->getHeight();
592 Rect win(s.active.w, s.active.h);
593 if (!s.active.crop.isEmpty()) {
594 win.intersect(s.active.crop, &win);
595 }
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700596 // subtract the transparent region and snap to the bounds
Mathias Agopianf3e85d42013-05-10 18:01:12 -0700597 win = reduce(win, s.activeTransparentRegion);
Mathias Agopian3f844832013-08-07 21:24:32 -0700598
599 tr.transform(mesh[0], win.left, win.top);
600 tr.transform(mesh[1], win.left, win.bottom);
601 tr.transform(mesh[2], win.right, win.bottom);
602 tr.transform(mesh[3], win.right, win.top);
603 for (size_t i=0 ; i<4 ; i++) {
604 mesh[i][1] = hw_h - mesh[i][1];
Mathias Agopian13127d82013-03-05 17:47:11 -0800605 }
606}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800607
Mathias Agopiana67932f2011-04-20 14:20:59 -0700608bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700609{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700610 // if we don't have a buffer yet, we're translucent regardless of the
611 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700612 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700613 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700614 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700615
616 // if the layer has the opaque flag, then we're always opaque,
617 // otherwise we use the current buffer's format.
618 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700619}
620
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800621bool Layer::isProtected() const
622{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700623 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800624 return (activeBuffer != 0) &&
625 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
626}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700627
Mathias Agopian13127d82013-03-05 17:47:11 -0800628bool Layer::isFixedSize() const {
629 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
630}
631
632bool Layer::isCropped() const {
633 return !mCurrentCrop.isEmpty();
634}
635
636bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
637 return mNeedsFiltering || hw->needsFiltering();
638}
639
640void Layer::setVisibleRegion(const Region& visibleRegion) {
641 // always called from main thread
642 this->visibleRegion = visibleRegion;
643}
644
645void Layer::setCoveredRegion(const Region& coveredRegion) {
646 // always called from main thread
647 this->coveredRegion = coveredRegion;
648}
649
650void Layer::setVisibleNonTransparentRegion(const Region&
651 setVisibleNonTransparentRegion) {
652 // always called from main thread
653 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
654}
655
656// ----------------------------------------------------------------------------
657// transaction
658// ----------------------------------------------------------------------------
659
660uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800661 ATRACE_CALL();
662
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700663 const Layer::State& s(getDrawingState());
664 const Layer::State& c(getCurrentState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800665
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700666 const bool sizeChanged = (c.requested.w != s.requested.w) ||
667 (c.requested.h != s.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700668
669 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700670 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000671 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700672 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700673 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
674 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
675 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
676 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700677 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
678 c.active.w, c.active.h,
679 c.active.crop.left,
680 c.active.crop.top,
681 c.active.crop.right,
682 c.active.crop.bottom,
683 c.active.crop.getWidth(),
684 c.active.crop.getHeight(),
685 c.requested.w, c.requested.h,
686 c.requested.crop.left,
687 c.requested.crop.top,
688 c.requested.crop.right,
689 c.requested.crop.bottom,
690 c.requested.crop.getWidth(),
691 c.requested.crop.getHeight(),
692 s.active.w, s.active.h,
693 s.active.crop.left,
694 s.active.crop.top,
695 s.active.crop.right,
696 s.active.crop.bottom,
697 s.active.crop.getWidth(),
698 s.active.crop.getHeight(),
699 s.requested.w, s.requested.h,
700 s.requested.crop.left,
701 s.requested.crop.top,
702 s.requested.crop.right,
703 s.requested.crop.bottom,
704 s.requested.crop.getWidth(),
705 s.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800706
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700707 // record the new size, form this point on, when the client request
708 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800709 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700710 c.requested.w, c.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800711 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700712
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700713 if (!isFixedSize()) {
714
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700715 const bool resizePending = (c.requested.w != c.active.w) ||
716 (c.requested.h != c.active.h);
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700717
718 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800719 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700720 // if we have a pending resize, unless we are in fixed-size mode.
721 // the drawing state will be updated only once we receive a buffer
722 // with the correct size.
723 //
724 // in particular, we want to make sure the clip (which is part
725 // of the geometry state) is latched together with the size but is
726 // latched immediately when no resizing is involved.
727
728 flags |= eDontUpdateGeometryState;
729 }
730 }
731
Mathias Agopian13127d82013-03-05 17:47:11 -0800732 // always set active to requested, unless we're asked not to
733 // this is used by Layer, which special cases resizes.
734 if (flags & eDontUpdateGeometryState) {
735 } else {
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700736 Layer::State& editCurrentState(getCurrentState());
737 editCurrentState.active = c.requested;
Mathias Agopian13127d82013-03-05 17:47:11 -0800738 }
739
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700740 if (s.active != c.active) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800741 // invalidate and recompute the visible regions if needed
742 flags |= Layer::eVisibleRegion;
743 }
744
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700745 if (c.sequence != s.sequence) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800746 // invalidate and recompute the visible regions if needed
747 flags |= eVisibleRegion;
748 this->contentDirty = true;
749
750 // we may use linear filtering, if the matrix scales us
Mathias Agopian1eae0ee2013-06-05 16:59:15 -0700751 const uint8_t type = c.transform.getType();
752 mNeedsFiltering = (!c.transform.preserveRects() ||
Mathias Agopian13127d82013-03-05 17:47:11 -0800753 (type >= Transform::SCALE));
754 }
755
756 // Commit the transaction
757 commitTransaction();
758 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800759}
760
Mathias Agopian13127d82013-03-05 17:47:11 -0800761void Layer::commitTransaction() {
762 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700763}
764
Mathias Agopian13127d82013-03-05 17:47:11 -0800765uint32_t Layer::getTransactionFlags(uint32_t flags) {
766 return android_atomic_and(~flags, &mTransactionFlags) & flags;
767}
768
769uint32_t Layer::setTransactionFlags(uint32_t flags) {
770 return android_atomic_or(flags, &mTransactionFlags);
771}
772
773bool Layer::setPosition(float x, float y) {
774 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
775 return false;
776 mCurrentState.sequence++;
777 mCurrentState.transform.set(x, y);
778 setTransactionFlags(eTransactionNeeded);
779 return true;
780}
781bool Layer::setLayer(uint32_t z) {
782 if (mCurrentState.z == z)
783 return false;
784 mCurrentState.sequence++;
785 mCurrentState.z = z;
786 setTransactionFlags(eTransactionNeeded);
787 return true;
788}
789bool Layer::setSize(uint32_t w, uint32_t h) {
790 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
791 return false;
792 mCurrentState.requested.w = w;
793 mCurrentState.requested.h = h;
794 setTransactionFlags(eTransactionNeeded);
795 return true;
796}
797bool Layer::setAlpha(uint8_t alpha) {
798 if (mCurrentState.alpha == alpha)
799 return false;
800 mCurrentState.sequence++;
801 mCurrentState.alpha = alpha;
802 setTransactionFlags(eTransactionNeeded);
803 return true;
804}
805bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
806 mCurrentState.sequence++;
807 mCurrentState.transform.set(
808 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
809 setTransactionFlags(eTransactionNeeded);
810 return true;
811}
812bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700813 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800814 setTransactionFlags(eTransactionNeeded);
815 return true;
816}
817bool Layer::setFlags(uint8_t flags, uint8_t mask) {
818 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
819 if (mCurrentState.flags == newFlags)
820 return false;
821 mCurrentState.sequence++;
822 mCurrentState.flags = newFlags;
823 setTransactionFlags(eTransactionNeeded);
824 return true;
825}
826bool Layer::setCrop(const Rect& crop) {
827 if (mCurrentState.requested.crop == crop)
828 return false;
829 mCurrentState.sequence++;
830 mCurrentState.requested.crop = crop;
831 setTransactionFlags(eTransactionNeeded);
832 return true;
833}
834
835bool Layer::setLayerStack(uint32_t layerStack) {
836 if (mCurrentState.layerStack == layerStack)
837 return false;
838 mCurrentState.sequence++;
839 mCurrentState.layerStack = layerStack;
840 setTransactionFlags(eTransactionNeeded);
841 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700842}
843
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800844// ----------------------------------------------------------------------------
845// pageflip handling...
846// ----------------------------------------------------------------------------
847
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800848bool Layer::onPreComposition() {
849 mRefreshPending = false;
850 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800851}
852
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700853void Layer::onPostComposition() {
854 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800855 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800856 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
857
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800858 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800859 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800860 mFrameTracker.setFrameReadyFence(frameReadyFence);
861 } else {
862 // There was no fence for this frame, so assume that it was ready
863 // to be presented at the desired present time.
864 mFrameTracker.setFrameReadyTime(desiredPresentTime);
865 }
866
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700867 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800868 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800869 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800870 mFrameTracker.setActualPresentFence(presentFence);
871 } else {
872 // The HWC doesn't support present fences, so use the refresh
873 // timestamp instead.
874 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
875 mFrameTracker.setActualPresentTime(presentTime);
876 }
877
878 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700879 mFrameLatencyNeeded = false;
880 }
881}
882
Mathias Agopianda27af92012-09-13 18:17:13 -0700883bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800884 const Layer::State& s(mDrawingState);
885 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
886 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700887}
888
Mathias Agopian4fec8732012-06-29 14:12:52 -0700889Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800890{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800891 ATRACE_CALL();
892
Mathias Agopian4fec8732012-06-29 14:12:52 -0700893 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700894 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800895
896 // if we've already called updateTexImage() without going through
897 // a composition step, we have to skip this layer at this point
898 // because we cannot call updateTeximage() without a corresponding
899 // compositionComplete() call.
900 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800901 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700902 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800903 }
904
Jamie Gennis351a5132011-09-14 18:23:37 -0700905 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700906 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700907 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700908
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800909 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700910 Layer::State& front;
911 Layer::State& current;
912 bool& recomputeVisibleRegions;
913 Reject(Layer::State& front, Layer::State& current,
914 bool& recomputeVisibleRegions)
915 : front(front), current(current),
916 recomputeVisibleRegions(recomputeVisibleRegions) {
917 }
918
919 virtual bool reject(const sp<GraphicBuffer>& buf,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700920 const IGraphicBufferConsumer::BufferItem& item) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700921 if (buf == NULL) {
922 return false;
923 }
924
925 uint32_t bufWidth = buf->getWidth();
926 uint32_t bufHeight = buf->getHeight();
927
928 // check that we received a buffer of the right size
929 // (Take the buffer's orientation into account)
930 if (item.mTransform & Transform::ROT_90) {
931 swap(bufWidth, bufHeight);
932 }
933
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700934 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
935 if (front.active != front.requested) {
936
937 if (isFixedSize ||
938 (bufWidth == front.requested.w &&
939 bufHeight == front.requested.h))
940 {
941 // Here we pretend the transaction happened by updating the
942 // current and drawing states. Drawing state is only accessed
943 // in this thread, no need to have it locked
944 front.active = front.requested;
945
946 // We also need to update the current state so that
947 // we don't end-up overwriting the drawing state with
948 // this stale current state during the next transaction
949 //
950 // NOTE: We don't need to hold the transaction lock here
951 // because State::active is only accessed from this thread.
952 current.active = front.active;
953
954 // recompute visible region
955 recomputeVisibleRegions = true;
956 }
957
958 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700959 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700960 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
961 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700962 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700963 front.active.w, front.active.h,
964 front.active.crop.left,
965 front.active.crop.top,
966 front.active.crop.right,
967 front.active.crop.bottom,
968 front.active.crop.getWidth(),
969 front.active.crop.getHeight(),
970 front.requested.w, front.requested.h,
971 front.requested.crop.left,
972 front.requested.crop.top,
973 front.requested.crop.right,
974 front.requested.crop.bottom,
975 front.requested.crop.getWidth(),
976 front.requested.crop.getHeight());
977 }
978
979 if (!isFixedSize) {
980 if (front.active.w != bufWidth ||
981 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -0700982 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700983 return true;
984 }
985 }
Mathias Agopian2ca79392013-04-02 18:30:32 -0700986
987 // if the transparent region has changed (this test is
988 // conservative, but that's fine, worst case we're doing
989 // a bit of extra work), we latch the new one and we
990 // trigger a visible-region recompute.
991 if (!front.activeTransparentRegion.isTriviallyEqual(
992 front.requestedTransparentRegion)) {
993 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -0700994
995 // We also need to update the current state so that
996 // we don't end-up overwriting the drawing state with
997 // this stale current state during the next transaction
998 //
999 // NOTE: We don't need to hold the transaction lock here
1000 // because State::active is only accessed from this thread.
1001 current.activeTransparentRegion = front.activeTransparentRegion;
1002
1003 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001004 recomputeVisibleRegions = true;
1005 }
1006
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001007 return false;
1008 }
1009 };
1010
1011
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001012 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001013
Andy McFadden1585c4d2013-06-28 13:52:40 -07001014 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1015 if (updateResult == BufferQueue::PRESENT_LATER) {
1016 // Producer doesn't want buffer to be displayed yet. Signal a
1017 // layer update so we check again at the next opportunity.
1018 mFlinger->signalLayerUpdate();
1019 return outDirtyRegion;
1020 }
1021
1022 // Decrement the queued-frames count. Signal another event if we
1023 // have more frames pending.
1024 if (android_atomic_dec(&mQueuedFrames) > 1) {
1025 mFlinger->signalLayerUpdate();
1026 }
1027
1028 if (updateResult != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001029 // something happened!
1030 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001031 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001032 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001033
Jamie Gennis351a5132011-09-14 18:23:37 -07001034 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001035 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001036 if (mActiveBuffer == NULL) {
1037 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001038 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001039 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001040
Mathias Agopian4824d402012-06-04 18:16:30 -07001041 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001042 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001043 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001044 // the first time we receive a buffer, we need to trigger a
1045 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001046 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001047 }
1048
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001049 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1050 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1051 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001052 if ((crop != mCurrentCrop) ||
1053 (transform != mCurrentTransform) ||
1054 (scalingMode != mCurrentScalingMode))
1055 {
1056 mCurrentCrop = crop;
1057 mCurrentTransform = transform;
1058 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001059 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001060 }
1061
1062 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001063 uint32_t bufWidth = mActiveBuffer->getWidth();
1064 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001065 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1066 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001067 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001068 }
1069 }
1070
1071 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1072 if (oldOpacity != isOpaque()) {
1073 recomputeVisibleRegions = true;
1074 }
1075
Mathias Agopian4fec8732012-06-29 14:12:52 -07001076 // FIXME: postedRegion should be dirty & bounds
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001077 const Layer::State& s(getDrawingState());
1078 Region dirtyRegion(Rect(s.active.w, s.active.h));
Mathias Agopian4fec8732012-06-29 14:12:52 -07001079
1080 // transform the dirty region to window-manager space
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001081 outDirtyRegion = (s.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001082 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001083 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001084}
1085
Mathias Agopiana67932f2011-04-20 14:20:59 -07001086uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001087{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001088 // TODO: should we do something special if mSecure is set?
1089 if (mProtectedByApp) {
1090 // need a hardware-protected path to external video sink
1091 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001092 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001093 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001094 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001095}
1096
Mathias Agopian84300952012-11-21 16:02:13 -08001097void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001098 uint32_t orientation = 0;
1099 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001100 // The transform hint is used to improve performance, but we can
1101 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001102 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001103 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001104 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001105 if (orientation & Transform::ROT_INVALID) {
1106 orientation = 0;
1107 }
1108 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001109 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001110}
1111
Mathias Agopian13127d82013-03-05 17:47:11 -08001112// ----------------------------------------------------------------------------
1113// debugging
1114// ----------------------------------------------------------------------------
1115
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001116void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001117{
Mathias Agopian1eae0ee2013-06-05 16:59:15 -07001118 const Layer::State& s(getDrawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -08001119
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001120 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001121 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001122 "+ %s %p (%s)\n",
1123 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001124 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001125
Mathias Agopian2ca79392013-04-02 18:30:32 -07001126 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001127 visibleRegion.dump(result, "visibleRegion");
1128 sp<Client> client(mClientRef.promote());
1129
Mathias Agopian74d211a2013-04-22 16:55:35 +02001130 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001131 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1132 "isOpaque=%1d, invalidate=%1d, "
1133 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1134 " client=%p\n",
1135 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1136 s.active.crop.left, s.active.crop.top,
1137 s.active.crop.right, s.active.crop.bottom,
1138 isOpaque(), contentDirty,
1139 s.alpha, s.flags,
1140 s.transform[0][0], s.transform[0][1],
1141 s.transform[1][0], s.transform[1][1],
1142 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001143
1144 sp<const GraphicBuffer> buf0(mActiveBuffer);
1145 uint32_t w0=0, h0=0, s0=0, f0=0;
1146 if (buf0 != 0) {
1147 w0 = buf0->getWidth();
1148 h0 = buf0->getHeight();
1149 s0 = buf0->getStride();
1150 f0 = buf0->format;
1151 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001152 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001153 " "
1154 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1155 " queued-frames=%d, mRefreshPending=%d\n",
1156 mFormat, w0, h0, s0,f0,
1157 mQueuedFrames, mRefreshPending);
1158
Mathias Agopian13127d82013-03-05 17:47:11 -08001159 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001160 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001161 }
1162}
1163
Mathias Agopian74d211a2013-04-22 16:55:35 +02001164void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001165 mFrameTracker.dump(result);
1166}
1167
1168void Layer::clearStats() {
1169 mFrameTracker.clear();
1170}
1171
Jamie Gennis6547ff42013-07-16 20:12:42 -07001172void Layer::logFrameStats() {
1173 mFrameTracker.logAndResetStats(mName);
1174}
1175
Mathias Agopian13127d82013-03-05 17:47:11 -08001176// ---------------------------------------------------------------------------
1177
1178Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1179 const sp<Layer>& layer)
1180 : mFlinger(flinger), mLayer(layer) {
1181}
1182
1183Layer::LayerCleaner::~LayerCleaner() {
1184 // destroy client resources
1185 mFlinger->onLayerDestroyed(mLayer);
1186}
1187
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001188// ---------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001189}; // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -07001190
1191#if defined(__gl_h_)
1192#error "don't include gl/gl.h in this file"
1193#endif
1194
1195#if defined(__gl2_h_)
1196#error "don't include gl2/gl2.h in this file"
1197#endif