1 /*
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
17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include <math.h>
23
24 #include <cutils/compiler.h>
25 #include <cutils/native_handle.h>
26 #include <cutils/properties.h>
27
28 #include <utils/Errors.h>
29 #include <utils/Log.h>
30 #include <utils/NativeHandle.h>
31 #include <utils/StopWatch.h>
32 #include <utils/Trace.h>
33
34 #include <ui/GraphicBuffer.h>
35 #include <ui/PixelFormat.h>
36
37 #include <gui/Surface.h>
38
39 #include "clz.h"
40 #include "Colorizer.h"
41 #include "DisplayDevice.h"
42 #include "Layer.h"
43 #include "MonitoredProducer.h"
44 #include "SurfaceFlinger.h"
45
46 #include "DisplayHardware/HWComposer.h"
47
48 #include "RenderEngine/RenderEngine.h"
49
50 #define DEBUG_RESIZE 0
51
52 namespace android {
53
54 // ---------------------------------------------------------------------------
55
56 int32_t Layer::sSequence = 1;
57
Layer(SurfaceFlinger * flinger,const sp<Client> & client,const String8 & name,uint32_t w,uint32_t h,uint32_t flags)58 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
59 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
60 : contentDirty(false),
61 sequence(uint32_t(android_atomic_inc(&sSequence))),
62 mFlinger(flinger),
63 mTextureName(-1U),
64 mPremultipliedAlpha(true),
65 mName("unnamed"),
66 mDebug(false),
67 mFormat(PIXEL_FORMAT_NONE),
68 mTransactionFlags(0),
69 mQueuedFrames(0),
70 mSidebandStreamChanged(false),
71 mCurrentTransform(0),
72 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
73 mCurrentOpacity(true),
74 mRefreshPending(false),
75 mFrameLatencyNeeded(false),
76 mFiltering(false),
77 mNeedsFiltering(false),
78 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79 mSecure(false),
80 mProtectedByApp(false),
81 mHasSurface(false),
82 mClientRef(client),
83 mPotentialCursor(false)
84 {
85 mCurrentCrop.makeInvalid();
86 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
87 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
88
89 uint32_t layerFlags = 0;
90 if (flags & ISurfaceComposerClient::eHidden)
91 layerFlags |= layer_state_t::eLayerHidden;
92 if (flags & ISurfaceComposerClient::eOpaque)
93 layerFlags |= layer_state_t::eLayerOpaque;
94
95 if (flags & ISurfaceComposerClient::eNonPremultiplied)
96 mPremultipliedAlpha = false;
97
98 mName = name;
99
100 mCurrentState.active.w = w;
101 mCurrentState.active.h = h;
102 mCurrentState.active.crop.makeInvalid();
103 mCurrentState.z = 0;
104 mCurrentState.alpha = 0xFF;
105 mCurrentState.layerStack = 0;
106 mCurrentState.flags = layerFlags;
107 mCurrentState.sequence = 0;
108 mCurrentState.transform.set(0, 0);
109 mCurrentState.requested = mCurrentState.active;
110
111 // drawing state & current state are identical
112 mDrawingState = mCurrentState;
113
114 nsecs_t displayPeriod =
115 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
116 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
117 }
118
onFirstRef()119 void Layer::onFirstRef() {
120 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
121 sp<IGraphicBufferProducer> producer;
122 sp<IGraphicBufferConsumer> consumer;
123 BufferQueue::createBufferQueue(&producer, &consumer);
124 mProducer = new MonitoredProducer(producer, mFlinger);
125 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
126 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
127 mSurfaceFlingerConsumer->setContentsChangedListener(this);
128 mSurfaceFlingerConsumer->setName(mName);
129
130 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
131 #warning "disabling triple buffering"
132 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
133 #else
134 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
135 #endif
136
137 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
138 updateTransformHint(hw);
139 }
140
~Layer()141 Layer::~Layer() {
142 sp<Client> c(mClientRef.promote());
143 if (c != 0) {
144 c->detachLayer(this);
145 }
146 mFlinger->deleteTextureAsync(mTextureName);
147 mFrameTracker.logAndResetStats(mName);
148 }
149
150 // ---------------------------------------------------------------------------
151 // callbacks
152 // ---------------------------------------------------------------------------
153
onLayerDisplayed(const sp<const DisplayDevice> &,HWComposer::HWCLayerInterface * layer)154 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
155 HWComposer::HWCLayerInterface* layer) {
156 if (layer) {
157 layer->onDisplayed();
158 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
159 }
160 }
161
onFrameAvailable()162 void Layer::onFrameAvailable() {
163 android_atomic_inc(&mQueuedFrames);
164 mFlinger->signalLayerUpdate();
165 }
166
onSidebandStreamChanged()167 void Layer::onSidebandStreamChanged() {
168 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
169 // mSidebandStreamChanged was false
170 mFlinger->signalLayerUpdate();
171 }
172 }
173
174 // called with SurfaceFlinger::mStateLock from the drawing thread after
175 // the layer has been remove from the current state list (and just before
176 // it's removed from the drawing state list)
onRemoved()177 void Layer::onRemoved() {
178 mSurfaceFlingerConsumer->abandon();
179 }
180
181 // ---------------------------------------------------------------------------
182 // set-up
183 // ---------------------------------------------------------------------------
184
getName() const185 const String8& Layer::getName() const {
186 return mName;
187 }
188
setBuffers(uint32_t w,uint32_t h,PixelFormat format,uint32_t flags)189 status_t Layer::setBuffers( uint32_t w, uint32_t h,
190 PixelFormat format, uint32_t flags)
191 {
192 uint32_t const maxSurfaceDims = min(
193 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
194
195 // never allow a surface larger than what our underlying GL implementation
196 // can handle.
197 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
198 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
199 return BAD_VALUE;
200 }
201
202 mFormat = format;
203
204 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
205 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
206 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
207 mCurrentOpacity = getOpacityForFormat(format);
208
209 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
210 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
211 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
212
213 return NO_ERROR;
214 }
215
getHandle()216 sp<IBinder> Layer::getHandle() {
217 Mutex::Autolock _l(mLock);
218
219 LOG_ALWAYS_FATAL_IF(mHasSurface,
220 "Layer::getHandle() has already been called");
221
222 mHasSurface = true;
223
224 /*
225 * The layer handle is just a BBinder object passed to the client
226 * (remote process) -- we don't keep any reference on our side such that
227 * the dtor is called when the remote side let go of its reference.
228 *
229 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
230 * this layer when the handle is destroyed.
231 */
232
233 class Handle : public BBinder, public LayerCleaner {
234 wp<const Layer> mOwner;
235 public:
236 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
237 : LayerCleaner(flinger, layer), mOwner(layer) {
238 }
239 };
240
241 return new Handle(mFlinger, this);
242 }
243
getProducer() const244 sp<IGraphicBufferProducer> Layer::getProducer() const {
245 return mProducer;
246 }
247
248 // ---------------------------------------------------------------------------
249 // h/w composer set-up
250 // ---------------------------------------------------------------------------
251
getContentCrop() const252 Rect Layer::getContentCrop() const {
253 // this is the crop rectangle that applies to the buffer
254 // itself (as opposed to the window)
255 Rect crop;
256 if (!mCurrentCrop.isEmpty()) {
257 // if the buffer crop is defined, we use that
258 crop = mCurrentCrop;
259 } else if (mActiveBuffer != NULL) {
260 // otherwise we use the whole buffer
261 crop = mActiveBuffer->getBounds();
262 } else {
263 // if we don't have a buffer yet, we use an empty/invalid crop
264 crop.makeInvalid();
265 }
266 return crop;
267 }
268
reduce(const Rect & win,const Region & exclude)269 static Rect reduce(const Rect& win, const Region& exclude) {
270 if (CC_LIKELY(exclude.isEmpty())) {
271 return win;
272 }
273 if (exclude.isRect()) {
274 return win.reduce(exclude.getBounds());
275 }
276 return Region(win).subtract(exclude).getBounds();
277 }
278
computeBounds() const279 Rect Layer::computeBounds() const {
280 const Layer::State& s(getDrawingState());
281 Rect win(s.active.w, s.active.h);
282 if (!s.active.crop.isEmpty()) {
283 win.intersect(s.active.crop, &win);
284 }
285 // subtract the transparent region and snap to the bounds
286 return reduce(win, s.activeTransparentRegion);
287 }
288
computeCrop(const sp<const DisplayDevice> & hw) const289 FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
290 // the content crop is the area of the content that gets scaled to the
291 // layer's size.
292 FloatRect 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(getDrawingState());
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 involved, this operation will map to full
301 // pixels in the buffer.
302 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
303 // a viewport clipping and a window transform. we should use floating point to fix this.
304
305 Rect activeCrop(s.active.w, s.active.h);
306 if (!s.active.crop.isEmpty()) {
307 activeCrop = s.active.crop;
308 }
309
310 activeCrop = s.transform.transform(activeCrop);
311 activeCrop.intersect(hw->getViewport(), &activeCrop);
312 activeCrop = s.transform.inverse().transform(activeCrop);
313
314 // paranoia: make sure the window-crop is constrained in the
315 // window's bounds
316 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
317
318 // subtract the transparent region and snap to the bounds
319 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
320
321 if (!activeCrop.isEmpty()) {
322 // Transform the window crop to match the buffer coordinate system,
323 // which means using the inverse of the current transform set on the
324 // SurfaceFlingerConsumer.
325 uint32_t invTransform = mCurrentTransform;
326 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
327 /*
328 * the code below applies the display's inverse transform to the buffer
329 */
330 uint32_t invTransformOrient = hw->getOrientationTransform();
331 // calculate the inverse transform
332 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
333 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
334 NATIVE_WINDOW_TRANSFORM_FLIP_H;
335 // If the transform has been rotated the axis of flip has been swapped
336 // so we need to swap which flip operations we are performing
337 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
338 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
339 if (is_h_flipped != is_v_flipped) {
340 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
341 NATIVE_WINDOW_TRANSFORM_FLIP_H;
342 }
343 }
344 // and apply to the current transform
345 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
346 }
347
348 int winWidth = s.active.w;
349 int winHeight = s.active.h;
350 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
351 // If the activeCrop has been rotate the ends are rotated but not
352 // the space itself so when transforming ends back we can't rely on
353 // a modification of the axes of rotation. To account for this we
354 // need to reorient the inverse rotation in terms of the current
355 // axes of rotation.
356 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
357 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
358 if (is_h_flipped == is_v_flipped) {
359 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
360 NATIVE_WINDOW_TRANSFORM_FLIP_H;
361 }
362 winWidth = s.active.h;
363 winHeight = s.active.w;
364 }
365 const Rect winCrop = activeCrop.transform(
366 invTransform, s.active.w, s.active.h);
367
368 // below, crop is intersected with winCrop expressed in crop's coordinate space
369 float xScale = crop.getWidth() / float(winWidth);
370 float yScale = crop.getHeight() / float(winHeight);
371
372 float insetL = winCrop.left * xScale;
373 float insetT = winCrop.top * yScale;
374 float insetR = (winWidth - winCrop.right ) * xScale;
375 float insetB = (winHeight - winCrop.bottom) * yScale;
376
377 crop.left += insetL;
378 crop.top += insetT;
379 crop.right -= insetR;
380 crop.bottom -= insetB;
381 }
382 return crop;
383 }
384
setGeometry(const sp<const DisplayDevice> & hw,HWComposer::HWCLayerInterface & layer)385 void Layer::setGeometry(
386 const sp<const DisplayDevice>& hw,
387 HWComposer::HWCLayerInterface& layer)
388 {
389 layer.setDefaultState();
390
391 // enable this layer
392 layer.setSkip(false);
393
394 if (isSecure() && !hw->isSecure()) {
395 layer.setSkip(true);
396 }
397
398 // this gives us only the "orientation" component of the transform
399 const State& s(getDrawingState());
400 if (!isOpaque(s) || s.alpha != 0xFF) {
401 layer.setBlending(mPremultipliedAlpha ?
402 HWC_BLENDING_PREMULT :
403 HWC_BLENDING_COVERAGE);
404 }
405
406 // apply the layer's transform, followed by the display's global transform
407 // here we're guaranteed that the layer's transform preserves rects
408 Rect frame(s.transform.transform(computeBounds()));
409 frame.intersect(hw->getViewport(), &frame);
410 const Transform& tr(hw->getTransform());
411 layer.setFrame(tr.transform(frame));
412 layer.setCrop(computeCrop(hw));
413 layer.setPlaneAlpha(s.alpha);
414
415 /*
416 * Transformations are applied in this order:
417 * 1) buffer orientation/flip/mirror
418 * 2) state transformation (window manager)
419 * 3) layer orientation (screen orientation)
420 * (NOTE: the matrices are multiplied in reverse order)
421 */
422
423 const Transform bufferOrientation(mCurrentTransform);
424 Transform transform(tr * s.transform * bufferOrientation);
425
426 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
427 /*
428 * the code below applies the display's inverse transform to the buffer
429 */
430 uint32_t invTransform = hw->getOrientationTransform();
431 uint32_t t_orientation = transform.getOrientation();
432 // calculate the inverse transform
433 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
434 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
435 NATIVE_WINDOW_TRANSFORM_FLIP_H;
436 // If the transform has been rotated the axis of flip has been swapped
437 // so we need to swap which flip operations we are performing
438 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
439 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
440 if (is_h_flipped != is_v_flipped) {
441 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
442 NATIVE_WINDOW_TRANSFORM_FLIP_H;
443 }
444 }
445 // and apply to the current transform
446 transform = Transform(t_orientation) * Transform(invTransform);
447 }
448
449 // this gives us only the "orientation" component of the transform
450 const uint32_t orientation = transform.getOrientation();
451 if (orientation & Transform::ROT_INVALID) {
452 // we can only handle simple transformation
453 layer.setSkip(true);
454 } else {
455 layer.setTransform(orientation);
456 }
457 }
458
setPerFrameData(const sp<const DisplayDevice> & hw,HWComposer::HWCLayerInterface & layer)459 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
460 HWComposer::HWCLayerInterface& layer) {
461 // we have to set the visible region on every frame because
462 // we currently free it during onLayerDisplayed(), which is called
463 // after HWComposer::commit() -- every frame.
464 // Apply this display's projection's viewport to the visible region
465 // before giving it to the HWC HAL.
466 const Transform& tr = hw->getTransform();
467 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
468 layer.setVisibleRegionScreen(visible);
469
470 if (mSidebandStream.get()) {
471 layer.setSidebandStream(mSidebandStream);
472 } else {
473 // NOTE: buffer can be NULL if the client never drew into this
474 // layer yet, or if we ran out of memory
475 layer.setBuffer(mActiveBuffer);
476 }
477 }
478
setAcquireFence(const sp<const DisplayDevice> &,HWComposer::HWCLayerInterface & layer)479 void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
480 HWComposer::HWCLayerInterface& layer) {
481 int fenceFd = -1;
482
483 // TODO: there is a possible optimization here: we only need to set the
484 // acquire fence the first time a new buffer is acquired on EACH display.
485
486 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
487 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
488 if (fence->isValid()) {
489 fenceFd = fence->dup();
490 if (fenceFd == -1) {
491 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
492 }
493 }
494 }
495 layer.setAcquireFenceFd(fenceFd);
496 }
497
getPosition(const sp<const DisplayDevice> & hw)498 Rect Layer::getPosition(
499 const sp<const DisplayDevice>& hw)
500 {
501 // this gives us only the "orientation" component of the transform
502 const State& s(getCurrentState());
503
504 // apply the layer's transform, followed by the display's global transform
505 // here we're guaranteed that the layer's transform preserves rects
506 Rect win(s.active.w, s.active.h);
507 if (!s.active.crop.isEmpty()) {
508 win.intersect(s.active.crop, &win);
509 }
510 // subtract the transparent region and snap to the bounds
511 Rect bounds = reduce(win, s.activeTransparentRegion);
512 Rect frame(s.transform.transform(bounds));
513 frame.intersect(hw->getViewport(), &frame);
514 const Transform& tr(hw->getTransform());
515 return Rect(tr.transform(frame));
516 }
517
518 // ---------------------------------------------------------------------------
519 // drawing...
520 // ---------------------------------------------------------------------------
521
draw(const sp<const DisplayDevice> & hw,const Region & clip) const522 void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
523 onDraw(hw, clip, false);
524 }
525
draw(const sp<const DisplayDevice> & hw,bool useIdentityTransform) const526 void Layer::draw(const sp<const DisplayDevice>& hw,
527 bool useIdentityTransform) const {
528 onDraw(hw, Region(hw->bounds()), useIdentityTransform);
529 }
530
draw(const sp<const DisplayDevice> & hw) const531 void Layer::draw(const sp<const DisplayDevice>& hw) const {
532 onDraw(hw, Region(hw->bounds()), false);
533 }
534
onDraw(const sp<const DisplayDevice> & hw,const Region & clip,bool useIdentityTransform) const535 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
536 bool useIdentityTransform) const
537 {
538 ATRACE_CALL();
539
540 if (CC_UNLIKELY(mActiveBuffer == 0)) {
541 // the texture has not been created yet, this Layer has
542 // in fact never been drawn into. This happens frequently with
543 // SurfaceView because the WindowManager can't know when the client
544 // has drawn the first time.
545
546 // If there is nothing under us, we paint the screen in black, otherwise
547 // we just skip this update.
548
549 // figure out if there is something below us
550 Region under;
551 const SurfaceFlinger::LayerVector& drawingLayers(
552 mFlinger->mDrawingState.layersSortedByZ);
553 const size_t count = drawingLayers.size();
554 for (size_t i=0 ; i<count ; ++i) {
555 const sp<Layer>& layer(drawingLayers[i]);
556 if (layer.get() == static_cast<Layer const*>(this))
557 break;
558 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
559 }
560 // if not everything below us is covered, we plug the holes!
561 Region holes(clip.subtract(under));
562 if (!holes.isEmpty()) {
563 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
564 }
565 return;
566 }
567
568 // Bind the current buffer to the GL texture, and wait for it to be
569 // ready for us to draw into.
570 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
571 if (err != NO_ERROR) {
572 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
573 // Go ahead and draw the buffer anyway; no matter what we do the screen
574 // is probably going to have something visibly wrong.
575 }
576
577 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
578
579 RenderEngine& engine(mFlinger->getRenderEngine());
580
581 if (!blackOutLayer) {
582 // TODO: we could be more subtle with isFixedSize()
583 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
584
585 // Query the texture matrix given our current filtering mode.
586 float textureMatrix[16];
587 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
588 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
589
590 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
591
592 /*
593 * the code below applies the display's inverse transform to the texture transform
594 */
595
596 // create a 4x4 transform matrix from the display transform flags
597 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
598 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
599 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
600
601 mat4 tr;
602 uint32_t transform = hw->getOrientationTransform();
603 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
604 tr = tr * rot90;
605 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
606 tr = tr * flipH;
607 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
608 tr = tr * flipV;
609
610 // calculate the inverse
611 tr = inverse(tr);
612
613 // and finally apply it to the original texture matrix
614 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
615 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
616 }
617
618 // Set things up for texturing.
619 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
620 mTexture.setFiltering(useFiltering);
621 mTexture.setMatrix(textureMatrix);
622
623 engine.setupLayerTexturing(mTexture);
624 } else {
625 engine.setupLayerBlackedOut();
626 }
627 drawWithOpenGL(hw, clip, useIdentityTransform);
628 engine.disableTexturing();
629 }
630
631
clearWithOpenGL(const sp<const DisplayDevice> & hw,const Region &,float red,float green,float blue,float alpha) const632 void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
633 const Region& /* clip */, float red, float green, float blue,
634 float alpha) const
635 {
636 RenderEngine& engine(mFlinger->getRenderEngine());
637 computeGeometry(hw, mMesh, false);
638 engine.setupFillWithColor(red, green, blue, alpha);
639 engine.drawMesh(mMesh);
640 }
641
clearWithOpenGL(const sp<const DisplayDevice> & hw,const Region & clip) const642 void Layer::clearWithOpenGL(
643 const sp<const DisplayDevice>& hw, const Region& clip) const {
644 clearWithOpenGL(hw, clip, 0,0,0,0);
645 }
646
drawWithOpenGL(const sp<const DisplayDevice> & hw,const Region &,bool useIdentityTransform) const647 void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
648 const Region& /* clip */, bool useIdentityTransform) const {
649 const uint32_t fbHeight = hw->getHeight();
650 const State& s(getDrawingState());
651
652 computeGeometry(hw, mMesh, useIdentityTransform);
653
654 /*
655 * NOTE: the way we compute the texture coordinates here produces
656 * different results than when we take the HWC path -- in the later case
657 * the "source crop" is rounded to texel boundaries.
658 * This can produce significantly different results when the texture
659 * is scaled by a large amount.
660 *
661 * The GL code below is more logical (imho), and the difference with
662 * HWC is due to a limitation of the HWC API to integers -- a question
663 * is suspend is whether we should ignore this problem or revert to
664 * GL composition when a buffer scaling is applied (maybe with some
665 * minimal value)? Or, we could make GL behave like HWC -- but this feel
666 * like more of a hack.
667 */
668 const Rect win(computeBounds());
669
670 float left = float(win.left) / float(s.active.w);
671 float top = float(win.top) / float(s.active.h);
672 float right = float(win.right) / float(s.active.w);
673 float bottom = float(win.bottom) / float(s.active.h);
674
675 // TODO: we probably want to generate the texture coords with the mesh
676 // here we assume that we only have 4 vertices
677 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
678 texCoords[0] = vec2(left, 1.0f - top);
679 texCoords[1] = vec2(left, 1.0f - bottom);
680 texCoords[2] = vec2(right, 1.0f - bottom);
681 texCoords[3] = vec2(right, 1.0f - top);
682
683 RenderEngine& engine(mFlinger->getRenderEngine());
684 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
685 engine.drawMesh(mMesh);
686 engine.disableBlending();
687 }
688
getProducerStickyTransform() const689 uint32_t Layer::getProducerStickyTransform() const {
690 int producerStickyTransform = 0;
691 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
692 if (ret != OK) {
693 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
694 strerror(-ret), ret);
695 return 0;
696 }
697 return static_cast<uint32_t>(producerStickyTransform);
698 }
699
setFiltering(bool filtering)700 void Layer::setFiltering(bool filtering) {
701 mFiltering = filtering;
702 }
703
getFiltering() const704 bool Layer::getFiltering() const {
705 return mFiltering;
706 }
707
708 // As documented in libhardware header, formats in the range
709 // 0x100 - 0x1FF are specific to the HAL implementation, and
710 // are known to have no alpha channel
711 // TODO: move definition for device-specific range into
712 // hardware.h, instead of using hard-coded values here.
713 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
714
getOpacityForFormat(uint32_t format)715 bool Layer::getOpacityForFormat(uint32_t format) {
716 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
717 return true;
718 }
719 switch (format) {
720 case HAL_PIXEL_FORMAT_RGBA_8888:
721 case HAL_PIXEL_FORMAT_BGRA_8888:
722 case HAL_PIXEL_FORMAT_sRGB_A_8888:
723 return false;
724 }
725 // in all other case, we have no blending (also for unknown formats)
726 return true;
727 }
728
729 // ----------------------------------------------------------------------------
730 // local state
731 // ----------------------------------------------------------------------------
732
computeGeometry(const sp<const DisplayDevice> & hw,Mesh & mesh,bool useIdentityTransform) const733 void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
734 bool useIdentityTransform) const
735 {
736 const Layer::State& s(getDrawingState());
737 const Transform tr(useIdentityTransform ?
738 hw->getTransform() : hw->getTransform() * s.transform);
739 const uint32_t hw_h = hw->getHeight();
740 Rect win(s.active.w, s.active.h);
741 if (!s.active.crop.isEmpty()) {
742 win.intersect(s.active.crop, &win);
743 }
744 // subtract the transparent region and snap to the bounds
745 win = reduce(win, s.activeTransparentRegion);
746
747 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
748 position[0] = tr.transform(win.left, win.top);
749 position[1] = tr.transform(win.left, win.bottom);
750 position[2] = tr.transform(win.right, win.bottom);
751 position[3] = tr.transform(win.right, win.top);
752 for (size_t i=0 ; i<4 ; i++) {
753 position[i].y = hw_h - position[i].y;
754 }
755 }
756
isOpaque(const Layer::State & s) const757 bool Layer::isOpaque(const Layer::State& s) const
758 {
759 // if we don't have a buffer yet, we're translucent regardless of the
760 // layer's opaque flag.
761 if (mActiveBuffer == 0) {
762 return false;
763 }
764
765 // if the layer has the opaque flag, then we're always opaque,
766 // otherwise we use the current buffer's format.
767 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
768 }
769
isProtected() const770 bool Layer::isProtected() const
771 {
772 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
773 return (activeBuffer != 0) &&
774 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
775 }
776
isFixedSize() const777 bool Layer::isFixedSize() const {
778 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
779 }
780
isCropped() const781 bool Layer::isCropped() const {
782 return !mCurrentCrop.isEmpty();
783 }
784
needsFiltering(const sp<const DisplayDevice> & hw) const785 bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
786 return mNeedsFiltering || hw->needsFiltering();
787 }
788
setVisibleRegion(const Region & visibleRegion)789 void Layer::setVisibleRegion(const Region& visibleRegion) {
790 // always called from main thread
791 this->visibleRegion = visibleRegion;
792 }
793
setCoveredRegion(const Region & coveredRegion)794 void Layer::setCoveredRegion(const Region& coveredRegion) {
795 // always called from main thread
796 this->coveredRegion = coveredRegion;
797 }
798
setVisibleNonTransparentRegion(const Region & setVisibleNonTransparentRegion)799 void Layer::setVisibleNonTransparentRegion(const Region&
800 setVisibleNonTransparentRegion) {
801 // always called from main thread
802 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
803 }
804
805 // ----------------------------------------------------------------------------
806 // transaction
807 // ----------------------------------------------------------------------------
808
doTransaction(uint32_t flags)809 uint32_t Layer::doTransaction(uint32_t flags) {
810 ATRACE_CALL();
811
812 const Layer::State& s(getDrawingState());
813 const Layer::State& c(getCurrentState());
814
815 const bool sizeChanged = (c.requested.w != s.requested.w) ||
816 (c.requested.h != s.requested.h);
817
818 if (sizeChanged) {
819 // the size changed, we need to ask our client to request a new buffer
820 ALOGD_IF(DEBUG_RESIZE,
821 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
822 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
823 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
824 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
825 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
826 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
827 c.active.w, c.active.h,
828 c.active.crop.left,
829 c.active.crop.top,
830 c.active.crop.right,
831 c.active.crop.bottom,
832 c.active.crop.getWidth(),
833 c.active.crop.getHeight(),
834 c.requested.w, c.requested.h,
835 c.requested.crop.left,
836 c.requested.crop.top,
837 c.requested.crop.right,
838 c.requested.crop.bottom,
839 c.requested.crop.getWidth(),
840 c.requested.crop.getHeight(),
841 s.active.w, s.active.h,
842 s.active.crop.left,
843 s.active.crop.top,
844 s.active.crop.right,
845 s.active.crop.bottom,
846 s.active.crop.getWidth(),
847 s.active.crop.getHeight(),
848 s.requested.w, s.requested.h,
849 s.requested.crop.left,
850 s.requested.crop.top,
851 s.requested.crop.right,
852 s.requested.crop.bottom,
853 s.requested.crop.getWidth(),
854 s.requested.crop.getHeight());
855
856 // record the new size, form this point on, when the client request
857 // a buffer, it'll get the new size.
858 mSurfaceFlingerConsumer->setDefaultBufferSize(
859 c.requested.w, c.requested.h);
860 }
861
862 if (!isFixedSize()) {
863
864 const bool resizePending = (c.requested.w != c.active.w) ||
865 (c.requested.h != c.active.h);
866
867 if (resizePending) {
868 // don't let Layer::doTransaction update the drawing state
869 // if we have a pending resize, unless we are in fixed-size mode.
870 // the drawing state will be updated only once we receive a buffer
871 // with the correct size.
872 //
873 // in particular, we want to make sure the clip (which is part
874 // of the geometry state) is latched together with the size but is
875 // latched immediately when no resizing is involved.
876
877 flags |= eDontUpdateGeometryState;
878 }
879 }
880
881 // always set active to requested, unless we're asked not to
882 // this is used by Layer, which special cases resizes.
883 if (flags & eDontUpdateGeometryState) {
884 } else {
885 Layer::State& editCurrentState(getCurrentState());
886 editCurrentState.active = c.requested;
887 }
888
889 if (s.active != c.active) {
890 // invalidate and recompute the visible regions if needed
891 flags |= Layer::eVisibleRegion;
892 }
893
894 if (c.sequence != s.sequence) {
895 // invalidate and recompute the visible regions if needed
896 flags |= eVisibleRegion;
897 this->contentDirty = true;
898
899 // we may use linear filtering, if the matrix scales us
900 const uint8_t type = c.transform.getType();
901 mNeedsFiltering = (!c.transform.preserveRects() ||
902 (type >= Transform::SCALE));
903 }
904
905 // Commit the transaction
906 commitTransaction();
907 return flags;
908 }
909
commitTransaction()910 void Layer::commitTransaction() {
911 mDrawingState = mCurrentState;
912 }
913
getTransactionFlags(uint32_t flags)914 uint32_t Layer::getTransactionFlags(uint32_t flags) {
915 return android_atomic_and(~flags, &mTransactionFlags) & flags;
916 }
917
setTransactionFlags(uint32_t flags)918 uint32_t Layer::setTransactionFlags(uint32_t flags) {
919 return android_atomic_or(flags, &mTransactionFlags);
920 }
921
setPosition(float x,float y)922 bool Layer::setPosition(float x, float y) {
923 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
924 return false;
925 mCurrentState.sequence++;
926 mCurrentState.transform.set(x, y);
927 setTransactionFlags(eTransactionNeeded);
928 return true;
929 }
setLayer(uint32_t z)930 bool Layer::setLayer(uint32_t z) {
931 if (mCurrentState.z == z)
932 return false;
933 mCurrentState.sequence++;
934 mCurrentState.z = z;
935 setTransactionFlags(eTransactionNeeded);
936 return true;
937 }
setSize(uint32_t w,uint32_t h)938 bool Layer::setSize(uint32_t w, uint32_t h) {
939 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
940 return false;
941 mCurrentState.requested.w = w;
942 mCurrentState.requested.h = h;
943 setTransactionFlags(eTransactionNeeded);
944 return true;
945 }
setAlpha(uint8_t alpha)946 bool Layer::setAlpha(uint8_t alpha) {
947 if (mCurrentState.alpha == alpha)
948 return false;
949 mCurrentState.sequence++;
950 mCurrentState.alpha = alpha;
951 setTransactionFlags(eTransactionNeeded);
952 return true;
953 }
setMatrix(const layer_state_t::matrix22_t & matrix)954 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
955 mCurrentState.sequence++;
956 mCurrentState.transform.set(
957 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
958 setTransactionFlags(eTransactionNeeded);
959 return true;
960 }
setTransparentRegionHint(const Region & transparent)961 bool Layer::setTransparentRegionHint(const Region& transparent) {
962 mCurrentState.requestedTransparentRegion = transparent;
963 setTransactionFlags(eTransactionNeeded);
964 return true;
965 }
setFlags(uint8_t flags,uint8_t mask)966 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
967 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
968 if (mCurrentState.flags == newFlags)
969 return false;
970 mCurrentState.sequence++;
971 mCurrentState.flags = newFlags;
972 setTransactionFlags(eTransactionNeeded);
973 return true;
974 }
setCrop(const Rect & crop)975 bool Layer::setCrop(const Rect& crop) {
976 if (mCurrentState.requested.crop == crop)
977 return false;
978 mCurrentState.sequence++;
979 mCurrentState.requested.crop = crop;
980 setTransactionFlags(eTransactionNeeded);
981 return true;
982 }
983
setLayerStack(uint32_t layerStack)984 bool Layer::setLayerStack(uint32_t layerStack) {
985 if (mCurrentState.layerStack == layerStack)
986 return false;
987 mCurrentState.sequence++;
988 mCurrentState.layerStack = layerStack;
989 setTransactionFlags(eTransactionNeeded);
990 return true;
991 }
992
993 // ----------------------------------------------------------------------------
994 // pageflip handling...
995 // ----------------------------------------------------------------------------
996
onPreComposition()997 bool Layer::onPreComposition() {
998 mRefreshPending = false;
999 return mQueuedFrames > 0 || mSidebandStreamChanged;
1000 }
1001
onPostComposition()1002 void Layer::onPostComposition() {
1003 if (mFrameLatencyNeeded) {
1004 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
1005 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1006
1007 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1008 if (frameReadyFence->isValid()) {
1009 mFrameTracker.setFrameReadyFence(frameReadyFence);
1010 } else {
1011 // There was no fence for this frame, so assume that it was ready
1012 // to be presented at the desired present time.
1013 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1014 }
1015
1016 const HWComposer& hwc = mFlinger->getHwComposer();
1017 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1018 if (presentFence->isValid()) {
1019 mFrameTracker.setActualPresentFence(presentFence);
1020 } else {
1021 // The HWC doesn't support present fences, so use the refresh
1022 // timestamp instead.
1023 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1024 mFrameTracker.setActualPresentTime(presentTime);
1025 }
1026
1027 mFrameTracker.advanceFrame();
1028 mFrameLatencyNeeded = false;
1029 }
1030 }
1031
isVisible() const1032 bool Layer::isVisible() const {
1033 const Layer::State& s(mDrawingState);
1034 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1035 && (mActiveBuffer != NULL || mSidebandStream != NULL);
1036 }
1037
latchBuffer(bool & recomputeVisibleRegions)1038 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
1039 {
1040 ATRACE_CALL();
1041
1042 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1043 // mSidebandStreamChanged was true
1044 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
1045 recomputeVisibleRegions = true;
1046
1047 const State& s(getDrawingState());
1048 return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1049 }
1050
1051 Region outDirtyRegion;
1052 if (mQueuedFrames > 0) {
1053
1054 // if we've already called updateTexImage() without going through
1055 // a composition step, we have to skip this layer at this point
1056 // because we cannot call updateTeximage() without a corresponding
1057 // compositionComplete() call.
1058 // we'll trigger an update in onPreComposition().
1059 if (mRefreshPending) {
1060 return outDirtyRegion;
1061 }
1062
1063 // Capture the old state of the layer for comparisons later
1064 const State& s(getDrawingState());
1065 const bool oldOpacity = isOpaque(s);
1066 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1067
1068 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
1069 Layer::State& front;
1070 Layer::State& current;
1071 bool& recomputeVisibleRegions;
1072 bool stickyTransformSet;
1073 Reject(Layer::State& front, Layer::State& current,
1074 bool& recomputeVisibleRegions, bool stickySet)
1075 : front(front), current(current),
1076 recomputeVisibleRegions(recomputeVisibleRegions),
1077 stickyTransformSet(stickySet) {
1078 }
1079
1080 virtual bool reject(const sp<GraphicBuffer>& buf,
1081 const IGraphicBufferConsumer::BufferItem& item) {
1082 if (buf == NULL) {
1083 return false;
1084 }
1085
1086 uint32_t bufWidth = buf->getWidth();
1087 uint32_t bufHeight = buf->getHeight();
1088
1089 // check that we received a buffer of the right size
1090 // (Take the buffer's orientation into account)
1091 if (item.mTransform & Transform::ROT_90) {
1092 swap(bufWidth, bufHeight);
1093 }
1094
1095 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1096 if (front.active != front.requested) {
1097
1098 if (isFixedSize ||
1099 (bufWidth == front.requested.w &&
1100 bufHeight == front.requested.h))
1101 {
1102 // Here we pretend the transaction happened by updating the
1103 // current and drawing states. Drawing state is only accessed
1104 // in this thread, no need to have it locked
1105 front.active = front.requested;
1106
1107 // We also need to update the current state so that
1108 // we don't end-up overwriting the drawing state with
1109 // this stale current state during the next transaction
1110 //
1111 // NOTE: We don't need to hold the transaction lock here
1112 // because State::active is only accessed from this thread.
1113 current.active = front.active;
1114
1115 // recompute visible region
1116 recomputeVisibleRegions = true;
1117 }
1118
1119 ALOGD_IF(DEBUG_RESIZE,
1120 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
1121 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1122 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
1123 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
1124 front.active.w, front.active.h,
1125 front.active.crop.left,
1126 front.active.crop.top,
1127 front.active.crop.right,
1128 front.active.crop.bottom,
1129 front.active.crop.getWidth(),
1130 front.active.crop.getHeight(),
1131 front.requested.w, front.requested.h,
1132 front.requested.crop.left,
1133 front.requested.crop.top,
1134 front.requested.crop.right,
1135 front.requested.crop.bottom,
1136 front.requested.crop.getWidth(),
1137 front.requested.crop.getHeight());
1138 }
1139
1140 if (!isFixedSize && !stickyTransformSet) {
1141 if (front.active.w != bufWidth ||
1142 front.active.h != bufHeight) {
1143 // reject this buffer
1144 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1145 bufWidth, bufHeight, front.active.w, front.active.h);
1146 return true;
1147 }
1148 }
1149
1150 // if the transparent region has changed (this test is
1151 // conservative, but that's fine, worst case we're doing
1152 // a bit of extra work), we latch the new one and we
1153 // trigger a visible-region recompute.
1154 if (!front.activeTransparentRegion.isTriviallyEqual(
1155 front.requestedTransparentRegion)) {
1156 front.activeTransparentRegion = front.requestedTransparentRegion;
1157
1158 // We also need to update the current state so that
1159 // we don't end-up overwriting the drawing state with
1160 // this stale current state during the next transaction
1161 //
1162 // NOTE: We don't need to hold the transaction lock here
1163 // because State::active is only accessed from this thread.
1164 current.activeTransparentRegion = front.activeTransparentRegion;
1165
1166 // recompute visible region
1167 recomputeVisibleRegions = true;
1168 }
1169
1170 return false;
1171 }
1172 };
1173
1174 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1175 getProducerStickyTransform() != 0);
1176
1177 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1178 mFlinger->mPrimaryDispSync);
1179 if (updateResult == BufferQueue::PRESENT_LATER) {
1180 // Producer doesn't want buffer to be displayed yet. Signal a
1181 // layer update so we check again at the next opportunity.
1182 mFlinger->signalLayerUpdate();
1183 return outDirtyRegion;
1184 }
1185
1186 // Decrement the queued-frames count. Signal another event if we
1187 // have more frames pending.
1188 if (android_atomic_dec(&mQueuedFrames) > 1) {
1189 mFlinger->signalLayerUpdate();
1190 }
1191
1192 if (updateResult != NO_ERROR) {
1193 // something happened!
1194 recomputeVisibleRegions = true;
1195 return outDirtyRegion;
1196 }
1197
1198 // update the active buffer
1199 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1200 if (mActiveBuffer == NULL) {
1201 // this can only happen if the very first buffer was rejected.
1202 return outDirtyRegion;
1203 }
1204
1205 mRefreshPending = true;
1206 mFrameLatencyNeeded = true;
1207 if (oldActiveBuffer == NULL) {
1208 // the first time we receive a buffer, we need to trigger a
1209 // geometry invalidation.
1210 recomputeVisibleRegions = true;
1211 }
1212
1213 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1214 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1215 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1216 if ((crop != mCurrentCrop) ||
1217 (transform != mCurrentTransform) ||
1218 (scalingMode != mCurrentScalingMode))
1219 {
1220 mCurrentCrop = crop;
1221 mCurrentTransform = transform;
1222 mCurrentScalingMode = scalingMode;
1223 recomputeVisibleRegions = true;
1224 }
1225
1226 if (oldActiveBuffer != NULL) {
1227 uint32_t bufWidth = mActiveBuffer->getWidth();
1228 uint32_t bufHeight = mActiveBuffer->getHeight();
1229 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1230 bufHeight != uint32_t(oldActiveBuffer->height)) {
1231 recomputeVisibleRegions = true;
1232 }
1233 }
1234
1235 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1236 if (oldOpacity != isOpaque(s)) {
1237 recomputeVisibleRegions = true;
1238 }
1239
1240 // FIXME: postedRegion should be dirty & bounds
1241 Region dirtyRegion(Rect(s.active.w, s.active.h));
1242
1243 // transform the dirty region to window-manager space
1244 outDirtyRegion = (s.transform.transform(dirtyRegion));
1245 }
1246 return outDirtyRegion;
1247 }
1248
getEffectiveUsage(uint32_t usage) const1249 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1250 {
1251 // TODO: should we do something special if mSecure is set?
1252 if (mProtectedByApp) {
1253 // need a hardware-protected path to external video sink
1254 usage |= GraphicBuffer::USAGE_PROTECTED;
1255 }
1256 if (mPotentialCursor) {
1257 usage |= GraphicBuffer::USAGE_CURSOR;
1258 }
1259 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1260 return usage;
1261 }
1262
updateTransformHint(const sp<const DisplayDevice> & hw) const1263 void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
1264 uint32_t orientation = 0;
1265 if (!mFlinger->mDebugDisableTransformHint) {
1266 // The transform hint is used to improve performance, but we can
1267 // only have a single transform hint, it cannot
1268 // apply to all displays.
1269 const Transform& planeTransform(hw->getTransform());
1270 orientation = planeTransform.getOrientation();
1271 if (orientation & Transform::ROT_INVALID) {
1272 orientation = 0;
1273 }
1274 }
1275 mSurfaceFlingerConsumer->setTransformHint(orientation);
1276 }
1277
1278 // ----------------------------------------------------------------------------
1279 // debugging
1280 // ----------------------------------------------------------------------------
1281
dump(String8 & result,Colorizer & colorizer) const1282 void Layer::dump(String8& result, Colorizer& colorizer) const
1283 {
1284 const Layer::State& s(getDrawingState());
1285
1286 colorizer.colorize(result, Colorizer::GREEN);
1287 result.appendFormat(
1288 "+ %s %p (%s)\n",
1289 getTypeId(), this, getName().string());
1290 colorizer.reset(result);
1291
1292 s.activeTransparentRegion.dump(result, "transparentRegion");
1293 visibleRegion.dump(result, "visibleRegion");
1294 sp<Client> client(mClientRef.promote());
1295
1296 result.appendFormat( " "
1297 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1298 "isOpaque=%1d, invalidate=%1d, "
1299 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1300 " client=%p\n",
1301 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1302 s.active.crop.left, s.active.crop.top,
1303 s.active.crop.right, s.active.crop.bottom,
1304 isOpaque(s), contentDirty,
1305 s.alpha, s.flags,
1306 s.transform[0][0], s.transform[0][1],
1307 s.transform[1][0], s.transform[1][1],
1308 client.get());
1309
1310 sp<const GraphicBuffer> buf0(mActiveBuffer);
1311 uint32_t w0=0, h0=0, s0=0, f0=0;
1312 if (buf0 != 0) {
1313 w0 = buf0->getWidth();
1314 h0 = buf0->getHeight();
1315 s0 = buf0->getStride();
1316 f0 = buf0->format;
1317 }
1318 result.appendFormat(
1319 " "
1320 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1321 " queued-frames=%d, mRefreshPending=%d\n",
1322 mFormat, w0, h0, s0,f0,
1323 mQueuedFrames, mRefreshPending);
1324
1325 if (mSurfaceFlingerConsumer != 0) {
1326 mSurfaceFlingerConsumer->dump(result, " ");
1327 }
1328 }
1329
dumpFrameStats(String8 & result) const1330 void Layer::dumpFrameStats(String8& result) const {
1331 mFrameTracker.dumpStats(result);
1332 }
1333
clearFrameStats()1334 void Layer::clearFrameStats() {
1335 mFrameTracker.clearStats();
1336 }
1337
logFrameStats()1338 void Layer::logFrameStats() {
1339 mFrameTracker.logAndResetStats(mName);
1340 }
1341
getFrameStats(FrameStats * outStats) const1342 void Layer::getFrameStats(FrameStats* outStats) const {
1343 mFrameTracker.getStats(outStats);
1344 }
1345
1346 // ---------------------------------------------------------------------------
1347
LayerCleaner(const sp<SurfaceFlinger> & flinger,const sp<Layer> & layer)1348 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1349 const sp<Layer>& layer)
1350 : mFlinger(flinger), mLayer(layer) {
1351 }
1352
~LayerCleaner()1353 Layer::LayerCleaner::~LayerCleaner() {
1354 // destroy client resources
1355 mFlinger->onLayerDestroyed(mLayer);
1356 }
1357
1358 // ---------------------------------------------------------------------------
1359 }; // namespace android
1360
1361 #if defined(__gl_h_)
1362 #error "don't include gl/gl.h in this file"
1363 #endif
1364
1365 #if defined(__gl2_h_)
1366 #error "don't include gl2/gl2.h in this file"
1367 #endif
1368