blob: 4779804a29a4e3f76b4c5cdeab5a35aca54593f0 [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 Agopian0f2f5ff2012-07-31 23:09:07 -070039#include "DisplayDevice.h"
Mathias Agopian1f7bec62010-06-25 18:02:21 -070040#include "GLExtensions.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
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080047#define DEBUG_RESIZE 0
48
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080049namespace android {
50
51// ---------------------------------------------------------------------------
52
Mathias Agopian13127d82013-03-05 17:47:11 -080053int32_t Layer::sSequence = 1;
54
Mathias Agopian4d9b8222013-03-12 17:11:48 -070055Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
56 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
Mathias Agopian13127d82013-03-05 17:47:11 -080057 : contentDirty(false),
58 sequence(uint32_t(android_atomic_inc(&sSequence))),
59 mFlinger(flinger),
Mathias Agopiana67932f2011-04-20 14:20:59 -070060 mTextureName(-1U),
Mathias Agopian13127d82013-03-05 17:47:11 -080061 mPremultipliedAlpha(true),
62 mName("unnamed"),
63 mDebug(false),
64 mFormat(PIXEL_FORMAT_NONE),
65 mGLExtensions(GLExtensions::getInstance()),
66 mOpaqueLayer(true),
67 mTransactionFlags(0),
Mathias Agopiana67932f2011-04-20 14:20:59 -070068 mQueuedFrames(0),
69 mCurrentTransform(0),
Mathias Agopian933389f2011-07-18 16:15:08 -070070 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
Mathias Agopiana67932f2011-04-20 14:20:59 -070071 mCurrentOpacity(true),
Mathias Agopian4d143ee2012-02-23 20:05:39 -080072 mRefreshPending(false),
Mathias Agopian82d7ab62012-01-19 18:34:40 -080073 mFrameLatencyNeeded(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080074 mFiltering(false),
75 mNeedsFiltering(false),
Mathias Agopianb7e930d2010-06-01 15:12:58 -070076 mSecure(false),
Mathias Agopian13127d82013-03-05 17:47:11 -080077 mProtectedByApp(false),
78 mHasSurface(false),
79 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080080{
Mathias Agopiana67932f2011-04-20 14:20:59 -070081 mCurrentCrop.makeInvalid();
82 glGenTextures(1, &mTextureName);
Mathias Agopian4d9b8222013-03-12 17:11:48 -070083
84 uint32_t layerFlags = 0;
85 if (flags & ISurfaceComposerClient::eHidden)
86 layerFlags = layer_state_t::eLayerHidden;
87
88 if (flags & ISurfaceComposerClient::eNonPremultiplied)
89 mPremultipliedAlpha = false;
90
91 mName = name;
92
93 mCurrentState.active.w = w;
94 mCurrentState.active.h = h;
95 mCurrentState.active.crop.makeInvalid();
96 mCurrentState.z = 0;
97 mCurrentState.alpha = 0xFF;
98 mCurrentState.layerStack = 0;
99 mCurrentState.flags = layerFlags;
100 mCurrentState.sequence = 0;
101 mCurrentState.transform.set(0, 0);
102 mCurrentState.requested = mCurrentState.active;
103
104 // drawing state & current state are identical
105 mDrawingState = mCurrentState;
Jamie Gennise8696a42012-01-15 18:54:57 -0800106}
107
Mathias Agopiana67932f2011-04-20 14:20:59 -0700108void Layer::onFirstRef()
Mathias Agopian96f08192010-06-02 23:28:45 -0700109{
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800110 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
Mathias Agopian67106042013-03-14 19:18:13 -0700111 sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800112 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
Mathias Agopiana0db3082012-04-23 13:59:36 -0700113 GL_TEXTURE_EXTERNAL_OES, false, bq);
Daniel Lamb2675792012-02-23 14:35:13 -0800114
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800115 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
116 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
117 mSurfaceFlingerConsumer->setSynchronousMode(true);
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700118 mSurfaceFlingerConsumer->setName(mName);
Daniel Lamb2675792012-02-23 14:35:13 -0800119
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700120#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
121#warning "disabling triple buffering"
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800122 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
Mathias Agopian7f42a9c2012-04-23 20:00:16 -0700123#else
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800124 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
Mathias Agopian303d5382012-02-05 01:49:16 -0800125#endif
Andy McFadden69052052012-09-14 16:10:11 -0700126
Mathias Agopian84300952012-11-21 16:02:13 -0800127 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
128 updateTransformHint(hw);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700129}
130
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700131Layer::~Layer() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800132 sp<Client> c(mClientRef.promote());
133 if (c != 0) {
134 c->detachLayer(this);
135 }
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700136 mFlinger->deleteTextureAsync(mTextureName);
Mathias Agopian96f08192010-06-02 23:28:45 -0700137}
138
Mathias Agopian13127d82013-03-05 17:47:11 -0800139// ---------------------------------------------------------------------------
140// callbacks
141// ---------------------------------------------------------------------------
142
143void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
144 HWComposer::HWCLayerInterface* layer) {
145 if (layer) {
146 layer->onDisplayed();
Jesse Hall13f01cb2013-03-20 11:37:21 -0700147 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
Mathias Agopian13127d82013-03-05 17:47:11 -0800148 }
149}
150
Igor Murashkina4a31492012-10-29 13:36:11 -0700151void Layer::onFrameAvailable() {
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700152 android_atomic_inc(&mQueuedFrames);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800153 mFlinger->signalLayerUpdate();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700154}
155
Mathias Agopian67106042013-03-14 19:18:13 -0700156// called with SurfaceFlinger::mStateLock from the drawing thread after
157// the layer has been remove from the current state list (and just before
158// it's removed from the drawing state list)
Mathias Agopian13127d82013-03-05 17:47:11 -0800159void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800160 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700161}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700162
Mathias Agopian13127d82013-03-05 17:47:11 -0800163// ---------------------------------------------------------------------------
164// set-up
165// ---------------------------------------------------------------------------
166
Mathias Agopian13127d82013-03-05 17:47:11 -0800167String8 Layer::getName() const {
168 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800169}
170
Mathias Agopianf9d93272009-06-19 17:00:27 -0700171status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800172 PixelFormat format, uint32_t flags)
173{
Mathias Agopian401c2572009-09-23 19:16:27 -0700174 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800175 PixelFormatInfo info;
176 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800177 if (err) {
178 ALOGE("unsupported pixelformat %d", format);
179 return err;
180 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800181
Mathias Agopianca99fb82010-04-14 16:43:44 -0700182 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700183 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700184
185 // never allow a surface larger than what our underlying GL implementation
186 // can handle.
187 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800188 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700189 return BAD_VALUE;
190 }
191
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700192 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700193
Mathias Agopian3165cc22012-08-08 19:42:09 -0700194 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
195 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
196 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700197 mCurrentOpacity = getOpacityForFormat(format);
198
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800199 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
200 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
201 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700202
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800203 return NO_ERROR;
204}
205
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700206sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800207 Mutex::Autolock _l(mLock);
208
209 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700210 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800211
212 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700213
214 /*
215 * The layer handle is just a BBinder object passed to the client
216 * (remote process) -- we don't keep any reference on our side such that
217 * the dtor is called when the remote side let go of its reference.
218 *
219 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
220 * this layer when the handle is destroyed.
221 */
222
223 class Handle : public BBinder, public LayerCleaner {
224 wp<const Layer> mOwner;
225 public:
226 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
227 : LayerCleaner(flinger, layer), mOwner(layer) {
228 }
229 };
230
231 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800232}
233
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700234sp<BufferQueue> Layer::getBufferQueue() const {
235 return mSurfaceFlingerConsumer->getBufferQueue();
236}
237
238//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
239// sp<IGraphicBufferProducer> res;
240// sp<const Layer> that( mOwner.promote() );
241// if (that != NULL) {
242// res = that->mSurfaceFlingerConsumer->getBufferQueue();
243// }
244// return res;
245//}
246
Mathias Agopian13127d82013-03-05 17:47:11 -0800247// ---------------------------------------------------------------------------
248// h/w composer set-up
249// ---------------------------------------------------------------------------
250
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800251Rect Layer::getContentCrop() const {
252 // this is the crop rectangle that applies to the buffer
253 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700254 Rect crop;
255 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800256 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700257 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800258 } else if (mActiveBuffer != NULL) {
259 // otherwise we use the whole buffer
260 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700261 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800262 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700263 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700264 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700265 return crop;
266}
267
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800268uint32_t Layer::getContentTransform() const {
269 return mCurrentTransform;
270}
271
Mathias Agopian13127d82013-03-05 17:47:11 -0800272Rect Layer::computeBounds() const {
273 const Layer::State& s(drawingState());
274 Rect win(s.active.w, s.active.h);
275 if (!s.active.crop.isEmpty()) {
276 win.intersect(s.active.crop, &win);
277 }
278 return win;
279}
280
281Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
282 /*
283 * The way we compute the crop (aka. texture coordinates when we have a
284 * Layer) produces a different output from the GL code in
285 * drawWithOpenGL() due to HWC being limited to integers. The difference
286 * can be large if getContentTransform() contains a large scale factor.
287 * See comments in drawWithOpenGL() for more details.
288 */
289
290 // the content crop is the area of the content that gets scaled to the
291 // layer's size.
292 Rect crop(getContentCrop());
293
294 // the active.crop is the area of the window that gets cropped, but not
295 // scaled in any ways.
296 const State& s(drawingState());
297
298 // apply the projection's clipping to the window crop in
299 // layerstack space, and convert-back to layer space.
300 // if there are no window scaling (or content scaling) involved,
301 // this operation will map to full pixels in the buffer.
302 // NOTE: should we revert to GL composition if a scaling is involved
303 // since it cannot be represented in the HWC API?
304 Rect activeCrop(s.transform.transform(s.active.crop));
305 activeCrop.intersect(hw->getViewport(), &activeCrop);
306 activeCrop = s.transform.inverse().transform(activeCrop);
307
308 // paranoia: make sure the window-crop is constrained in the
309 // window's bounds
310 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
311
312 if (!activeCrop.isEmpty()) {
313 // Transform the window crop to match the buffer coordinate system,
314 // which means using the inverse of the current transform set on the
315 // SurfaceFlingerConsumer.
316 uint32_t invTransform = getContentTransform();
317 int winWidth = s.active.w;
318 int winHeight = s.active.h;
319 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
320 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
321 NATIVE_WINDOW_TRANSFORM_FLIP_H;
322 winWidth = s.active.h;
323 winHeight = s.active.w;
324 }
325 const Rect winCrop = activeCrop.transform(
326 invTransform, s.active.w, s.active.h);
327
328 // the code below essentially performs a scaled intersection
329 // of crop and winCrop
330 float xScale = float(crop.width()) / float(winWidth);
331 float yScale = float(crop.height()) / float(winHeight);
332
333 int insetL = int(ceilf( winCrop.left * xScale));
334 int insetT = int(ceilf( winCrop.top * yScale));
335 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
336 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
337
338 crop.left += insetL;
339 crop.top += insetT;
340 crop.right -= insetR;
341 crop.bottom -= insetB;
342 }
343 return crop;
344}
345
Mathias Agopian4fec8732012-06-29 14:12:52 -0700346void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700347 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700348 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700349{
Mathias Agopian13127d82013-03-05 17:47:11 -0800350 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700351
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700352 // enable this layer
353 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700354
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700355 if (isSecure() && !hw->isSecure()) {
356 layer.setSkip(true);
357 }
358
Mathias Agopian13127d82013-03-05 17:47:11 -0800359 // this gives us only the "orientation" component of the transform
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800360 const State& s(drawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800361 if (!isOpaque() || s.alpha != 0xFF) {
362 layer.setBlending(mPremultipliedAlpha ?
363 HWC_BLENDING_PREMULT :
364 HWC_BLENDING_COVERAGE);
365 }
366
367 // apply the layer's transform, followed by the display's global transform
368 // here we're guaranteed that the layer's transform preserves rects
369 Rect frame(s.transform.transform(computeBounds()));
370 frame.intersect(hw->getViewport(), &frame);
371 const Transform& tr(hw->getTransform());
372 layer.setFrame(tr.transform(frame));
373 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800374 layer.setPlaneAlpha(s.alpha);
375
Mathias Agopian29a367b2011-07-12 14:51:45 -0700376 /*
377 * Transformations are applied in this order:
378 * 1) buffer orientation/flip/mirror
379 * 2) state transformation (window manager)
380 * 3) layer orientation (screen orientation)
381 * (NOTE: the matrices are multiplied in reverse order)
382 */
383
384 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800385 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700386
387 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800388 const uint32_t orientation = transform.getOrientation();
389 if (orientation & Transform::ROT_INVALID) {
390 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700391 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700392 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800393 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700394 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700395}
396
Mathias Agopian42977342012-08-05 00:40:46 -0700397void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700398 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800399 // we have to set the visible region on every frame because
400 // we currently free it during onLayerDisplayed(), which is called
401 // after HWComposer::commit() -- every frame.
402 // Apply this display's projection's viewport to the visible region
403 // before giving it to the HWC HAL.
404 const Transform& tr = hw->getTransform();
405 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
406 layer.setVisibleRegionScreen(visible);
407
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700408 // NOTE: buffer can be NULL if the client never drew into this
409 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700410 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700411}
Jesse Halldc5b4852012-06-29 15:21:18 -0700412
Mathias Agopian42977342012-08-05 00:40:46 -0700413void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700414 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700415 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700416
417 // TODO: there is a possible optimization here: we only need to set the
418 // acquire fence the first time a new buffer is acquired on EACH display.
419
420 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800421 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800422 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700423 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700424 if (fenceFd == -1) {
425 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
426 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700427 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700428 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700429 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700430}
431
Mathias Agopian13127d82013-03-05 17:47:11 -0800432// ---------------------------------------------------------------------------
433// drawing...
434// ---------------------------------------------------------------------------
435
436void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
437 onDraw(hw, clip);
438}
439
440void Layer::draw(const sp<const DisplayDevice>& hw) {
441 onDraw( hw, Region(hw->bounds()) );
442}
443
Mathias Agopian42977342012-08-05 00:40:46 -0700444void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800445{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800446 ATRACE_CALL();
447
Mathias Agopiana67932f2011-04-20 14:20:59 -0700448 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800449 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700450 // in fact never been drawn into. This happens frequently with
451 // SurfaceView because the WindowManager can't know when the client
452 // has drawn the first time.
453
454 // If there is nothing under us, we paint the screen in black, otherwise
455 // we just skip this update.
456
457 // figure out if there is something below us
458 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700459 const SurfaceFlinger::LayerVector& drawingLayers(
460 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700461 const size_t count = drawingLayers.size();
462 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800463 const sp<Layer>& layer(drawingLayers[i]);
464 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700465 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700466 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700467 }
468 // if not everything below us is covered, we plug the holes!
469 Region holes(clip.subtract(under));
470 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700471 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700472 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800473 return;
474 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700475
Andy McFadden97eba892012-12-11 15:21:45 -0800476 // Bind the current buffer to the GL texture, and wait for it to be
477 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800478 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
479 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800480 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700481 // Go ahead and draw the buffer anyway; no matter what we do the screen
482 // is probably going to have something visibly wrong.
483 }
484
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700485 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
486
487 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700488 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700489 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700490
491 // Query the texture matrix given our current filtering mode.
492 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800493 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
494 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700495
496 // Set things up for texturing.
Mathias Agopianc492e672011-10-18 14:49:27 -0700497 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
498 GLenum filter = GL_NEAREST;
Jamie Genniscbb1a952012-05-08 17:05:52 -0700499 if (useFiltering) {
Mathias Agopianc492e672011-10-18 14:49:27 -0700500 filter = GL_LINEAR;
Jamie Gennis9575f602011-10-07 14:51:16 -0700501 }
Mathias Agopianc492e672011-10-18 14:49:27 -0700502 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
503 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
Jamie Gennis9575f602011-10-07 14:51:16 -0700504 glMatrixMode(GL_TEXTURE);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700505 glLoadMatrixf(textureMatrix);
Jamie Gennis9575f602011-10-07 14:51:16 -0700506 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700507 glDisable(GL_TEXTURE_2D);
Xavier Ducrohet4c4163b2011-10-21 16:18:48 -0700508 glEnable(GL_TEXTURE_EXTERNAL_OES);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700509 } else {
Mathias Agopianc492e672011-10-18 14:49:27 -0700510 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
Jamie Gennis9575f602011-10-07 14:51:16 -0700511 glMatrixMode(GL_TEXTURE);
512 glLoadIdentity();
513 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700514 glDisable(GL_TEXTURE_EXTERNAL_OES);
515 glEnable(GL_TEXTURE_2D);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700516 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700517
Mathias Agopian1b031492012-06-20 17:51:20 -0700518 drawWithOpenGL(hw, clip);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700519
Mathias Agopianc492e672011-10-18 14:49:27 -0700520 glDisable(GL_TEXTURE_EXTERNAL_OES);
521 glDisable(GL_TEXTURE_2D);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800522}
523
Mathias Agopian13127d82013-03-05 17:47:11 -0800524
525void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
526 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
527{
528 const uint32_t fbHeight = hw->getHeight();
529 glColor4f(red,green,blue,alpha);
530
531 glDisable(GL_TEXTURE_EXTERNAL_OES);
532 glDisable(GL_TEXTURE_2D);
533 glDisable(GL_BLEND);
534
535 LayerMesh mesh;
536 computeGeometry(hw, &mesh);
537
538 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
539 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
540}
541
542void Layer::clearWithOpenGL(
543 const sp<const DisplayDevice>& hw, const Region& clip) const {
544 clearWithOpenGL(hw, clip, 0,0,0,0);
545}
546
547void Layer::drawWithOpenGL(
548 const sp<const DisplayDevice>& hw, const Region& clip) const {
549 const uint32_t fbHeight = hw->getHeight();
550 const State& s(drawingState());
551
552 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
553 if (CC_UNLIKELY(s.alpha < 0xFF)) {
554 const GLfloat alpha = s.alpha * (1.0f/255.0f);
555 if (mPremultipliedAlpha) {
556 glColor4f(alpha, alpha, alpha, alpha);
557 } else {
558 glColor4f(1, 1, 1, alpha);
559 }
560 glEnable(GL_BLEND);
561 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
562 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
563 } else {
564 glColor4f(1, 1, 1, 1);
565 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
566 if (!isOpaque()) {
567 glEnable(GL_BLEND);
568 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
569 } else {
570 glDisable(GL_BLEND);
571 }
572 }
573
574 LayerMesh mesh;
575 computeGeometry(hw, &mesh);
576
577 // TODO: we probably want to generate the texture coords with the mesh
578 // here we assume that we only have 4 vertices
579
580 struct TexCoords {
581 GLfloat u;
582 GLfloat v;
583 };
584
585
586 /*
587 * NOTE: the way we compute the texture coordinates here produces
588 * different results than when we take the HWC path -- in the later case
589 * the "source crop" is rounded to texel boundaries.
590 * This can produce significantly different results when the texture
591 * is scaled by a large amount.
592 *
593 * The GL code below is more logical (imho), and the difference with
594 * HWC is due to a limitation of the HWC API to integers -- a question
595 * is suspend is wether we should ignore this problem or revert to
596 * GL composition when a buffer scaling is applied (maybe with some
597 * minimal value)? Or, we could make GL behave like HWC -- but this feel
598 * like more of a hack.
599 */
600 const Rect win(computeBounds());
601
602 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
603 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
604 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
605 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
606
607 TexCoords texCoords[4];
608 texCoords[0].u = left;
609 texCoords[0].v = top;
610 texCoords[1].u = left;
611 texCoords[1].v = bottom;
612 texCoords[2].u = right;
613 texCoords[2].v = bottom;
614 texCoords[3].u = right;
615 texCoords[3].v = top;
616 for (int i = 0; i < 4; i++) {
617 texCoords[i].v = 1.0f - texCoords[i].v;
618 }
619
620 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
621 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
622 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
623 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
624
625 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
626 glDisable(GL_BLEND);
627}
628
629void Layer::setFiltering(bool filtering) {
630 mFiltering = filtering;
631}
632
633bool Layer::getFiltering() const {
634 return mFiltering;
635}
636
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800637// As documented in libhardware header, formats in the range
638// 0x100 - 0x1FF are specific to the HAL implementation, and
639// are known to have no alpha channel
640// TODO: move definition for device-specific range into
641// hardware.h, instead of using hard-coded values here.
642#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
643
Mathias Agopiana67932f2011-04-20 14:20:59 -0700644bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800645{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700646 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
647 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800648 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700649 PixelFormatInfo info;
650 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
651 // in case of error (unknown format), we assume no blending
652 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800653}
654
Mathias Agopian13127d82013-03-05 17:47:11 -0800655// ----------------------------------------------------------------------------
656// local state
657// ----------------------------------------------------------------------------
658
659void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
660{
661 const Layer::State& s(drawingState());
662 const Transform tr(hw->getTransform() * s.transform);
663 const uint32_t hw_h = hw->getHeight();
664 Rect win(s.active.w, s.active.h);
665 if (!s.active.crop.isEmpty()) {
666 win.intersect(s.active.crop, &win);
667 }
668 if (mesh) {
669 tr.transform(mesh->mVertices[0], win.left, win.top);
670 tr.transform(mesh->mVertices[1], win.left, win.bottom);
671 tr.transform(mesh->mVertices[2], win.right, win.bottom);
672 tr.transform(mesh->mVertices[3], win.right, win.top);
673 for (size_t i=0 ; i<4 ; i++) {
674 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
675 }
676 }
677}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800678
Mathias Agopiana67932f2011-04-20 14:20:59 -0700679bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700680{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700681 // if we don't have a buffer yet, we're translucent regardless of the
682 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700683 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700684 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700685 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700686
687 // if the layer has the opaque flag, then we're always opaque,
688 // otherwise we use the current buffer's format.
689 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700690}
691
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800692bool Layer::isProtected() const
693{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700694 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800695 return (activeBuffer != 0) &&
696 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
697}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700698
Mathias Agopian13127d82013-03-05 17:47:11 -0800699bool Layer::isFixedSize() const {
700 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
701}
702
703bool Layer::isCropped() const {
704 return !mCurrentCrop.isEmpty();
705}
706
707bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
708 return mNeedsFiltering || hw->needsFiltering();
709}
710
711void Layer::setVisibleRegion(const Region& visibleRegion) {
712 // always called from main thread
713 this->visibleRegion = visibleRegion;
714}
715
716void Layer::setCoveredRegion(const Region& coveredRegion) {
717 // always called from main thread
718 this->coveredRegion = coveredRegion;
719}
720
721void Layer::setVisibleNonTransparentRegion(const Region&
722 setVisibleNonTransparentRegion) {
723 // always called from main thread
724 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
725}
726
727// ----------------------------------------------------------------------------
728// transaction
729// ----------------------------------------------------------------------------
730
731uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800732 ATRACE_CALL();
733
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800734 const Layer::State& front(drawingState());
735 const Layer::State& temp(currentState());
736
Mathias Agopian4824d402012-06-04 18:16:30 -0700737 const bool sizeChanged = (temp.requested.w != front.requested.w) ||
738 (temp.requested.h != front.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700739
740 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700741 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000742 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700743 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700744 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
745 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
746 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
747 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -0700748 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
Mathias Agopian419e1962012-05-23 14:34:07 -0700749 temp.active.w, temp.active.h,
750 temp.active.crop.left,
751 temp.active.crop.top,
752 temp.active.crop.right,
753 temp.active.crop.bottom,
754 temp.active.crop.getWidth(),
755 temp.active.crop.getHeight(),
756 temp.requested.w, temp.requested.h,
Mathias Agopianb30c4152012-05-16 18:21:32 -0700757 temp.requested.crop.left,
758 temp.requested.crop.top,
759 temp.requested.crop.right,
760 temp.requested.crop.bottom,
761 temp.requested.crop.getWidth(),
762 temp.requested.crop.getHeight(),
Mathias Agopian419e1962012-05-23 14:34:07 -0700763 front.active.w, front.active.h,
764 front.active.crop.left,
765 front.active.crop.top,
766 front.active.crop.right,
767 front.active.crop.bottom,
768 front.active.crop.getWidth(),
769 front.active.crop.getHeight(),
770 front.requested.w, front.requested.h,
Mathias Agopianb30c4152012-05-16 18:21:32 -0700771 front.requested.crop.left,
772 front.requested.crop.top,
773 front.requested.crop.right,
774 front.requested.crop.bottom,
775 front.requested.crop.getWidth(),
Mathias Agopian419e1962012-05-23 14:34:07 -0700776 front.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800777
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700778 // record the new size, form this point on, when the client request
779 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800780 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopianb30c4152012-05-16 18:21:32 -0700781 temp.requested.w, temp.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800782 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700783
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700784 if (!isFixedSize()) {
785
786 const bool resizePending = (temp.requested.w != temp.active.w) ||
787 (temp.requested.h != temp.active.h);
788
789 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800790 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700791 // if we have a pending resize, unless we are in fixed-size mode.
792 // the drawing state will be updated only once we receive a buffer
793 // with the correct size.
794 //
795 // in particular, we want to make sure the clip (which is part
796 // of the geometry state) is latched together with the size but is
797 // latched immediately when no resizing is involved.
798
799 flags |= eDontUpdateGeometryState;
800 }
801 }
802
Mathias Agopian13127d82013-03-05 17:47:11 -0800803 // always set active to requested, unless we're asked not to
804 // this is used by Layer, which special cases resizes.
805 if (flags & eDontUpdateGeometryState) {
806 } else {
807 Layer::State& editTemp(currentState());
808 editTemp.active = temp.requested;
809 }
810
811 if (front.active != temp.active) {
812 // invalidate and recompute the visible regions if needed
813 flags |= Layer::eVisibleRegion;
814 }
815
816 if (temp.sequence != front.sequence) {
817 // invalidate and recompute the visible regions if needed
818 flags |= eVisibleRegion;
819 this->contentDirty = true;
820
821 // we may use linear filtering, if the matrix scales us
822 const uint8_t type = temp.transform.getType();
823 mNeedsFiltering = (!temp.transform.preserveRects() ||
824 (type >= Transform::SCALE));
825 }
826
827 // Commit the transaction
828 commitTransaction();
829 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800830}
831
Mathias Agopian13127d82013-03-05 17:47:11 -0800832void Layer::commitTransaction() {
833 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700834}
835
Mathias Agopian13127d82013-03-05 17:47:11 -0800836uint32_t Layer::getTransactionFlags(uint32_t flags) {
837 return android_atomic_and(~flags, &mTransactionFlags) & flags;
838}
839
840uint32_t Layer::setTransactionFlags(uint32_t flags) {
841 return android_atomic_or(flags, &mTransactionFlags);
842}
843
844bool Layer::setPosition(float x, float y) {
845 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
846 return false;
847 mCurrentState.sequence++;
848 mCurrentState.transform.set(x, y);
849 setTransactionFlags(eTransactionNeeded);
850 return true;
851}
852bool Layer::setLayer(uint32_t z) {
853 if (mCurrentState.z == z)
854 return false;
855 mCurrentState.sequence++;
856 mCurrentState.z = z;
857 setTransactionFlags(eTransactionNeeded);
858 return true;
859}
860bool Layer::setSize(uint32_t w, uint32_t h) {
861 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
862 return false;
863 mCurrentState.requested.w = w;
864 mCurrentState.requested.h = h;
865 setTransactionFlags(eTransactionNeeded);
866 return true;
867}
868bool Layer::setAlpha(uint8_t alpha) {
869 if (mCurrentState.alpha == alpha)
870 return false;
871 mCurrentState.sequence++;
872 mCurrentState.alpha = alpha;
873 setTransactionFlags(eTransactionNeeded);
874 return true;
875}
876bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
877 mCurrentState.sequence++;
878 mCurrentState.transform.set(
879 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
880 setTransactionFlags(eTransactionNeeded);
881 return true;
882}
883bool Layer::setTransparentRegionHint(const Region& transparent) {
Mathias Agopian2ca79392013-04-02 18:30:32 -0700884 mCurrentState.requestedTransparentRegion = transparent;
Mathias Agopian13127d82013-03-05 17:47:11 -0800885 setTransactionFlags(eTransactionNeeded);
886 return true;
887}
888bool Layer::setFlags(uint8_t flags, uint8_t mask) {
889 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
890 if (mCurrentState.flags == newFlags)
891 return false;
892 mCurrentState.sequence++;
893 mCurrentState.flags = newFlags;
894 setTransactionFlags(eTransactionNeeded);
895 return true;
896}
897bool Layer::setCrop(const Rect& crop) {
898 if (mCurrentState.requested.crop == crop)
899 return false;
900 mCurrentState.sequence++;
901 mCurrentState.requested.crop = crop;
902 setTransactionFlags(eTransactionNeeded);
903 return true;
904}
905
906bool Layer::setLayerStack(uint32_t layerStack) {
907 if (mCurrentState.layerStack == layerStack)
908 return false;
909 mCurrentState.sequence++;
910 mCurrentState.layerStack = layerStack;
911 setTransactionFlags(eTransactionNeeded);
912 return true;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700913}
914
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800915// ----------------------------------------------------------------------------
916// pageflip handling...
917// ----------------------------------------------------------------------------
918
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800919bool Layer::onPreComposition() {
920 mRefreshPending = false;
921 return mQueuedFrames > 0;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800922}
923
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700924void Layer::onPostComposition() {
925 if (mFrameLatencyNeeded) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800926 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800927 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
928
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800929 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis789a6c32013-02-25 13:37:54 -0800930 if (frameReadyFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800931 mFrameTracker.setFrameReadyFence(frameReadyFence);
932 } else {
933 // There was no fence for this frame, so assume that it was ready
934 // to be presented at the desired present time.
935 mFrameTracker.setFrameReadyTime(desiredPresentTime);
936 }
937
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700938 const HWComposer& hwc = mFlinger->getHwComposer();
Jamie Gennis82dbc742012-11-08 19:23:28 -0800939 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
Jamie Gennis789a6c32013-02-25 13:37:54 -0800940 if (presentFence->isValid()) {
Jamie Gennis82dbc742012-11-08 19:23:28 -0800941 mFrameTracker.setActualPresentFence(presentFence);
942 } else {
943 // The HWC doesn't support present fences, so use the refresh
944 // timestamp instead.
945 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
946 mFrameTracker.setActualPresentTime(presentTime);
947 }
948
949 mFrameTracker.advanceFrame();
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700950 mFrameLatencyNeeded = false;
951 }
952}
953
Mathias Agopianda27af92012-09-13 18:17:13 -0700954bool Layer::isVisible() const {
Mathias Agopian13127d82013-03-05 17:47:11 -0800955 const Layer::State& s(mDrawingState);
956 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
957 && (mActiveBuffer != NULL);
Mathias Agopianda27af92012-09-13 18:17:13 -0700958}
959
Mathias Agopian4fec8732012-06-29 14:12:52 -0700960Region Layer::latchBuffer(bool& recomputeVisibleRegions)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800961{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800962 ATRACE_CALL();
963
Mathias Agopian4fec8732012-06-29 14:12:52 -0700964 Region outDirtyRegion;
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700965 if (mQueuedFrames > 0) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800966
967 // if we've already called updateTexImage() without going through
968 // a composition step, we have to skip this layer at this point
969 // because we cannot call updateTeximage() without a corresponding
970 // compositionComplete() call.
971 // we'll trigger an update in onPreComposition().
Mathias Agopian4d143ee2012-02-23 20:05:39 -0800972 if (mRefreshPending) {
Mathias Agopian4fec8732012-06-29 14:12:52 -0700973 return outDirtyRegion;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800974 }
975
Jamie Gennis351a5132011-09-14 18:23:37 -0700976 // Capture the old state of the layer for comparisons later
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700977 const bool oldOpacity = isOpaque();
Jamie Gennis351a5132011-09-14 18:23:37 -0700978 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700979
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700980 // signal another event if we have more frames pending
981 if (android_atomic_dec(&mQueuedFrames) > 1) {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800982 mFlinger->signalLayerUpdate();
Jamie Gennis3d8063b2011-06-26 18:27:47 -0700983 }
984
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800985 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
Mathias Agopian2c8207e2012-05-23 17:56:42 -0700986 Layer::State& front;
987 Layer::State& current;
988 bool& recomputeVisibleRegions;
989 Reject(Layer::State& front, Layer::State& current,
990 bool& recomputeVisibleRegions)
991 : front(front), current(current),
992 recomputeVisibleRegions(recomputeVisibleRegions) {
993 }
994
995 virtual bool reject(const sp<GraphicBuffer>& buf,
996 const BufferQueue::BufferItem& item) {
997 if (buf == NULL) {
998 return false;
999 }
1000
1001 uint32_t bufWidth = buf->getWidth();
1002 uint32_t bufHeight = buf->getHeight();
1003
1004 // check that we received a buffer of the right size
1005 // (Take the buffer's orientation into account)
1006 if (item.mTransform & Transform::ROT_90) {
1007 swap(bufWidth, bufHeight);
1008 }
1009
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001010 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1011 if (front.active != front.requested) {
1012
1013 if (isFixedSize ||
1014 (bufWidth == front.requested.w &&
1015 bufHeight == front.requested.h))
1016 {
1017 // Here we pretend the transaction happened by updating the
1018 // current and drawing states. Drawing state is only accessed
1019 // in this thread, no need to have it locked
1020 front.active = front.requested;
1021
1022 // We also need to update the current state so that
1023 // we don't end-up overwriting the drawing state with
1024 // this stale current state during the next transaction
1025 //
1026 // NOTE: We don't need to hold the transaction lock here
1027 // because State::active is only accessed from this thread.
1028 current.active = front.active;
1029
1030 // recompute visible region
1031 recomputeVisibleRegions = true;
1032 }
1033
1034 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -07001035 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001036 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1037 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
Andy McFadden69052052012-09-14 16:10:11 -07001038 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001039 front.active.w, front.active.h,
1040 front.active.crop.left,
1041 front.active.crop.top,
1042 front.active.crop.right,
1043 front.active.crop.bottom,
1044 front.active.crop.getWidth(),
1045 front.active.crop.getHeight(),
1046 front.requested.w, front.requested.h,
1047 front.requested.crop.left,
1048 front.requested.crop.top,
1049 front.requested.crop.right,
1050 front.requested.crop.bottom,
1051 front.requested.crop.getWidth(),
1052 front.requested.crop.getHeight());
1053 }
1054
1055 if (!isFixedSize) {
1056 if (front.active.w != bufWidth ||
1057 front.active.h != bufHeight) {
Mathias Agopian4824d402012-06-04 18:16:30 -07001058 // reject this buffer
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001059 return true;
1060 }
1061 }
Mathias Agopian2ca79392013-04-02 18:30:32 -07001062
1063 // if the transparent region has changed (this test is
1064 // conservative, but that's fine, worst case we're doing
1065 // a bit of extra work), we latch the new one and we
1066 // trigger a visible-region recompute.
1067 if (!front.activeTransparentRegion.isTriviallyEqual(
1068 front.requestedTransparentRegion)) {
1069 front.activeTransparentRegion = front.requestedTransparentRegion;
Mathias Agopian6c67f0f2013-04-12 16:58:11 -07001070
1071 // We also need to update the current state so that
1072 // we don't end-up overwriting the drawing state with
1073 // this stale current state during the next transaction
1074 //
1075 // NOTE: We don't need to hold the transaction lock here
1076 // because State::active is only accessed from this thread.
1077 current.activeTransparentRegion = front.activeTransparentRegion;
1078
1079 // recompute visible region
Mathias Agopian2ca79392013-04-02 18:30:32 -07001080 recomputeVisibleRegions = true;
1081 }
1082
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001083 return false;
1084 }
1085 };
1086
1087
1088 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
1089
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001090 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001091 // something happened!
1092 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001093 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001094 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001095
Jamie Gennis351a5132011-09-14 18:23:37 -07001096 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001097 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001098 if (mActiveBuffer == NULL) {
1099 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001100 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001101 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001102
Mathias Agopian4824d402012-06-04 18:16:30 -07001103 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001104 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001105 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001106 // the first time we receive a buffer, we need to trigger a
1107 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001108 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001109 }
1110
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001111 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1112 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1113 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001114 if ((crop != mCurrentCrop) ||
1115 (transform != mCurrentTransform) ||
1116 (scalingMode != mCurrentScalingMode))
1117 {
1118 mCurrentCrop = crop;
1119 mCurrentTransform = transform;
1120 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001121 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001122 }
1123
1124 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001125 uint32_t bufWidth = mActiveBuffer->getWidth();
1126 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001127 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1128 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001129 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001130 }
1131 }
1132
1133 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1134 if (oldOpacity != isOpaque()) {
1135 recomputeVisibleRegions = true;
1136 }
1137
Mathias Agopian702634a2012-05-23 17:50:31 -07001138 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1139 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Mathias Agopian4fec8732012-06-29 14:12:52 -07001140
1141 // FIXME: postedRegion should be dirty & bounds
1142 const Layer::State& front(drawingState());
1143 Region dirtyRegion(Rect(front.active.w, front.active.h));
1144
1145 // transform the dirty region to window-manager space
1146 outDirtyRegion = (front.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001147 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001148 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001149}
1150
Mathias Agopiana67932f2011-04-20 14:20:59 -07001151uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001152{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001153 // TODO: should we do something special if mSecure is set?
1154 if (mProtectedByApp) {
1155 // need a hardware-protected path to external video sink
1156 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001157 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001158 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001159 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001160}
1161
Mathias Agopian84300952012-11-21 16:02:13 -08001162void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001163 uint32_t orientation = 0;
1164 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001165 // The transform hint is used to improve performance, but we can
1166 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001167 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001168 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001169 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001170 if (orientation & Transform::ROT_INVALID) {
1171 orientation = 0;
1172 }
1173 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001174 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001175}
1176
Mathias Agopian13127d82013-03-05 17:47:11 -08001177// ----------------------------------------------------------------------------
1178// debugging
1179// ----------------------------------------------------------------------------
1180
1181void Layer::dump(String8& result, char* buffer, size_t SIZE) const
1182{
1183 const Layer::State& s(drawingState());
1184
1185 snprintf(buffer, SIZE,
1186 "+ %s %p (%s)\n",
1187 getTypeId(), this, getName().string());
1188 result.append(buffer);
1189
Mathias Agopian2ca79392013-04-02 18:30:32 -07001190 s.activeTransparentRegion.dump(result, "transparentRegion");
Mathias Agopian13127d82013-03-05 17:47:11 -08001191 visibleRegion.dump(result, "visibleRegion");
1192 sp<Client> client(mClientRef.promote());
1193
1194 snprintf(buffer, SIZE,
1195 " "
1196 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1197 "isOpaque=%1d, invalidate=%1d, "
1198 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1199 " client=%p\n",
1200 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1201 s.active.crop.left, s.active.crop.top,
1202 s.active.crop.right, s.active.crop.bottom,
1203 isOpaque(), contentDirty,
1204 s.alpha, s.flags,
1205 s.transform[0][0], s.transform[0][1],
1206 s.transform[1][0], s.transform[1][1],
1207 client.get());
1208 result.append(buffer);
1209
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 }
1218 snprintf(buffer, SIZE,
1219 " "
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
1225 result.append(buffer);
1226
1227 if (mSurfaceFlingerConsumer != 0) {
1228 mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE);
1229 }
1230}
1231
1232
1233void Layer::shortDump(String8& result, char* scratch, size_t size) const {
1234 Layer::dump(result, scratch, size);
1235}
1236
1237void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const {
1238 mFrameTracker.dump(result);
1239}
1240
1241void Layer::clearStats() {
1242 mFrameTracker.clear();
1243}
1244
1245// ---------------------------------------------------------------------------
1246
1247Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1248 const sp<Layer>& layer)
1249 : mFlinger(flinger), mLayer(layer) {
1250}
1251
1252Layer::LayerCleaner::~LayerCleaner() {
1253 // destroy client resources
1254 mFlinger->onLayerDestroyed(mLayer);
1255}
1256
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001257// ---------------------------------------------------------------------------
1258
1259
1260}; // namespace android