blob: 5996c907d1841593bbeffece1191e798825dbc00 [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
Daniel Lamb2675792012-02-23 14:35:13 -0800111 sp<BufferQueue> bq = new SurfaceTextureLayer();
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();
147 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
148 }
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 Agopiand606de62010-05-10 20:06:11 -0700156// called with SurfaceFlinger::mStateLock as soon as the layer is entered
157// in the purgatory list
Mathias Agopian13127d82013-03-05 17:47:11 -0800158void Layer::onRemoved() {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800159 mSurfaceFlingerConsumer->abandon();
Mathias Agopian48d819a2009-09-10 19:41:18 -0700160}
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700161
Mathias Agopian13127d82013-03-05 17:47:11 -0800162// ---------------------------------------------------------------------------
163// set-up
164// ---------------------------------------------------------------------------
165
Mathias Agopian13127d82013-03-05 17:47:11 -0800166String8 Layer::getName() const {
167 return mName;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800168}
169
Mathias Agopianf9d93272009-06-19 17:00:27 -0700170status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800171 PixelFormat format, uint32_t flags)
172{
Mathias Agopian401c2572009-09-23 19:16:27 -0700173 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800174 PixelFormatInfo info;
175 status_t err = getPixelFormatInfo(format, &info);
Mathias Agopianff615cc2012-02-24 14:58:36 -0800176 if (err) {
177 ALOGE("unsupported pixelformat %d", format);
178 return err;
179 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800180
Mathias Agopianca99fb82010-04-14 16:43:44 -0700181 uint32_t const maxSurfaceDims = min(
Mathias Agopiana4912602012-07-12 14:25:33 -0700182 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
Mathias Agopianca99fb82010-04-14 16:43:44 -0700183
184 // never allow a surface larger than what our underlying GL implementation
185 // can handle.
186 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
Mathias Agopianff615cc2012-02-24 14:58:36 -0800187 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700188 return BAD_VALUE;
189 }
190
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700191 mFormat = format;
Mathias Agopianeff062c2010-08-25 14:59:15 -0700192
Mathias Agopian3165cc22012-08-08 19:42:09 -0700193 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
194 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
195 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700196 mCurrentOpacity = getOpacityForFormat(format);
197
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800198 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
199 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
200 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
Mathias Agopianca99fb82010-04-14 16:43:44 -0700201
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800202 return NO_ERROR;
203}
204
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700205sp<IBinder> Layer::getHandle() {
Mathias Agopian13127d82013-03-05 17:47:11 -0800206 Mutex::Autolock _l(mLock);
207
208 LOG_ALWAYS_FATAL_IF(mHasSurface,
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700209 "Layer::getHandle() has already been called");
Mathias Agopian13127d82013-03-05 17:47:11 -0800210
211 mHasSurface = true;
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700212
213 /*
214 * The layer handle is just a BBinder object passed to the client
215 * (remote process) -- we don't keep any reference on our side such that
216 * the dtor is called when the remote side let go of its reference.
217 *
218 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
219 * this layer when the handle is destroyed.
220 */
221
222 class Handle : public BBinder, public LayerCleaner {
223 wp<const Layer> mOwner;
224 public:
225 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
226 : LayerCleaner(flinger, layer), mOwner(layer) {
227 }
228 };
229
230 return new Handle(mFlinger, this);
Mathias Agopian13127d82013-03-05 17:47:11 -0800231}
232
Mathias Agopian4d9b8222013-03-12 17:11:48 -0700233sp<BufferQueue> Layer::getBufferQueue() const {
234 return mSurfaceFlingerConsumer->getBufferQueue();
235}
236
237//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
238// sp<IGraphicBufferProducer> res;
239// sp<const Layer> that( mOwner.promote() );
240// if (that != NULL) {
241// res = that->mSurfaceFlingerConsumer->getBufferQueue();
242// }
243// return res;
244//}
245
Mathias Agopian13127d82013-03-05 17:47:11 -0800246// ---------------------------------------------------------------------------
247// h/w composer set-up
248// ---------------------------------------------------------------------------
249
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800250Rect Layer::getContentCrop() const {
251 // this is the crop rectangle that applies to the buffer
252 // itself (as opposed to the window)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700253 Rect crop;
254 if (!mCurrentCrop.isEmpty()) {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800255 // if the buffer crop is defined, we use that
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700256 crop = mCurrentCrop;
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800257 } else if (mActiveBuffer != NULL) {
258 // otherwise we use the whole buffer
259 crop = mActiveBuffer->getBounds();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700260 } else {
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800261 // if we don't have a buffer yet, we use an empty/invalid crop
Mathias Agopian4fec8732012-06-29 14:12:52 -0700262 crop.makeInvalid();
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700263 }
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700264 return crop;
265}
266
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800267uint32_t Layer::getContentTransform() const {
268 return mCurrentTransform;
269}
270
Mathias Agopian13127d82013-03-05 17:47:11 -0800271Rect Layer::computeBounds() const {
272 const Layer::State& s(drawingState());
273 Rect win(s.active.w, s.active.h);
274 if (!s.active.crop.isEmpty()) {
275 win.intersect(s.active.crop, &win);
276 }
277 return win;
278}
279
280Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
281 /*
282 * The way we compute the crop (aka. texture coordinates when we have a
283 * Layer) produces a different output from the GL code in
284 * drawWithOpenGL() due to HWC being limited to integers. The difference
285 * can be large if getContentTransform() contains a large scale factor.
286 * See comments in drawWithOpenGL() for more details.
287 */
288
289 // the content crop is the area of the content that gets scaled to the
290 // layer's size.
291 Rect crop(getContentCrop());
292
293 // the active.crop is the area of the window that gets cropped, but not
294 // scaled in any ways.
295 const State& s(drawingState());
296
297 // apply the projection's clipping to the window crop in
298 // layerstack space, and convert-back to layer space.
299 // if there are no window scaling (or content scaling) involved,
300 // this operation will map to full pixels in the buffer.
301 // NOTE: should we revert to GL composition if a scaling is involved
302 // since it cannot be represented in the HWC API?
303 Rect activeCrop(s.transform.transform(s.active.crop));
304 activeCrop.intersect(hw->getViewport(), &activeCrop);
305 activeCrop = s.transform.inverse().transform(activeCrop);
306
307 // paranoia: make sure the window-crop is constrained in the
308 // window's bounds
309 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
310
311 if (!activeCrop.isEmpty()) {
312 // Transform the window crop to match the buffer coordinate system,
313 // which means using the inverse of the current transform set on the
314 // SurfaceFlingerConsumer.
315 uint32_t invTransform = getContentTransform();
316 int winWidth = s.active.w;
317 int winHeight = s.active.h;
318 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
319 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
320 NATIVE_WINDOW_TRANSFORM_FLIP_H;
321 winWidth = s.active.h;
322 winHeight = s.active.w;
323 }
324 const Rect winCrop = activeCrop.transform(
325 invTransform, s.active.w, s.active.h);
326
327 // the code below essentially performs a scaled intersection
328 // of crop and winCrop
329 float xScale = float(crop.width()) / float(winWidth);
330 float yScale = float(crop.height()) / float(winHeight);
331
332 int insetL = int(ceilf( winCrop.left * xScale));
333 int insetT = int(ceilf( winCrop.top * yScale));
334 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
335 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
336
337 crop.left += insetL;
338 crop.top += insetT;
339 crop.right -= insetR;
340 crop.bottom -= insetB;
341 }
342 return crop;
343}
344
Mathias Agopian4fec8732012-06-29 14:12:52 -0700345void Layer::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700346 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700347 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana350ff92010-08-10 17:14:02 -0700348{
Mathias Agopian13127d82013-03-05 17:47:11 -0800349 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700350
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700351 // enable this layer
352 layer.setSkip(false);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700353
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700354 if (isSecure() && !hw->isSecure()) {
355 layer.setSkip(true);
356 }
357
Mathias Agopian13127d82013-03-05 17:47:11 -0800358 // this gives us only the "orientation" component of the transform
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800359 const State& s(drawingState());
Mathias Agopian13127d82013-03-05 17:47:11 -0800360 if (!isOpaque() || s.alpha != 0xFF) {
361 layer.setBlending(mPremultipliedAlpha ?
362 HWC_BLENDING_PREMULT :
363 HWC_BLENDING_COVERAGE);
364 }
365
366 // apply the layer's transform, followed by the display's global transform
367 // here we're guaranteed that the layer's transform preserves rects
368 Rect frame(s.transform.transform(computeBounds()));
369 frame.intersect(hw->getViewport(), &frame);
370 const Transform& tr(hw->getTransform());
371 layer.setFrame(tr.transform(frame));
372 layer.setCrop(computeCrop(hw));
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800373 layer.setPlaneAlpha(s.alpha);
374
Mathias Agopian29a367b2011-07-12 14:51:45 -0700375 /*
376 * Transformations are applied in this order:
377 * 1) buffer orientation/flip/mirror
378 * 2) state transformation (window manager)
379 * 3) layer orientation (screen orientation)
380 * (NOTE: the matrices are multiplied in reverse order)
381 */
382
383 const Transform bufferOrientation(mCurrentTransform);
Mathias Agopian13127d82013-03-05 17:47:11 -0800384 const Transform transform(tr * s.transform * bufferOrientation);
Mathias Agopian29a367b2011-07-12 14:51:45 -0700385
386 // this gives us only the "orientation" component of the transform
Mathias Agopian13127d82013-03-05 17:47:11 -0800387 const uint32_t orientation = transform.getOrientation();
388 if (orientation & Transform::ROT_INVALID) {
389 // we can only handle simple transformation
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700390 layer.setSkip(true);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700391 } else {
Mathias Agopian13127d82013-03-05 17:47:11 -0800392 layer.setTransform(orientation);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700393 }
Mathias Agopiana350ff92010-08-10 17:14:02 -0700394}
395
Mathias Agopian42977342012-08-05 00:40:46 -0700396void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700397 HWComposer::HWCLayerInterface& layer) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800398 // we have to set the visible region on every frame because
399 // we currently free it during onLayerDisplayed(), which is called
400 // after HWComposer::commit() -- every frame.
401 // Apply this display's projection's viewport to the visible region
402 // before giving it to the HWC HAL.
403 const Transform& tr = hw->getTransform();
404 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
405 layer.setVisibleRegionScreen(visible);
406
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700407 // NOTE: buffer can be NULL if the client never drew into this
408 // layer yet, or if we ran out of memory
Mathias Agopian71e83e12012-09-04 20:25:39 -0700409 layer.setBuffer(mActiveBuffer);
Jesse Hallc5c5a142012-07-02 16:49:28 -0700410}
Jesse Halldc5b4852012-06-29 15:21:18 -0700411
Mathias Agopian42977342012-08-05 00:40:46 -0700412void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700413 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700414 int fenceFd = -1;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700415
416 // TODO: there is a possible optimization here: we only need to set the
417 // acquire fence the first time a new buffer is acquired on EACH display.
418
419 if (layer.getCompositionType() == HWC_OVERLAY) {
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800420 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800421 if (fence->isValid()) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700422 fenceFd = fence->dup();
Jesse Halldc5b4852012-06-29 15:21:18 -0700423 if (fenceFd == -1) {
424 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
425 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700426 }
Jesse Halldc5b4852012-06-29 15:21:18 -0700427 }
Jesse Hallc5c5a142012-07-02 16:49:28 -0700428 layer.setAcquireFenceFd(fenceFd);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700429}
430
Mathias Agopian13127d82013-03-05 17:47:11 -0800431// ---------------------------------------------------------------------------
432// drawing...
433// ---------------------------------------------------------------------------
434
435void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
436 onDraw(hw, clip);
437}
438
439void Layer::draw(const sp<const DisplayDevice>& hw) {
440 onDraw( hw, Region(hw->bounds()) );
441}
442
Mathias Agopian42977342012-08-05 00:40:46 -0700443void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800444{
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800445 ATRACE_CALL();
446
Mathias Agopiana67932f2011-04-20 14:20:59 -0700447 if (CC_UNLIKELY(mActiveBuffer == 0)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800448 // the texture has not been created yet, this Layer has
Mathias Agopian179169e2010-05-06 20:21:45 -0700449 // in fact never been drawn into. This happens frequently with
450 // SurfaceView because the WindowManager can't know when the client
451 // has drawn the first time.
452
453 // If there is nothing under us, we paint the screen in black, otherwise
454 // we just skip this update.
455
456 // figure out if there is something below us
457 Region under;
Mathias Agopianf7ae69d2011-08-23 12:34:29 -0700458 const SurfaceFlinger::LayerVector& drawingLayers(
459 mFlinger->mDrawingState.layersSortedByZ);
Mathias Agopian179169e2010-05-06 20:21:45 -0700460 const size_t count = drawingLayers.size();
461 for (size_t i=0 ; i<count ; ++i) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800462 const sp<Layer>& layer(drawingLayers[i]);
463 if (layer.get() == static_cast<Layer const*>(this))
Mathias Agopian179169e2010-05-06 20:21:45 -0700464 break;
Mathias Agopian42977342012-08-05 00:40:46 -0700465 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
Mathias Agopian179169e2010-05-06 20:21:45 -0700466 }
467 // if not everything below us is covered, we plug the holes!
468 Region holes(clip.subtract(under));
469 if (!holes.isEmpty()) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700470 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
Mathias Agopian179169e2010-05-06 20:21:45 -0700471 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800472 return;
473 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700474
Andy McFadden97eba892012-12-11 15:21:45 -0800475 // Bind the current buffer to the GL texture, and wait for it to be
476 // ready for us to draw into.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800477 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
478 if (err != NO_ERROR) {
Andy McFadden97eba892012-12-11 15:21:45 -0800479 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
Jesse Halldc5b4852012-06-29 15:21:18 -0700480 // Go ahead and draw the buffer anyway; no matter what we do the screen
481 // is probably going to have something visibly wrong.
482 }
483
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700484 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
485
486 if (!blackOutLayer) {
Jamie Genniscbb1a952012-05-08 17:05:52 -0700487 // TODO: we could be more subtle with isFixedSize()
Mathias Agopianeba8c682012-09-19 23:14:45 -0700488 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
Jamie Genniscbb1a952012-05-08 17:05:52 -0700489
490 // Query the texture matrix given our current filtering mode.
491 float textureMatrix[16];
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800492 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
493 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700494
495 // Set things up for texturing.
Mathias Agopianc492e672011-10-18 14:49:27 -0700496 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
497 GLenum filter = GL_NEAREST;
Jamie Genniscbb1a952012-05-08 17:05:52 -0700498 if (useFiltering) {
Mathias Agopianc492e672011-10-18 14:49:27 -0700499 filter = GL_LINEAR;
Jamie Gennis9575f602011-10-07 14:51:16 -0700500 }
Mathias Agopianc492e672011-10-18 14:49:27 -0700501 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
502 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
Jamie Gennis9575f602011-10-07 14:51:16 -0700503 glMatrixMode(GL_TEXTURE);
Jamie Genniscbb1a952012-05-08 17:05:52 -0700504 glLoadMatrixf(textureMatrix);
Jamie Gennis9575f602011-10-07 14:51:16 -0700505 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700506 glDisable(GL_TEXTURE_2D);
Xavier Ducrohet4c4163b2011-10-21 16:18:48 -0700507 glEnable(GL_TEXTURE_EXTERNAL_OES);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700508 } else {
Mathias Agopianc492e672011-10-18 14:49:27 -0700509 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
Jamie Gennis9575f602011-10-07 14:51:16 -0700510 glMatrixMode(GL_TEXTURE);
511 glLoadIdentity();
512 glMatrixMode(GL_MODELVIEW);
Mathias Agopianc492e672011-10-18 14:49:27 -0700513 glDisable(GL_TEXTURE_EXTERNAL_OES);
514 glEnable(GL_TEXTURE_2D);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700515 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700516
Mathias Agopian1b031492012-06-20 17:51:20 -0700517 drawWithOpenGL(hw, clip);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700518
Mathias Agopianc492e672011-10-18 14:49:27 -0700519 glDisable(GL_TEXTURE_EXTERNAL_OES);
520 glDisable(GL_TEXTURE_2D);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800521}
522
Mathias Agopian13127d82013-03-05 17:47:11 -0800523
524void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
525 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
526{
527 const uint32_t fbHeight = hw->getHeight();
528 glColor4f(red,green,blue,alpha);
529
530 glDisable(GL_TEXTURE_EXTERNAL_OES);
531 glDisable(GL_TEXTURE_2D);
532 glDisable(GL_BLEND);
533
534 LayerMesh mesh;
535 computeGeometry(hw, &mesh);
536
537 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
538 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
539}
540
541void Layer::clearWithOpenGL(
542 const sp<const DisplayDevice>& hw, const Region& clip) const {
543 clearWithOpenGL(hw, clip, 0,0,0,0);
544}
545
546void Layer::drawWithOpenGL(
547 const sp<const DisplayDevice>& hw, const Region& clip) const {
548 const uint32_t fbHeight = hw->getHeight();
549 const State& s(drawingState());
550
551 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
552 if (CC_UNLIKELY(s.alpha < 0xFF)) {
553 const GLfloat alpha = s.alpha * (1.0f/255.0f);
554 if (mPremultipliedAlpha) {
555 glColor4f(alpha, alpha, alpha, alpha);
556 } else {
557 glColor4f(1, 1, 1, alpha);
558 }
559 glEnable(GL_BLEND);
560 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
561 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
562 } else {
563 glColor4f(1, 1, 1, 1);
564 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
565 if (!isOpaque()) {
566 glEnable(GL_BLEND);
567 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
568 } else {
569 glDisable(GL_BLEND);
570 }
571 }
572
573 LayerMesh mesh;
574 computeGeometry(hw, &mesh);
575
576 // TODO: we probably want to generate the texture coords with the mesh
577 // here we assume that we only have 4 vertices
578
579 struct TexCoords {
580 GLfloat u;
581 GLfloat v;
582 };
583
584
585 /*
586 * NOTE: the way we compute the texture coordinates here produces
587 * different results than when we take the HWC path -- in the later case
588 * the "source crop" is rounded to texel boundaries.
589 * This can produce significantly different results when the texture
590 * is scaled by a large amount.
591 *
592 * The GL code below is more logical (imho), and the difference with
593 * HWC is due to a limitation of the HWC API to integers -- a question
594 * is suspend is wether we should ignore this problem or revert to
595 * GL composition when a buffer scaling is applied (maybe with some
596 * minimal value)? Or, we could make GL behave like HWC -- but this feel
597 * like more of a hack.
598 */
599 const Rect win(computeBounds());
600
601 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
602 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
603 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
604 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
605
606 TexCoords texCoords[4];
607 texCoords[0].u = left;
608 texCoords[0].v = top;
609 texCoords[1].u = left;
610 texCoords[1].v = bottom;
611 texCoords[2].u = right;
612 texCoords[2].v = bottom;
613 texCoords[3].u = right;
614 texCoords[3].v = top;
615 for (int i = 0; i < 4; i++) {
616 texCoords[i].v = 1.0f - texCoords[i].v;
617 }
618
619 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
620 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
621 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
622 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
623
624 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
625 glDisable(GL_BLEND);
626}
627
628void Layer::setFiltering(bool filtering) {
629 mFiltering = filtering;
630}
631
632bool Layer::getFiltering() const {
633 return mFiltering;
634}
635
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800636// As documented in libhardware header, formats in the range
637// 0x100 - 0x1FF are specific to the HAL implementation, and
638// are known to have no alpha channel
639// TODO: move definition for device-specific range into
640// hardware.h, instead of using hard-coded values here.
641#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
642
Mathias Agopiana67932f2011-04-20 14:20:59 -0700643bool Layer::getOpacityForFormat(uint32_t format)
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800644{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700645 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
646 return true;
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800647 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700648 PixelFormatInfo info;
649 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
650 // in case of error (unknown format), we assume no blending
651 return (err || info.h_alpha <= info.l_alpha);
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800652}
653
Mathias Agopian13127d82013-03-05 17:47:11 -0800654// ----------------------------------------------------------------------------
655// local state
656// ----------------------------------------------------------------------------
657
658void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
659{
660 const Layer::State& s(drawingState());
661 const Transform tr(hw->getTransform() * s.transform);
662 const uint32_t hw_h = hw->getHeight();
663 Rect win(s.active.w, s.active.h);
664 if (!s.active.crop.isEmpty()) {
665 win.intersect(s.active.crop, &win);
666 }
667 if (mesh) {
668 tr.transform(mesh->mVertices[0], win.left, win.top);
669 tr.transform(mesh->mVertices[1], win.left, win.bottom);
670 tr.transform(mesh->mVertices[2], win.right, win.bottom);
671 tr.transform(mesh->mVertices[3], win.right, win.top);
672 for (size_t i=0 ; i<4 ; i++) {
673 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
674 }
675 }
676}
Eric Hassoldac45e6b2011-02-10 14:41:26 -0800677
Mathias Agopiana67932f2011-04-20 14:20:59 -0700678bool Layer::isOpaque() const
Mathias Agopiana7f66922010-05-26 22:08:52 -0700679{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700680 // if we don't have a buffer yet, we're translucent regardless of the
681 // layer's opaque flag.
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700682 if (mActiveBuffer == 0) {
Mathias Agopiana67932f2011-04-20 14:20:59 -0700683 return false;
Jamie Gennisdb5230f2011-07-28 14:54:07 -0700684 }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700685
686 // if the layer has the opaque flag, then we're always opaque,
687 // otherwise we use the current buffer's format.
688 return mOpaqueLayer || mCurrentOpacity;
Mathias Agopiana7f66922010-05-26 22:08:52 -0700689}
690
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800691bool Layer::isProtected() const
692{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700693 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
Jamie Gennis7a4d0df2011-03-09 17:05:02 -0800694 return (activeBuffer != 0) &&
695 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
696}
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700697
Mathias Agopian13127d82013-03-05 17:47:11 -0800698bool Layer::isFixedSize() const {
699 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
700}
701
702bool Layer::isCropped() const {
703 return !mCurrentCrop.isEmpty();
704}
705
706bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
707 return mNeedsFiltering || hw->needsFiltering();
708}
709
710void Layer::setVisibleRegion(const Region& visibleRegion) {
711 // always called from main thread
712 this->visibleRegion = visibleRegion;
713}
714
715void Layer::setCoveredRegion(const Region& coveredRegion) {
716 // always called from main thread
717 this->coveredRegion = coveredRegion;
718}
719
720void Layer::setVisibleNonTransparentRegion(const Region&
721 setVisibleNonTransparentRegion) {
722 // always called from main thread
723 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
724}
725
726// ----------------------------------------------------------------------------
727// transaction
728// ----------------------------------------------------------------------------
729
730uint32_t Layer::doTransaction(uint32_t flags) {
Jamie Gennis1c8e95c2012-02-23 19:27:23 -0800731 ATRACE_CALL();
732
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800733 const Layer::State& front(drawingState());
734 const Layer::State& temp(currentState());
735
Mathias Agopian4824d402012-06-04 18:16:30 -0700736 const bool sizeChanged = (temp.requested.w != front.requested.w) ||
737 (temp.requested.h != front.requested.h);
Mathias Agopiana138f892010-05-21 17:24:35 -0700738
739 if (sizeChanged) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700740 // the size changed, we need to ask our client to request a new buffer
Steve Block9d453682011-12-20 16:23:08 +0000741 ALOGD_IF(DEBUG_RESIZE,
Andy McFadden69052052012-09-14 16:10:11 -0700742 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
Mathias Agopian419e1962012-05-23 14:34:07 -0700743 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
744 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
745 " drawing={ 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",
Andy McFadden69052052012-09-14 16:10:11 -0700747 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
Mathias Agopian419e1962012-05-23 14:34:07 -0700748 temp.active.w, temp.active.h,
749 temp.active.crop.left,
750 temp.active.crop.top,
751 temp.active.crop.right,
752 temp.active.crop.bottom,
753 temp.active.crop.getWidth(),
754 temp.active.crop.getHeight(),
755 temp.requested.w, temp.requested.h,
Mathias Agopianb30c4152012-05-16 18:21:32 -0700756 temp.requested.crop.left,
757 temp.requested.crop.top,
758 temp.requested.crop.right,
759 temp.requested.crop.bottom,
760 temp.requested.crop.getWidth(),
761 temp.requested.crop.getHeight(),
Mathias Agopian419e1962012-05-23 14:34:07 -0700762 front.active.w, front.active.h,
763 front.active.crop.left,
764 front.active.crop.top,
765 front.active.crop.right,
766 front.active.crop.bottom,
767 front.active.crop.getWidth(),
768 front.active.crop.getHeight(),
769 front.requested.w, front.requested.h,
Mathias Agopianb30c4152012-05-16 18:21:32 -0700770 front.requested.crop.left,
771 front.requested.crop.top,
772 front.requested.crop.right,
773 front.requested.crop.bottom,
774 front.requested.crop.getWidth(),
Mathias Agopian419e1962012-05-23 14:34:07 -0700775 front.requested.crop.getHeight());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800776
Jamie Gennis2a0d5b62011-09-26 16:54:44 -0700777 // record the new size, form this point on, when the client request
778 // a buffer, it'll get the new size.
Andy McFaddenbf974ab2012-12-04 16:51:15 -0800779 mSurfaceFlingerConsumer->setDefaultBufferSize(
Mathias Agopianb30c4152012-05-16 18:21:32 -0700780 temp.requested.w, temp.requested.h);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800781 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700782
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700783 if (!isFixedSize()) {
784
785 const bool resizePending = (temp.requested.w != temp.active.w) ||
786 (temp.requested.h != temp.active.h);
787
788 if (resizePending) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800789 // don't let Layer::doTransaction update the drawing state
Mathias Agopian0cd545f2012-06-07 14:18:55 -0700790 // if we have a pending resize, unless we are in fixed-size mode.
791 // the drawing state will be updated only once we receive a buffer
792 // with the correct size.
793 //
794 // in particular, we want to make sure the clip (which is part
795 // of the geometry state) is latched together with the size but is
796 // latched immediately when no resizing is involved.
797
798 flags |= eDontUpdateGeometryState;
799 }
800 }
801
Mathias Agopian13127d82013-03-05 17:47:11 -0800802 // always set active to requested, unless we're asked not to
803 // this is used by Layer, which special cases resizes.
804 if (flags & eDontUpdateGeometryState) {
805 } else {
806 Layer::State& editTemp(currentState());
807 editTemp.active = temp.requested;
808 }
809
810 if (front.active != temp.active) {
811 // invalidate and recompute the visible regions if needed
812 flags |= Layer::eVisibleRegion;
813 }
814
815 if (temp.sequence != front.sequence) {
816 // invalidate and recompute the visible regions if needed
817 flags |= eVisibleRegion;
818 this->contentDirty = true;
819
820 // we may use linear filtering, if the matrix scales us
821 const uint8_t type = temp.transform.getType();
822 mNeedsFiltering = (!temp.transform.preserveRects() ||
823 (type >= Transform::SCALE));
824 }
825
826 // Commit the transaction
827 commitTransaction();
828 return flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800829}
830
Mathias Agopian13127d82013-03-05 17:47:11 -0800831void Layer::commitTransaction() {
832 mDrawingState = mCurrentState;
Mathias Agopiana67932f2011-04-20 14:20:59 -0700833}
834
Mathias Agopian13127d82013-03-05 17:47:11 -0800835uint32_t Layer::getTransactionFlags(uint32_t flags) {
836 return android_atomic_and(~flags, &mTransactionFlags) & flags;
837}
838
839uint32_t Layer::setTransactionFlags(uint32_t flags) {
840 return android_atomic_or(flags, &mTransactionFlags);
841}
842
843bool Layer::setPosition(float x, float y) {
844 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
845 return false;
846 mCurrentState.sequence++;
847 mCurrentState.transform.set(x, y);
848 setTransactionFlags(eTransactionNeeded);
849 return true;
850}
851bool Layer::setLayer(uint32_t z) {
852 if (mCurrentState.z == z)
853 return false;
854 mCurrentState.sequence++;
855 mCurrentState.z = z;
856 setTransactionFlags(eTransactionNeeded);
857 return true;
858}
859bool Layer::setSize(uint32_t w, uint32_t h) {
860 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
861 return false;
862 mCurrentState.requested.w = w;
863 mCurrentState.requested.h = h;
864 setTransactionFlags(eTransactionNeeded);
865 return true;
866}
867bool Layer::setAlpha(uint8_t alpha) {
868 if (mCurrentState.alpha == alpha)
869 return false;
870 mCurrentState.sequence++;
871 mCurrentState.alpha = alpha;
872 setTransactionFlags(eTransactionNeeded);
873 return true;
874}
875bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
876 mCurrentState.sequence++;
877 mCurrentState.transform.set(
878 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
879 setTransactionFlags(eTransactionNeeded);
880 return true;
881}
882bool Layer::setTransparentRegionHint(const Region& transparent) {
883 mCurrentState.sequence++;
884 mCurrentState.transparentRegion = transparent;
885 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
1010
1011 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 }
1063 return false;
1064 }
1065 };
1066
1067
1068 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
1069
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001070 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
Mathias Agopiana67932f2011-04-20 14:20:59 -07001071 // something happened!
1072 recomputeVisibleRegions = true;
Mathias Agopian4fec8732012-06-29 14:12:52 -07001073 return outDirtyRegion;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001074 }
Mathias Agopian96f08192010-06-02 23:28:45 -07001075
Jamie Gennis351a5132011-09-14 18:23:37 -07001076 // update the active buffer
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001077 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
Mathias Agopiane31564d2012-05-29 20:41:03 -07001078 if (mActiveBuffer == NULL) {
1079 // this can only happen if the very first buffer was rejected.
Mathias Agopian4fec8732012-06-29 14:12:52 -07001080 return outDirtyRegion;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001081 }
Mathias Agopianda9584d2010-12-13 18:51:59 -08001082
Mathias Agopian4824d402012-06-04 18:16:30 -07001083 mRefreshPending = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001084 mFrameLatencyNeeded = true;
Mathias Agopiane31564d2012-05-29 20:41:03 -07001085 if (oldActiveBuffer == NULL) {
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001086 // the first time we receive a buffer, we need to trigger a
1087 // geometry invalidation.
Andy McFaddenab10c582012-09-26 16:19:12 -07001088 recomputeVisibleRegions = true;
Mathias Agopian2c8207e2012-05-23 17:56:42 -07001089 }
1090
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001091 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1092 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1093 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
Mathias Agopian702634a2012-05-23 17:50:31 -07001094 if ((crop != mCurrentCrop) ||
1095 (transform != mCurrentTransform) ||
1096 (scalingMode != mCurrentScalingMode))
1097 {
1098 mCurrentCrop = crop;
1099 mCurrentTransform = transform;
1100 mCurrentScalingMode = scalingMode;
Andy McFaddenab10c582012-09-26 16:19:12 -07001101 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001102 }
1103
1104 if (oldActiveBuffer != NULL) {
Mathias Agopiane31564d2012-05-29 20:41:03 -07001105 uint32_t bufWidth = mActiveBuffer->getWidth();
1106 uint32_t bufHeight = mActiveBuffer->getHeight();
Mathias Agopian702634a2012-05-23 17:50:31 -07001107 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1108 bufHeight != uint32_t(oldActiveBuffer->height)) {
Andy McFaddenab10c582012-09-26 16:19:12 -07001109 recomputeVisibleRegions = true;
Mathias Agopian702634a2012-05-23 17:50:31 -07001110 }
1111 }
1112
1113 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1114 if (oldOpacity != isOpaque()) {
1115 recomputeVisibleRegions = true;
1116 }
1117
Mathias Agopian702634a2012-05-23 17:50:31 -07001118 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1119 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Mathias Agopian4fec8732012-06-29 14:12:52 -07001120
1121 // FIXME: postedRegion should be dirty & bounds
1122 const Layer::State& front(drawingState());
1123 Region dirtyRegion(Rect(front.active.w, front.active.h));
1124
1125 // transform the dirty region to window-manager space
1126 outDirtyRegion = (front.transform.transform(dirtyRegion));
Mathias Agopiancaa600c2009-09-16 18:27:24 -07001127 }
Mathias Agopian4fec8732012-06-29 14:12:52 -07001128 return outDirtyRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001129}
1130
Mathias Agopiana67932f2011-04-20 14:20:59 -07001131uint32_t Layer::getEffectiveUsage(uint32_t usage) const
Mathias Agopianb7e930d2010-06-01 15:12:58 -07001132{
Mathias Agopiana67932f2011-04-20 14:20:59 -07001133 // TODO: should we do something special if mSecure is set?
1134 if (mProtectedByApp) {
1135 // need a hardware-protected path to external video sink
1136 usage |= GraphicBuffer::USAGE_PROTECTED;
Jamie Gennis54cc83e2010-11-02 11:51:32 -07001137 }
Jamie Gennis3599bf22011-08-10 11:48:07 -07001138 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
Mathias Agopiana67932f2011-04-20 14:20:59 -07001139 return usage;
Mathias Agopianb5b7f262010-05-07 15:58:44 -07001140}
1141
Mathias Agopian84300952012-11-21 16:02:13 -08001142void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
Mathias Agopiana4583642011-08-23 18:03:18 -07001143 uint32_t orientation = 0;
1144 if (!mFlinger->mDebugDisableTransformHint) {
Mathias Agopian84300952012-11-21 16:02:13 -08001145 // The transform hint is used to improve performance, but we can
1146 // only have a single transform hint, it cannot
Mathias Agopian4fec8732012-06-29 14:12:52 -07001147 // apply to all displays.
Mathias Agopian42977342012-08-05 00:40:46 -07001148 const Transform& planeTransform(hw->getTransform());
Mathias Agopian4fec8732012-06-29 14:12:52 -07001149 orientation = planeTransform.getOrientation();
Mathias Agopiana4583642011-08-23 18:03:18 -07001150 if (orientation & Transform::ROT_INVALID) {
1151 orientation = 0;
1152 }
1153 }
Andy McFaddenbf974ab2012-12-04 16:51:15 -08001154 mSurfaceFlingerConsumer->setTransformHint(orientation);
Mathias Agopiana4583642011-08-23 18:03:18 -07001155}
1156
Mathias Agopian13127d82013-03-05 17:47:11 -08001157// ----------------------------------------------------------------------------
1158// debugging
1159// ----------------------------------------------------------------------------
1160
1161void Layer::dump(String8& result, char* buffer, size_t SIZE) const
1162{
1163 const Layer::State& s(drawingState());
1164
1165 snprintf(buffer, SIZE,
1166 "+ %s %p (%s)\n",
1167 getTypeId(), this, getName().string());
1168 result.append(buffer);
1169
1170 s.transparentRegion.dump(result, "transparentRegion");
1171 visibleRegion.dump(result, "visibleRegion");
1172 sp<Client> client(mClientRef.promote());
1173
1174 snprintf(buffer, SIZE,
1175 " "
1176 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1177 "isOpaque=%1d, invalidate=%1d, "
1178 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1179 " client=%p\n",
1180 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1181 s.active.crop.left, s.active.crop.top,
1182 s.active.crop.right, s.active.crop.bottom,
1183 isOpaque(), contentDirty,
1184 s.alpha, s.flags,
1185 s.transform[0][0], s.transform[0][1],
1186 s.transform[1][0], s.transform[1][1],
1187 client.get());
1188 result.append(buffer);
1189
1190 sp<const GraphicBuffer> buf0(mActiveBuffer);
1191 uint32_t w0=0, h0=0, s0=0, f0=0;
1192 if (buf0 != 0) {
1193 w0 = buf0->getWidth();
1194 h0 = buf0->getHeight();
1195 s0 = buf0->getStride();
1196 f0 = buf0->format;
1197 }
1198 snprintf(buffer, SIZE,
1199 " "
1200 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1201 " queued-frames=%d, mRefreshPending=%d\n",
1202 mFormat, w0, h0, s0,f0,
1203 mQueuedFrames, mRefreshPending);
1204
1205 result.append(buffer);
1206
1207 if (mSurfaceFlingerConsumer != 0) {
1208 mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE);
1209 }
1210}
1211
1212
1213void Layer::shortDump(String8& result, char* scratch, size_t size) const {
1214 Layer::dump(result, scratch, size);
1215}
1216
1217void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const {
1218 mFrameTracker.dump(result);
1219}
1220
1221void Layer::clearStats() {
1222 mFrameTracker.clear();
1223}
1224
1225// ---------------------------------------------------------------------------
1226
1227Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1228 const sp<Layer>& layer)
1229 : mFlinger(flinger), mLayer(layer) {
1230}
1231
1232Layer::LayerCleaner::~LayerCleaner() {
1233 // destroy client resources
1234 mFlinger->onLayerDestroyed(mLayer);
1235}
1236
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001237// ---------------------------------------------------------------------------
1238
1239
1240}; // namespace android