blob: 9896581578c1156a931b14dd7d8676d792fe0c3a [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"
Mathias Agopian1f7bec62010-06-25 18:02:21 -070041#include "GLExtensions.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080042#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043#include "SurfaceFlinger.h"
Mathias Agopiana67932f2011-04-20 14:20:59 -070044#include "SurfaceTextureLayer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045
Mathias Agopian1b031492012-06-20 17:51:20 -070046#include "DisplayHardware/HWComposer.h"
47
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#define DEBUG_RESIZE 0
49
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050namespace android {
51
52// ---------------------------------------------------------------------------
53
Mathias Agopian13127d82013-03-05 17:47:11 -080054int32_t Layer::sSequence = 1;
55
Mathias Agopian4d9b8222013-03-12 17:11:48 -070056Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
57 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080058 : contentDirty(false),
59 sequence(uint32_t(android_atomic_inc(&sSequence))),
60 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070061 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080062 mPremultipliedAlpha(true),
63 mName("unnamed"),
64 mDebug(false),
65 mFormat(PIXEL_FORMAT_NONE),
66 mGLExtensions(GLExtensions::getInstance()),
67 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();
83 glGenTextures(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 Gennise8696a42012-01-15 18:54:57 -0800107}
108
Mathias Agopiana67932f2011-04-20 14:20:59 -0700109void Layer::onFirstRef()
Mathias Agopian96f08192010-06-02 23:28:45 -0700110{
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800111 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopian67106042013-03-14 19:18:13 -0700112 sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800113 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
Mathias Agopiana0db3082012-04-23 13:59:36 -0700114 GL_TEXTURE_EXTERNAL_OES, false, bq);
Daniel Lamb2675792012-02-23 14:35:13 -0800115
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800116 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
118 mSurfaceFlingerConsumer->setSynchronousMode(true);
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);
Mathias Agopian96f08192010-06-02 23:28:45 -0700138}
139
Mathias Agopian13127d82013-03-05 17:47:11 -0800140// ---------------------------------------------------------------------------
141// callbacks
142// ---------------------------------------------------------------------------
143
144void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
145 HWComposer::HWCLayerInterface* layer) {
146 if (layer) {
147 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700148 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800149 }
150}
151
Igor Murashkina4a31492012-10-29 13:36:11 -0700152void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700153 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800154 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700155}
156
Mathias Agopian67106042013-03-14 19:18:13 -0700157// called with SurfaceFlinger::mStateLock from the drawing thread after
158// the layer has been remove from the current state list (and just before
159// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800160void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800161 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700162}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700163
Mathias Agopian13127d82013-03-05 17:47:11 -0800164// ---------------------------------------------------------------------------
165// set-up
166// ---------------------------------------------------------------------------
167
Mathias Agopian13127d82013-03-05 17:47:11 -0800168String8 Layer::getName() const {
169 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800170}
171
Mathias Agopianf9d93272009-06-19 17:00:27 -0700172status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800173 PixelFormat format, uint32_t flags)
174{
Mathias Agopian401c2572009-09-23 19:16:27 -0700175 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800176 PixelFormatInfo info;
177 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800178 if (err) {
179 ALOGE("unsupported pixelformat %d", format);
180 return err;
181 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800182
Mathias Agopianca99fb82010-04-14 16:43:44 -0700183 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700184 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700185
186 // never allow a surface larger than what our underlying GL implementation
187 // can handle.
188 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800189 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700190 return BAD_VALUE;
191 }
192
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700193 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700194
Mathias Agopian3165cc22012-08-08 19:42:09 -0700195 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
196 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
197 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700198 mCurrentOpacity = getOpacityForFormat(format);
199
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800200 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
201 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
202 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700203
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800204 return NO_ERROR;
205}
206
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700207sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800208 Mutex::Autolock _l(mLock);
209
210 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700211 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800212
213 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700214
215 /*
216 * The layer handle is just a BBinder object passed to the client
217 * (remote process) -- we don't keep any reference on our side such that
218 * the dtor is called when the remote side let go of its reference.
219 *
220 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
221 * this layer when the handle is destroyed.
222 */
223
224 class Handle : public BBinder, public LayerCleaner {
225 wp<const Layer> mOwner;
226 public:
227 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
228 : LayerCleaner(flinger, layer), mOwner(layer) {
229 }
230 };
231
232 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800233}
234
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700235sp<BufferQueue> Layer::getBufferQueue() const {
236 return mSurfaceFlingerConsumer->getBufferQueue();
237}
238
239//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
240// sp<IGraphicBufferProducer> res;
241// sp<const Layer> that( mOwner.promote() );
242// if (that != NULL) {
243// res = that->mSurfaceFlingerConsumer->getBufferQueue();
244// }
245// return res;
246//}
247
Mathias Agopian13127d82013-03-05 17:47:11 -0800248// ---------------------------------------------------------------------------
249// h/w composer set-up
250// ---------------------------------------------------------------------------
251
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800252Rect Layer::getContentCrop() const {
253 // this is the crop rectangle that applies to the buffer
254 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700255 Rect crop;
256 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800257 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700258 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800259 } else if (mActiveBuffer != NULL) {
260 // otherwise we use the whole buffer
261 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700262 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800263 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700264 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700265 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700266 return crop;
267}
268
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800269uint32_t Layer::getContentTransform() const {
270 return mCurrentTransform;
271}
272
Mathias Agopian13127d82013-03-05 17:47:11 -0800273Rect Layer::computeBounds() const {
274 const Layer::State& s(drawingState());
275 Rect win(s.active.w, s.active.h);
276 if (!s.active.crop.isEmpty()) {
277 win.intersect(s.active.crop, &win);
278 }
279 return win;
280}
281
282Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
283 /*
284 * The way we compute the crop (aka. texture coordinates when we have a
285 * Layer) produces a different output from the GL code in
286 * drawWithOpenGL() due to HWC being limited to integers. The difference
287 * can be large if getContentTransform() contains a large scale factor.
288 * See comments in drawWithOpenGL() for more details.
289 */
290
291 // the content crop is the area of the content that gets scaled to the
292 // layer's size.
293 Rect crop(getContentCrop());
294
295 // the active.crop is the area of the window that gets cropped, but not
296 // scaled in any ways.
297 const State& s(drawingState());
298
299 // apply the projection's clipping to the window crop in
300 // layerstack space, and convert-back to layer space.
301 // if there are no window scaling (or content scaling) involved,
302 // this operation will map to full pixels in the buffer.
303 // NOTE: should we revert to GL composition if a scaling is involved
304 // since it cannot be represented in the HWC API?
305 Rect activeCrop(s.transform.transform(s.active.crop));
306 activeCrop.intersect(hw->getViewport(), &activeCrop);
307 activeCrop = s.transform.inverse().transform(activeCrop);
308
309 // paranoia: make sure the window-crop is constrained in the
310 // window's bounds
311 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
312
313 if (!activeCrop.isEmpty()) {
314 // Transform the window crop to match the buffer coordinate system,
315 // which means using the inverse of the current transform set on the
316 // SurfaceFlingerConsumer.
317 uint32_t invTransform = getContentTransform();
318 int winWidth = s.active.w;
319 int winHeight = s.active.h;
320 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
321 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
322 NATIVE_WINDOW_TRANSFORM_FLIP_H;
323 winWidth = s.active.h;
324 winHeight = s.active.w;
325 }
326 const Rect winCrop = activeCrop.transform(
327 invTransform, s.active.w, s.active.h);
328
329 // the code below essentially performs a scaled intersection
330 // of crop and winCrop
331 float xScale = float(crop.width()) / float(winWidth);
332 float yScale = float(crop.height()) / float(winHeight);
333
334 int insetL = int(ceilf( winCrop.left * xScale));
335 int insetT = int(ceilf( winCrop.top * yScale));
336 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
337 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
338
339 crop.left += insetL;
340 crop.top += insetT;
341 crop.right -= insetR;
342 crop.bottom -= insetB;
343 }
344 return crop;
345}
346
Mathias Agopian4fec8732012-06-29 14:12:52 -0700347void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700348 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700349 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700350{
Mathias Agopian13127d82013-03-05 17:47:11 -0800351 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700352
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700353 // enable this layer
354 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700355
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700356 if (isSecure() && !hw->isSecure()) {
357 layer.setSkip(true);
358 }
359
Mathias Agopian13127d82013-03-05 17:47:11 -0800360 // this gives us only the "orientation" component of the transform
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800361 const State& s(drawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800362 if (!isOpaque() || s.alpha != 0xFF) {
363 layer.setBlending(mPremultipliedAlpha ?
364 HWC_BLENDING_PREMULT :
365 HWC_BLENDING_COVERAGE);
366 }
367
368 // apply the layer's transform, followed by the display's global transform
369 // here we're guaranteed that the layer's transform preserves rects
370 Rect frame(s.transform.transform(computeBounds()));
371 frame.intersect(hw->getViewport(), &frame);
372 const Transform& tr(hw->getTransform());
373 layer.setFrame(tr.transform(frame));
374 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800375 layer.setPlaneAlpha(s.alpha);
376
Mathias Agopian29a367b2011-07-12 14:51:45 -0700377 /*
378 * Transformations are applied in this order:
379 * 1) buffer orientation/flip/mirror
380 * 2) state transformation (window manager)
381 * 3) layer orientation (screen orientation)
382 * (NOTE: the matrices are multiplied in reverse order)
383 */
384
385 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800386 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700387
388 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800389 const uint32_t orientation = transform.getOrientation();
390 if (orientation & Transform::ROT_INVALID) {
391 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700392 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700393 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800394 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700395 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700396}
397
Mathias Agopian42977342012-08-05 00:40:46 -0700398void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700399 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800400 // we have to set the visible region on every frame because
401 // we currently free it during onLayerDisplayed(), which is called
402 // after HWComposer::commit() -- every frame.
403 // Apply this display's projection's viewport to the visible region
404 // before giving it to the HWC HAL.
405 const Transform& tr = hw->getTransform();
406 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
407 layer.setVisibleRegionScreen(visible);
408
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700409 // NOTE: buffer can be NULL if the client never drew into this
410 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700411 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700412}
Jesse Halldc5b4852012-06-29 15:21:18 -0700413
Mathias Agopian42977342012-08-05 00:40:46 -0700414void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700415 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700416 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700417
418 // TODO: there is a possible optimization here: we only need to set the
419 // acquire fence the first time a new buffer is acquired on EACH display.
420
421 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800422 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800423 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700424 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700425 if (fenceFd == -1) {
426 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
427 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700428 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700429 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700430 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700431}
432
Mathias Agopian13127d82013-03-05 17:47:11 -0800433// ---------------------------------------------------------------------------
434// drawing...
435// ---------------------------------------------------------------------------
436
437void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
438 onDraw(hw, clip);
439}
440
441void Layer::draw(const sp<const DisplayDevice>& hw) {
442 onDraw( hw, Region(hw->bounds()) );
443}
444
Mathias Agopian42977342012-08-05 00:40:46 -0700445void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800446{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800447 ATRACE_CALL();
448
Mathias Agopiana67932f2011-04-20 14:20:59 -0700449 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800450 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700451 // in fact never been drawn into. This happens frequently with
452 // SurfaceView because the WindowManager can't know when the client
453 // has drawn the first time.
454
455 // If there is nothing under us, we paint the screen in black, otherwise
456 // we just skip this update.
457
458 // figure out if there is something below us
459 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700460 const SurfaceFlinger::LayerVector& drawingLayers(
461 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700462 const size_t count = drawingLayers.size();
463 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800464 const sp<Layer>& layer(drawingLayers[i]);
465 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700466 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700467 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700468 }
469 // if not everything below us is covered, we plug the holes!
470 Region holes(clip.subtract(under));
471 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700472 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700473 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800474 return;
475 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700476
Andy McFadden97eba892012-12-11 15:21:45 -0800477 // Bind the current buffer to the GL texture, and wait for it to be
478 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800479 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
480 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800481 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700482 // Go ahead and draw the buffer anyway; no matter what we do the screen
483 // is probably going to have something visibly wrong.
484 }
485
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700486 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
487
488 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700489 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700490 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700491
492 // Query the texture matrix given our current filtering mode.
493 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800494 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
495 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700496
497 // Set things up for texturing.
Mathias Agopianc492e672011-10-18 14:49:27 -0700498 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
499 GLenum filter = GL_NEAREST;
Jamie Genniscbb1a952012-05-08 17:05:52 -0700500 if (useFiltering) {
Mathias Agopianc492e672011-10-18 14:49:27 -0700501 filter = GL_LINEAR;
Jamie Gennis9575f602011-10-07 14:51:16 -0700502 }
Mathias Agopianc492e672011-10-18 14:49:27 -0700503 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
504 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
Jamie Gennis9575f602011-10-07 14:51:16 -0700505 glMatrixMode(GL_TEXTURE);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700506 glLoadMatrixf(textureMatrix);
Jamie Gennis9575f602011-10-07 14:51:16 -0700507 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700508 glDisable(GL_TEXTURE_2D);
Xavier Ducrohet4c4163b2011-10-21 16:18:48 -0700509 glEnable(GL_TEXTURE_EXTERNAL_OES);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700510 } else {
Mathias Agopianc492e672011-10-18 14:49:27 -0700511 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
Jamie Gennis9575f602011-10-07 14:51:16 -0700512 glMatrixMode(GL_TEXTURE);
513 glLoadIdentity();
514 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700515 glDisable(GL_TEXTURE_EXTERNAL_OES);
516 glEnable(GL_TEXTURE_2D);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700517 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700518
Mathias Agopian1b031492012-06-20 17:51:20 -0700519 drawWithOpenGL(hw, clip);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700520
Mathias Agopianc492e672011-10-18 14:49:27 -0700521 glDisable(GL_TEXTURE_EXTERNAL_OES);
522 glDisable(GL_TEXTURE_2D);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800523}
524
Mathias Agopian13127d82013-03-05 17:47:11 -0800525
526void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
527 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
528{
529 const uint32_t fbHeight = hw->getHeight();
530 glColor4f(red,green,blue,alpha);
531
532 glDisable(GL_TEXTURE_EXTERNAL_OES);
533 glDisable(GL_TEXTURE_2D);
534 glDisable(GL_BLEND);
535
536 LayerMesh mesh;
537 computeGeometry(hw, &mesh);
538
539 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
540 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
541}
542
543void Layer::clearWithOpenGL(
544 const sp<const DisplayDevice>& hw, const Region& clip) const {
545 clearWithOpenGL(hw, clip, 0,0,0,0);
546}
547
548void Layer::drawWithOpenGL(
549 const sp<const DisplayDevice>& hw, const Region& clip) const {
550 const uint32_t fbHeight = hw->getHeight();
551 const State& s(drawingState());
552
553 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
554 if (CC_UNLIKELY(s.alpha < 0xFF)) {
555 const GLfloat alpha = s.alpha * (1.0f/255.0f);
556 if (mPremultipliedAlpha) {
557 glColor4f(alpha, alpha, alpha, alpha);
558 } else {
559 glColor4f(1, 1, 1, alpha);
560 }
561 glEnable(GL_BLEND);
562 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
563 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
564 } else {
565 glColor4f(1, 1, 1, 1);
566 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
567 if (!isOpaque()) {
568 glEnable(GL_BLEND);
569 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
570 } else {
571 glDisable(GL_BLEND);
572 }
573 }
574
575 LayerMesh mesh;
576 computeGeometry(hw, &mesh);
577
578 // TODO: we probably want to generate the texture coords with the mesh
579 // here we assume that we only have 4 vertices
580
581 struct TexCoords {
582 GLfloat u;
583 GLfloat v;
584 };
585
586
587 /*
588 * NOTE: the way we compute the texture coordinates here produces
589 * different results than when we take the HWC path -- in the later case
590 * the "source crop" is rounded to texel boundaries.
591 * This can produce significantly different results when the texture
592 * is scaled by a large amount.
593 *
594 * The GL code below is more logical (imho), and the difference with
595 * HWC is due to a limitation of the HWC API to integers -- a question
596 * is suspend is wether we should ignore this problem or revert to
597 * GL composition when a buffer scaling is applied (maybe with some
598 * minimal value)? Or, we could make GL behave like HWC -- but this feel
599 * like more of a hack.
600 */
601 const Rect win(computeBounds());
602
603 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
604 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
605 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
606 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
607
608 TexCoords texCoords[4];
609 texCoords[0].u = left;
610 texCoords[0].v = top;
611 texCoords[1].u = left;
612 texCoords[1].v = bottom;
613 texCoords[2].u = right;
614 texCoords[2].v = bottom;
615 texCoords[3].u = right;
616 texCoords[3].v = top;
617 for (int i = 0; i < 4; i++) {
618 texCoords[i].v = 1.0f - texCoords[i].v;
619 }
620
621 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
622 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
623 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
624 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
625
626 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
627 glDisable(GL_BLEND);
628}
629
630void Layer::setFiltering(bool filtering) {
631 mFiltering = filtering;
632}
633
634bool Layer::getFiltering() const {
635 return mFiltering;
636}
637
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800638// As documented in libhardware header, formats in the range
639// 0x100 - 0x1FF are specific to the HAL implementation, and
640// are known to have no alpha channel
641// TODO: move definition for device-specific range into
642// hardware.h, instead of using hard-coded values here.
643#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
644
Mathias Agopiana67932f2011-04-20 14:20:59 -0700645bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800646{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700647 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
648 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800649 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700650 PixelFormatInfo info;
651 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
652 // in case of error (unknown format), we assume no blending
653 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800654}
655
Mathias Agopian13127d82013-03-05 17:47:11 -0800656// ----------------------------------------------------------------------------
657// local state
658// ----------------------------------------------------------------------------
659
660void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
661{
662 const Layer::State& s(drawingState());
663 const Transform tr(hw->getTransform() * s.transform);
664 const uint32_t hw_h = hw->getHeight();
665 Rect win(s.active.w, s.active.h);
666 if (!s.active.crop.isEmpty()) {
667 win.intersect(s.active.crop, &win);
668 }
669 if (mesh) {
670 tr.transform(mesh->mVertices[0], win.left, win.top);
671 tr.transform(mesh->mVertices[1], win.left, win.bottom);
672 tr.transform(mesh->mVertices[2], win.right, win.bottom);
673 tr.transform(mesh->mVertices[3], win.right, win.top);
674 for (size_t i=0 ; i<4 ; i++) {
675 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
676 }
677 }
678}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800679
Mathias Agopiana67932f2011-04-20 14:20:59 -0700680bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700681{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700682 // if we don't have a buffer yet, we're translucent regardless of the
683 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700684 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700685 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700686 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700687
688 // if the layer has the opaque flag, then we're always opaque,
689 // otherwise we use the current buffer's format.
690 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700691}
692
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800693bool Layer::isProtected() const
694{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700695 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800696 return (activeBuffer != 0) &&
697 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
698}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700699
Mathias Agopian13127d82013-03-05 17:47:11 -0800700bool Layer::isFixedSize() const {
701 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
702}
703
704bool Layer::isCropped() const {
705 return !mCurrentCrop.isEmpty();
706}
707
708bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
709 return mNeedsFiltering || hw->needsFiltering();
710}
711
712void Layer::setVisibleRegion(const Region& visibleRegion) {
713 // always called from main thread
714 this->visibleRegion = visibleRegion;
715}
716
717void Layer::setCoveredRegion(const Region& coveredRegion) {
718 // always called from main thread
719 this->coveredRegion = coveredRegion;
720}
721
722void Layer::setVisibleNonTransparentRegion(const Region&
723 setVisibleNonTransparentRegion) {
724 // always called from main thread
725 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
726}
727
728// ----------------------------------------------------------------------------
729// transaction
730// ----------------------------------------------------------------------------
731
732uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800733 ATRACE_CALL();
734
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800735 const Layer::State& front(drawingState());
736 const Layer::State& temp(currentState());
737
Mathias Agopian4824d402012-06-04 18:16:30 -0700738 const bool sizeChanged = (temp.requested.w != front.requested.w) ||
739 (temp.requested.h != front.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700740
741 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700742 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000743 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700744 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700745 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
746 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
747 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
748 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700749 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
Mathias Agopian419e1962012-05-23 14:34:07 -0700750 temp.active.w, temp.active.h,
751 temp.active.crop.left,
752 temp.active.crop.top,
753 temp.active.crop.right,
754 temp.active.crop.bottom,
755 temp.active.crop.getWidth(),
756 temp.active.crop.getHeight(),
757 temp.requested.w, temp.requested.h,
Mathias Agopianb30c4152012-05-16 18:21:32 -0700758 temp.requested.crop.left,
759 temp.requested.crop.top,
760 temp.requested.crop.right,
761 temp.requested.crop.bottom,
762 temp.requested.crop.getWidth(),
763 temp.requested.crop.getHeight(),
Mathias Agopian419e1962012-05-23 14:34:07 -0700764 front.active.w, front.active.h,
765 front.active.crop.left,
766 front.active.crop.top,
767 front.active.crop.right,
768 front.active.crop.bottom,
769 front.active.crop.getWidth(),
770 front.active.crop.getHeight(),
771 front.requested.w, front.requested.h,
Mathias Agopianb30c4152012-05-16 18:21:32 -0700772 front.requested.crop.left,
773 front.requested.crop.top,
774 front.requested.crop.right,
775 front.requested.crop.bottom,
776 front.requested.crop.getWidth(),
Mathias Agopian419e1962012-05-23 14:34:07 -0700777 front.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800778
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700779 // record the new size, form this point on, when the client request
780 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800781 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopianb30c4152012-05-16 18:21:32 -0700782 temp.requested.w, temp.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800783 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700784
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700785 if (!isFixedSize()) {
786
787 const bool resizePending = (temp.requested.w != temp.active.w) ||
788 (temp.requested.h != temp.active.h);
789
790 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800791 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700792 // if we have a pending resize, unless we are in fixed-size mode.
793 // the drawing state will be updated only once we receive a buffer
794 // with the correct size.
795 //
796 // in particular, we want to make sure the clip (which is part
797 // of the geometry state) is latched together with the size but is
798 // latched immediately when no resizing is involved.
799
800 flags |= eDontUpdateGeometryState;
801 }
802 }
803
Mathias Agopian13127d82013-03-05 17:47:11 -0800804 // always set active to requested, unless we're asked not to
805 // this is used by Layer, which special cases resizes.
806 if (flags & eDontUpdateGeometryState) {
807 } else {
808 Layer::State& editTemp(currentState());
809 editTemp.active = temp.requested;
810 }
811
812 if (front.active != temp.active) {
813 // invalidate and recompute the visible regions if needed
814 flags |= Layer::eVisibleRegion;
815 }
816
817 if (temp.sequence != front.sequence) {
818 // invalidate and recompute the visible regions if needed
819 flags |= eVisibleRegion;
820 this->contentDirty = true;
821
822 // we may use linear filtering, if the matrix scales us
823 const uint8_t type = temp.transform.getType();
824 mNeedsFiltering = (!temp.transform.preserveRects() ||
825 (type >= Transform::SCALE));
826 }
827
828 // Commit the transaction
829 commitTransaction();
830 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800831}
832
Mathias Agopian13127d82013-03-05 17:47:11 -0800833void Layer::commitTransaction() {
834 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700835}
836
Mathias Agopian13127d82013-03-05 17:47:11 -0800837uint32_t Layer::getTransactionFlags(uint32_t flags) {
838 return android_atomic_and(~flags, &mTransactionFlags) & flags;
839}
840
841uint32_t Layer::setTransactionFlags(uint32_t flags) {
842 return android_atomic_or(flags, &mTransactionFlags);
843}
844
845bool Layer::setPosition(float x, float y) {
846 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
847 return false;
848 mCurrentState.sequence++;
849 mCurrentState.transform.set(x, y);
850 setTransactionFlags(eTransactionNeeded);
851 return true;
852}
853bool Layer::setLayer(uint32_t z) {
854 if (mCurrentState.z == z)
855 return false;
856 mCurrentState.sequence++;
857 mCurrentState.z = z;
858 setTransactionFlags(eTransactionNeeded);
859 return true;
860}
861bool Layer::setSize(uint32_t w, uint32_t h) {
862 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
863 return false;
864 mCurrentState.requested.w = w;
865 mCurrentState.requested.h = h;
866 setTransactionFlags(eTransactionNeeded);
867 return true;
868}
869bool Layer::setAlpha(uint8_t alpha) {
870 if (mCurrentState.alpha == alpha)
871 return false;
872 mCurrentState.sequence++;
873 mCurrentState.alpha = alpha;
874 setTransactionFlags(eTransactionNeeded);
875 return true;
876}
877bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
878 mCurrentState.sequence++;
879 mCurrentState.transform.set(
880 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
881 setTransactionFlags(eTransactionNeeded);
882 return true;
883}
884bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700885 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800886 setTransactionFlags(eTransactionNeeded);
887 return true;
888}
889bool Layer::setFlags(uint8_t flags, uint8_t mask) {
890 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
891 if (mCurrentState.flags == newFlags)
892 return false;
893 mCurrentState.sequence++;
894 mCurrentState.flags = newFlags;
895 setTransactionFlags(eTransactionNeeded);
896 return true;
897}
898bool Layer::setCrop(const Rect& crop) {
899 if (mCurrentState.requested.crop == crop)
900 return false;
901 mCurrentState.sequence++;
902 mCurrentState.requested.crop = crop;
903 setTransactionFlags(eTransactionNeeded);
904 return true;
905}
906
907bool Layer::setLayerStack(uint32_t layerStack) {
908 if (mCurrentState.layerStack == layerStack)
909 return false;
910 mCurrentState.sequence++;
911 mCurrentState.layerStack = layerStack;
912 setTransactionFlags(eTransactionNeeded);
913 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700914}
915
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800916// ----------------------------------------------------------------------------
917// pageflip handling...
918// ----------------------------------------------------------------------------
919
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800920bool Layer::onPreComposition() {
921 mRefreshPending = false;
922 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800923}
924
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700925void Layer::onPostComposition() {
926 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800927 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800928 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
929
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800930 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800931 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800932 mFrameTracker.setFrameReadyFence(frameReadyFence);
933 } else {
934 // There was no fence for this frame, so assume that it was ready
935 // to be presented at the desired present time.
936 mFrameTracker.setFrameReadyTime(desiredPresentTime);
937 }
938
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700939 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800940 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800941 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800942 mFrameTracker.setActualPresentFence(presentFence);
943 } else {
944 // The HWC doesn't support present fences, so use the refresh
945 // timestamp instead.
946 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
947 mFrameTracker.setActualPresentTime(presentTime);
948 }
949
950 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700951 mFrameLatencyNeeded = false;
952 }
953}
954
Mathias Agopianda27af92012-09-13 18:17:13 -0700955bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800956 const Layer::State& s(mDrawingState);
957 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
958 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700959}
960
Mathias Agopian4fec8732012-06-29 14:12:52 -0700961Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800962{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800963 ATRACE_CALL();
964
Mathias Agopian4fec8732012-06-29 14:12:52 -0700965 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700966 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800967
968 // if we've already called updateTexImage() without going through
969 // a composition step, we have to skip this layer at this point
970 // because we cannot call updateTeximage() without a corresponding
971 // compositionComplete() call.
972 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800973 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700974 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800975 }
976
Jamie Gennis351a5132011-09-14 18:23:37 -0700977 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700978 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700979 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700980
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700981 // signal another event if we have more frames pending
982 if (android_atomic_dec(&mQueuedFrames) > 1) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800983 mFlinger->signalLayerUpdate();
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700984 }
985
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800986 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700987 Layer::State& front;
988 Layer::State& current;
989 bool& recomputeVisibleRegions;
990 Reject(Layer::State& front, Layer::State& current,
991 bool& recomputeVisibleRegions)
992 : front(front), current(current),
993 recomputeVisibleRegions(recomputeVisibleRegions) {
994 }
995
996 virtual bool reject(const sp<GraphicBuffer>& buf,
997 const BufferQueue::BufferItem& item) {
998 if (buf == NULL) {
999 return false;
1000 }
1001
1002 uint32_t bufWidth = buf->getWidth();
1003 uint32_t bufHeight = buf->getHeight();
1004
1005 // check that we received a buffer of the right size
1006 // (Take the buffer's orientation into account)
1007 if (item.mTransform & Transform::ROT_90) {
1008 swap(bufWidth, bufHeight);
1009 }
1010
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001011 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1012 if (front.active != front.requested) {
1013
1014 if (isFixedSize ||
1015 (bufWidth == front.requested.w &&
1016 bufHeight == front.requested.h))
1017 {
1018 // Here we pretend the transaction happened by updating the
1019 // current and drawing states. Drawing state is only accessed
1020 // in this thread, no need to have it locked
1021 front.active = front.requested;
1022
1023 // We also need to update the current state so that
1024 // we don't end-up overwriting the drawing state with
1025 // this stale current state during the next transaction
1026 //
1027 // NOTE: We don't need to hold the transaction lock here
1028 // because State::active is only accessed from this thread.
1029 current.active = front.active;
1030
1031 // recompute visible region
1032 recomputeVisibleRegions = true;
1033 }
1034
1035 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001036 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001037 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1038 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001039 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001040 front.active.w, front.active.h,
1041 front.active.crop.left,
1042 front.active.crop.top,
1043 front.active.crop.right,
1044 front.active.crop.bottom,
1045 front.active.crop.getWidth(),
1046 front.active.crop.getHeight(),
1047 front.requested.w, front.requested.h,
1048 front.requested.crop.left,
1049 front.requested.crop.top,
1050 front.requested.crop.right,
1051 front.requested.crop.bottom,
1052 front.requested.crop.getWidth(),
1053 front.requested.crop.getHeight());
1054 }
1055
1056 if (!isFixedSize) {
1057 if (front.active.w != bufWidth ||
1058 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001059 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001060 return true;
1061 }
1062 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001063
1064 // if the transparent region has changed (this test is
1065 // conservative, but that's fine, worst case we're doing
1066 // a bit of extra work), we latch the new one and we
1067 // trigger a visible-region recompute.
1068 if (!front.activeTransparentRegion.isTriviallyEqual(
1069 front.requestedTransparentRegion)) {
1070 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001071
1072 // We also need to update the current state so that
1073 // we don't end-up overwriting the drawing state with
1074 // this stale current state during the next transaction
1075 //
1076 // NOTE: We don't need to hold the transaction lock here
1077 // because State::active is only accessed from this thread.
1078 current.activeTransparentRegion = front.activeTransparentRegion;
1079
1080 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001081 recomputeVisibleRegions = true;
1082 }
1083
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001084 return false;
1085 }
1086 };
1087
1088
1089 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
1090
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001091 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001092 // something happened!
1093 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001094 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001095 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001096
Jamie Gennis351a5132011-09-14 18:23:37 -07001097 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001098 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001099 if (mActiveBuffer == NULL) {
1100 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001101 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001102 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001103
Mathias Agopian4824d402012-06-04 18:16:30 -07001104 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001105 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001106 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001107 // the first time we receive a buffer, we need to trigger a
1108 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001109 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001110 }
1111
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001112 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1113 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1114 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001115 if ((crop != mCurrentCrop) ||
1116 (transform != mCurrentTransform) ||
1117 (scalingMode != mCurrentScalingMode))
1118 {
1119 mCurrentCrop = crop;
1120 mCurrentTransform = transform;
1121 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001122 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001123 }
1124
1125 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001126 uint32_t bufWidth = mActiveBuffer->getWidth();
1127 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001128 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1129 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001130 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001131 }
1132 }
1133
1134 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1135 if (oldOpacity != isOpaque()) {
1136 recomputeVisibleRegions = true;
1137 }
1138
Mathias Agopian702634a2012-05-23 17:50:31 -07001139 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1140 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Mathias Agopian4fec8732012-06-29 14:12:52 -07001141
1142 // FIXME: postedRegion should be dirty & bounds
1143 const Layer::State& front(drawingState());
1144 Region dirtyRegion(Rect(front.active.w, front.active.h));
1145
1146 // transform the dirty region to window-manager space
1147 outDirtyRegion = (front.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001148 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001149 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001150}
1151
Mathias Agopiana67932f2011-04-20 14:20:59 -07001152uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001153{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001154 // TODO: should we do something special if mSecure is set?
1155 if (mProtectedByApp) {
1156 // need a hardware-protected path to external video sink
1157 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001158 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001159 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001160 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001161}
1162
Mathias Agopian84300952012-11-21 16:02:13 -08001163void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001164 uint32_t orientation = 0;
1165 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001166 // The transform hint is used to improve performance, but we can
1167 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001168 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001169 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001170 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001171 if (orientation & Transform::ROT_INVALID) {
1172 orientation = 0;
1173 }
1174 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001175 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001176}
1177
Mathias Agopian13127d82013-03-05 17:47:11 -08001178// ----------------------------------------------------------------------------
1179// debugging
1180// ----------------------------------------------------------------------------
1181
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001182void Layer::dump(String8& result, Colorizer& colorizer) const
Mathias Agopian13127d82013-03-05 17:47:11 -08001183{
1184 const Layer::State& s(drawingState());
1185
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001186 colorizer.colorize(result, Colorizer::GREEN);
Mathias Agopian74d211a2013-04-22 16:55:35 +02001187 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001188 "+ %s %p (%s)\n",
1189 getTypeId(), this, getName().string());
Mathias Agopian3e25fd82013-04-22 17:52:16 +02001190 colorizer.reset(result);
Mathias Agopian13127d82013-03-05 17:47:11 -08001191
Mathias Agopian2ca79392013-04-02 18:30:32 -07001192 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001193 visibleRegion.dump(result, "visibleRegion");
1194 sp<Client> client(mClientRef.promote());
1195
Mathias Agopian74d211a2013-04-22 16:55:35 +02001196 result.appendFormat( " "
Mathias Agopian13127d82013-03-05 17:47:11 -08001197 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1198 "isOpaque=%1d, invalidate=%1d, "
1199 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1200 " client=%p\n",
1201 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1202 s.active.crop.left, s.active.crop.top,
1203 s.active.crop.right, s.active.crop.bottom,
1204 isOpaque(), contentDirty,
1205 s.alpha, s.flags,
1206 s.transform[0][0], s.transform[0][1],
1207 s.transform[1][0], s.transform[1][1],
1208 client.get());
Mathias Agopian13127d82013-03-05 17:47:11 -08001209
1210 sp<const GraphicBuffer> buf0(mActiveBuffer);
1211 uint32_t w0=0, h0=0, s0=0, f0=0;
1212 if (buf0 != 0) {
1213 w0 = buf0->getWidth();
1214 h0 = buf0->getHeight();
1215 s0 = buf0->getStride();
1216 f0 = buf0->format;
1217 }
Mathias Agopian74d211a2013-04-22 16:55:35 +02001218 result.appendFormat(
Mathias Agopian13127d82013-03-05 17:47:11 -08001219 " "
1220 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1221 " queued-frames=%d, mRefreshPending=%d\n",
1222 mFormat, w0, h0, s0,f0,
1223 mQueuedFrames, mRefreshPending);
1224
Mathias Agopian13127d82013-03-05 17:47:11 -08001225 if (mSurfaceFlingerConsumer != 0) {
Mathias Agopian74d211a2013-04-22 16:55:35 +02001226 mSurfaceFlingerConsumer->dump(result, " ");
Mathias Agopian13127d82013-03-05 17:47:11 -08001227 }
1228}
1229
Mathias Agopian74d211a2013-04-22 16:55:35 +02001230void Layer::dumpStats(String8& result) const {
Mathias Agopian13127d82013-03-05 17:47:11 -08001231 mFrameTracker.dump(result);
1232}
1233
1234void Layer::clearStats() {
1235 mFrameTracker.clear();
1236}
1237
1238// ---------------------------------------------------------------------------
1239
1240Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1241 const sp<Layer>& layer)
1242 : mFlinger(flinger), mLayer(layer) {
1243}
1244
1245Layer::LayerCleaner::~LayerCleaner() {
1246 // destroy client resources
1247 mFlinger->onLayerDestroyed(mLayer);
1248}
1249
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001250// ---------------------------------------------------------------------------
1251
1252
1253}; // namespace android