2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
21 #include <sys/types.h>
24 #include <cutils/compiler.h>
25 #include <cutils/native_handle.h>
26 #include <cutils/properties.h>
28 #include <utils/Errors.h>
29 #include <utils/Log.h>
30 #include <utils/StopWatch.h>
31 #include <utils/Trace.h>
33 #include <ui/GraphicBuffer.h>
34 #include <ui/PixelFormat.h>
36 #include <gui/Surface.h>
39 #include "Colorizer.h"
40 #include "DisplayDevice.h"
42 #include "SurfaceFlinger.h"
43 #include "SurfaceTextureLayer.h"
45 #include "DisplayHardware/HWComposer.h"
47 #include "RenderEngine/RenderEngine.h"
49 #define DEBUG_RESIZE 0
53 // ---------------------------------------------------------------------------
55 int32_t Layer::sSequence = 1;
57 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
58 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
59 : contentDirty(false),
60 sequence(uint32_t(android_atomic_inc(&sSequence))),
63 mPremultipliedAlpha(true),
66 mFormat(PIXEL_FORMAT_NONE),
71 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
72 mCurrentOpacity(true),
73 mRefreshPending(false),
74 mFrameLatencyNeeded(false),
76 mNeedsFiltering(false),
77 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79 mProtectedByApp(false),
83 mCurrentCrop.makeInvalid();
84 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
85 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
87 uint32_t layerFlags = 0;
88 if (flags & ISurfaceComposerClient::eHidden)
89 layerFlags = layer_state_t::eLayerHidden;
91 if (flags & ISurfaceComposerClient::eNonPremultiplied)
92 mPremultipliedAlpha = false;
96 mCurrentState.active.w = w;
97 mCurrentState.active.h = h;
98 mCurrentState.active.crop.makeInvalid();
100 mCurrentState.alpha = 0xFF;
101 mCurrentState.layerStack = 0;
102 mCurrentState.flags = layerFlags;
103 mCurrentState.sequence = 0;
104 mCurrentState.transform.set(0, 0);
105 mCurrentState.requested = mCurrentState.active;
107 // drawing state & current state are identical
108 mDrawingState = mCurrentState;
110 nsecs_t displayPeriod =
111 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
112 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
115 void Layer::onFirstRef() {
116 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
117 mBufferQueue = new SurfaceTextureLayer(mFlinger);
118 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
119 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
120 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
121 mSurfaceFlingerConsumer->setName(mName);
123 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
124 #warning "disabling triple buffering"
125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
127 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
130 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
131 updateTransformHint(hw);
135 sp<Client> c(mClientRef.promote());
137 c->detachLayer(this);
139 mFlinger->deleteTextureAsync(mTextureName);
140 mFrameTracker.logAndResetStats(mName);
143 // ---------------------------------------------------------------------------
145 // ---------------------------------------------------------------------------
147 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
148 HWComposer::HWCLayerInterface* layer) {
150 layer->onDisplayed();
151 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
155 void Layer::onFrameAvailable() {
156 android_atomic_inc(&mQueuedFrames);
157 mFlinger->signalLayerUpdate();
160 // called with SurfaceFlinger::mStateLock from the drawing thread after
161 // the layer has been remove from the current state list (and just before
162 // it's removed from the drawing state list)
163 void Layer::onRemoved() {
164 mSurfaceFlingerConsumer->abandon();
167 // ---------------------------------------------------------------------------
169 // ---------------------------------------------------------------------------
171 const String8& Layer::getName() const {
175 status_t Layer::setBuffers( uint32_t w, uint32_t h,
176 PixelFormat format, uint32_t flags)
178 uint32_t const maxSurfaceDims = min(
179 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
181 // never allow a surface larger than what our underlying GL implementation
183 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
184 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
190 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
191 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
192 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
193 mCurrentOpacity = getOpacityForFormat(format);
195 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
196 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
197 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
202 sp<IBinder> Layer::getHandle() {
203 Mutex::Autolock _l(mLock);
205 LOG_ALWAYS_FATAL_IF(mHasSurface,
206 "Layer::getHandle() has already been called");
211 * The layer handle is just a BBinder object passed to the client
212 * (remote process) -- we don't keep any reference on our side such that
213 * the dtor is called when the remote side let go of its reference.
215 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
216 * this layer when the handle is destroyed.
219 class Handle : public BBinder, public LayerCleaner {
220 wp<const Layer> mOwner;
222 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
223 : LayerCleaner(flinger, layer), mOwner(layer) {
227 return new Handle(mFlinger, this);
230 sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
234 // ---------------------------------------------------------------------------
235 // h/w composer set-up
236 // ---------------------------------------------------------------------------
238 Rect Layer::getContentCrop() const {
239 // this is the crop rectangle that applies to the buffer
240 // itself (as opposed to the window)
242 if (!mCurrentCrop.isEmpty()) {
243 // if the buffer crop is defined, we use that
245 } else if (mActiveBuffer != NULL) {
246 // otherwise we use the whole buffer
247 crop = mActiveBuffer->getBounds();
249 // if we don't have a buffer yet, we use an empty/invalid crop
255 static Rect reduce(const Rect& win, const Region& exclude) {
256 if (CC_LIKELY(exclude.isEmpty())) {
259 if (exclude.isRect()) {
260 return win.reduce(exclude.getBounds());
262 return Region(win).subtract(exclude).getBounds();
265 Rect Layer::computeBounds() const {
266 const Layer::State& s(getDrawingState());
267 Rect win(s.active.w, s.active.h);
268 if (!s.active.crop.isEmpty()) {
269 win.intersect(s.active.crop, &win);
271 // subtract the transparent region and snap to the bounds
272 return reduce(win, s.activeTransparentRegion);
275 FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
276 // the content crop is the area of the content that gets scaled to the
278 FloatRect crop(getContentCrop());
280 // the active.crop is the area of the window that gets cropped, but not
281 // scaled in any ways.
282 const State& s(getDrawingState());
284 // apply the projection's clipping to the window crop in
285 // layerstack space, and convert-back to layer space.
286 // if there are no window scaling involved, this operation will map to full
287 // pixels in the buffer.
288 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
289 // a viewport clipping and a window transform. we should use floating point to fix this.
290 Rect activeCrop(s.transform.transform(s.active.crop));
291 activeCrop.intersect(hw->getViewport(), &activeCrop);
292 activeCrop = s.transform.inverse().transform(activeCrop);
294 // paranoia: make sure the window-crop is constrained in the
296 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
298 // subtract the transparent region and snap to the bounds
299 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
301 if (!activeCrop.isEmpty()) {
302 // Transform the window crop to match the buffer coordinate system,
303 // which means using the inverse of the current transform set on the
304 // SurfaceFlingerConsumer.
305 uint32_t invTransform = mCurrentTransform;
306 int winWidth = s.active.w;
307 int winHeight = s.active.h;
308 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
309 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
310 NATIVE_WINDOW_TRANSFORM_FLIP_H;
311 winWidth = s.active.h;
312 winHeight = s.active.w;
314 const Rect winCrop = activeCrop.transform(
315 invTransform, s.active.w, s.active.h);
317 // below, crop is intersected with winCrop expressed in crop's coordinate space
318 float xScale = crop.getWidth() / float(winWidth);
319 float yScale = crop.getHeight() / float(winHeight);
321 float insetL = winCrop.left * xScale;
322 float insetT = winCrop.top * yScale;
323 float insetR = (winWidth - winCrop.right ) * xScale;
324 float insetB = (winHeight - winCrop.bottom) * yScale;
328 crop.right -= insetR;
329 crop.bottom -= insetB;
334 void Layer::setGeometry(
335 const sp<const DisplayDevice>& hw,
336 HWComposer::HWCLayerInterface& layer)
338 layer.setDefaultState();
341 layer.setSkip(false);
343 if (isSecure() && !hw->isSecure()) {
347 // this gives us only the "orientation" component of the transform
348 const State& s(getDrawingState());
349 if (!isOpaque() || s.alpha != 0xFF) {
350 layer.setBlending(mPremultipliedAlpha ?
351 HWC_BLENDING_PREMULT :
352 HWC_BLENDING_COVERAGE);
355 // apply the layer's transform, followed by the display's global transform
356 // here we're guaranteed that the layer's transform preserves rects
357 Rect frame(s.transform.transform(computeBounds()));
358 frame.intersect(hw->getViewport(), &frame);
359 const Transform& tr(hw->getTransform());
360 layer.setFrame(tr.transform(frame));
361 layer.setCrop(computeCrop(hw));
362 layer.setPlaneAlpha(s.alpha);
365 * Transformations are applied in this order:
366 * 1) buffer orientation/flip/mirror
367 * 2) state transformation (window manager)
368 * 3) layer orientation (screen orientation)
369 * (NOTE: the matrices are multiplied in reverse order)
372 const Transform bufferOrientation(mCurrentTransform);
373 const Transform transform(tr * s.transform * bufferOrientation);
375 // this gives us only the "orientation" component of the transform
376 const uint32_t orientation = transform.getOrientation();
377 if (orientation & Transform::ROT_INVALID) {
378 // we can only handle simple transformation
381 layer.setTransform(orientation);
385 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
386 HWComposer::HWCLayerInterface& layer) {
387 // we have to set the visible region on every frame because
388 // we currently free it during onLayerDisplayed(), which is called
389 // after HWComposer::commit() -- every frame.
390 // Apply this display's projection's viewport to the visible region
391 // before giving it to the HWC HAL.
392 const Transform& tr = hw->getTransform();
393 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
394 layer.setVisibleRegionScreen(visible);
396 // NOTE: buffer can be NULL if the client never drew into this
397 // layer yet, or if we ran out of memory
398 layer.setBuffer(mActiveBuffer);
401 void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
402 HWComposer::HWCLayerInterface& layer) {
405 // TODO: there is a possible optimization here: we only need to set the
406 // acquire fence the first time a new buffer is acquired on EACH display.
408 if (layer.getCompositionType() == HWC_OVERLAY) {
409 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
410 if (fence->isValid()) {
411 fenceFd = fence->dup();
413 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
417 layer.setAcquireFenceFd(fenceFd);
420 // ---------------------------------------------------------------------------
422 // ---------------------------------------------------------------------------
424 void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
428 void Layer::draw(const sp<const DisplayDevice>& hw) {
429 onDraw( hw, Region(hw->bounds()) );
432 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
436 if (CC_UNLIKELY(mActiveBuffer == 0)) {
437 // the texture has not been created yet, this Layer has
438 // in fact never been drawn into. This happens frequently with
439 // SurfaceView because the WindowManager can't know when the client
440 // has drawn the first time.
442 // If there is nothing under us, we paint the screen in black, otherwise
443 // we just skip this update.
445 // figure out if there is something below us
447 const SurfaceFlinger::LayerVector& drawingLayers(
448 mFlinger->mDrawingState.layersSortedByZ);
449 const size_t count = drawingLayers.size();
450 for (size_t i=0 ; i<count ; ++i) {
451 const sp<Layer>& layer(drawingLayers[i]);
452 if (layer.get() == static_cast<Layer const*>(this))
454 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
456 // if not everything below us is covered, we plug the holes!
457 Region holes(clip.subtract(under));
458 if (!holes.isEmpty()) {
459 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
464 // Bind the current buffer to the GL texture, and wait for it to be
465 // ready for us to draw into.
466 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
467 if (err != NO_ERROR) {
468 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
469 // Go ahead and draw the buffer anyway; no matter what we do the screen
470 // is probably going to have something visibly wrong.
473 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
475 RenderEngine& engine(mFlinger->getRenderEngine());
477 if (!blackOutLayer) {
478 // TODO: we could be more subtle with isFixedSize()
479 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
481 // Query the texture matrix given our current filtering mode.
482 float textureMatrix[16];
483 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
484 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
486 // Set things up for texturing.
487 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
488 mTexture.setFiltering(useFiltering);
489 mTexture.setMatrix(textureMatrix);
491 engine.setupLayerTexturing(mTexture);
493 engine.setupLayerBlackedOut();
495 drawWithOpenGL(hw, clip);
496 engine.disableTexturing();
500 void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
501 float red, float green, float blue, float alpha) const
503 computeGeometry(hw, mMesh);
504 mFlinger->getRenderEngine().fillWithColor(mMesh, red, green, blue, alpha);
507 void Layer::clearWithOpenGL(
508 const sp<const DisplayDevice>& hw, const Region& clip) const {
509 clearWithOpenGL(hw, clip, 0,0,0,0);
512 void Layer::drawWithOpenGL(
513 const sp<const DisplayDevice>& hw, const Region& clip) const {
514 const uint32_t fbHeight = hw->getHeight();
515 const State& s(getDrawingState());
517 computeGeometry(hw, mMesh);
520 * NOTE: the way we compute the texture coordinates here produces
521 * different results than when we take the HWC path -- in the later case
522 * the "source crop" is rounded to texel boundaries.
523 * This can produce significantly different results when the texture
524 * is scaled by a large amount.
526 * The GL code below is more logical (imho), and the difference with
527 * HWC is due to a limitation of the HWC API to integers -- a question
528 * is suspend is wether we should ignore this problem or revert to
529 * GL composition when a buffer scaling is applied (maybe with some
530 * minimal value)? Or, we could make GL behave like HWC -- but this feel
531 * like more of a hack.
533 const Rect win(computeBounds());
535 float left = float(win.left) / float(s.active.w);
536 float top = float(win.top) / float(s.active.h);
537 float right = float(win.right) / float(s.active.w);
538 float bottom = float(win.bottom) / float(s.active.h);
540 // TODO: we probably want to generate the texture coords with the mesh
541 // here we assume that we only have 4 vertices
542 Mesh::VertexArray texCoords(mMesh.getTexCoordArray());
543 texCoords[0].s = left;
544 texCoords[0].t = 1.0f - top;
545 texCoords[1].s = left;
546 texCoords[1].t = 1.0f - bottom;
547 texCoords[2].s = right;
548 texCoords[2].t = 1.0f - bottom;
549 texCoords[3].s = right;
550 texCoords[3].t = 1.0f - top;
552 RenderEngine& engine(mFlinger->getRenderEngine());
553 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
554 engine.drawMesh(mMesh);
555 engine.disableBlending();
558 void Layer::setFiltering(bool filtering) {
559 mFiltering = filtering;
562 bool Layer::getFiltering() const {
566 // As documented in libhardware header, formats in the range
567 // 0x100 - 0x1FF are specific to the HAL implementation, and
568 // are known to have no alpha channel
569 // TODO: move definition for device-specific range into
570 // hardware.h, instead of using hard-coded values here.
571 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
573 bool Layer::getOpacityForFormat(uint32_t format) {
574 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
578 case HAL_PIXEL_FORMAT_RGBA_8888:
579 case HAL_PIXEL_FORMAT_BGRA_8888:
580 case HAL_PIXEL_FORMAT_sRGB_A_8888:
583 // in all other case, we have no blending (also for unknown formats)
587 // ----------------------------------------------------------------------------
589 // ----------------------------------------------------------------------------
591 void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
593 const Layer::State& s(getDrawingState());
594 const Transform tr(hw->getTransform() * s.transform);
595 const uint32_t hw_h = hw->getHeight();
596 Rect win(s.active.w, s.active.h);
597 if (!s.active.crop.isEmpty()) {
598 win.intersect(s.active.crop, &win);
600 // subtract the transparent region and snap to the bounds
601 win = reduce(win, s.activeTransparentRegion);
603 Mesh::VertexArray position(mesh.getPositionArray());
604 tr.transform(position[0], win.left, win.top);
605 tr.transform(position[1], win.left, win.bottom);
606 tr.transform(position[2], win.right, win.bottom);
607 tr.transform(position[3], win.right, win.top);
608 for (size_t i=0 ; i<4 ; i++) {
609 position[i].y = hw_h - position[i].y;
613 bool Layer::isOpaque() const
615 // if we don't have a buffer yet, we're translucent regardless of the
616 // layer's opaque flag.
617 if (mActiveBuffer == 0) {
621 // if the layer has the opaque flag, then we're always opaque,
622 // otherwise we use the current buffer's format.
623 return mOpaqueLayer || mCurrentOpacity;
626 bool Layer::isProtected() const
628 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
629 return (activeBuffer != 0) &&
630 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
633 bool Layer::isFixedSize() const {
634 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
637 bool Layer::isCropped() const {
638 return !mCurrentCrop.isEmpty();
641 bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
642 return mNeedsFiltering || hw->needsFiltering();
645 void Layer::setVisibleRegion(const Region& visibleRegion) {
646 // always called from main thread
647 this->visibleRegion = visibleRegion;
650 void Layer::setCoveredRegion(const Region& coveredRegion) {
651 // always called from main thread
652 this->coveredRegion = coveredRegion;
655 void Layer::setVisibleNonTransparentRegion(const Region&
656 setVisibleNonTransparentRegion) {
657 // always called from main thread
658 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
661 // ----------------------------------------------------------------------------
663 // ----------------------------------------------------------------------------
665 uint32_t Layer::doTransaction(uint32_t flags) {
668 const Layer::State& s(getDrawingState());
669 const Layer::State& c(getCurrentState());
671 const bool sizeChanged = (c.requested.w != s.requested.w) ||
672 (c.requested.h != s.requested.h);
675 // the size changed, we need to ask our client to request a new buffer
676 ALOGD_IF(DEBUG_RESIZE,
677 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
678 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
679 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
680 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
681 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
682 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
683 c.active.w, c.active.h,
687 c.active.crop.bottom,
688 c.active.crop.getWidth(),
689 c.active.crop.getHeight(),
690 c.requested.w, c.requested.h,
691 c.requested.crop.left,
692 c.requested.crop.top,
693 c.requested.crop.right,
694 c.requested.crop.bottom,
695 c.requested.crop.getWidth(),
696 c.requested.crop.getHeight(),
697 s.active.w, s.active.h,
701 s.active.crop.bottom,
702 s.active.crop.getWidth(),
703 s.active.crop.getHeight(),
704 s.requested.w, s.requested.h,
705 s.requested.crop.left,
706 s.requested.crop.top,
707 s.requested.crop.right,
708 s.requested.crop.bottom,
709 s.requested.crop.getWidth(),
710 s.requested.crop.getHeight());
712 // record the new size, form this point on, when the client request
713 // a buffer, it'll get the new size.
714 mSurfaceFlingerConsumer->setDefaultBufferSize(
715 c.requested.w, c.requested.h);
718 if (!isFixedSize()) {
720 const bool resizePending = (c.requested.w != c.active.w) ||
721 (c.requested.h != c.active.h);
724 // don't let Layer::doTransaction update the drawing state
725 // if we have a pending resize, unless we are in fixed-size mode.
726 // the drawing state will be updated only once we receive a buffer
727 // with the correct size.
729 // in particular, we want to make sure the clip (which is part
730 // of the geometry state) is latched together with the size but is
731 // latched immediately when no resizing is involved.
733 flags |= eDontUpdateGeometryState;
737 // always set active to requested, unless we're asked not to
738 // this is used by Layer, which special cases resizes.
739 if (flags & eDontUpdateGeometryState) {
741 Layer::State& editCurrentState(getCurrentState());
742 editCurrentState.active = c.requested;
745 if (s.active != c.active) {
746 // invalidate and recompute the visible regions if needed
747 flags |= Layer::eVisibleRegion;
750 if (c.sequence != s.sequence) {
751 // invalidate and recompute the visible regions if needed
752 flags |= eVisibleRegion;
753 this->contentDirty = true;
755 // we may use linear filtering, if the matrix scales us
756 const uint8_t type = c.transform.getType();
757 mNeedsFiltering = (!c.transform.preserveRects() ||
758 (type >= Transform::SCALE));
761 // Commit the transaction
766 void Layer::commitTransaction() {
767 mDrawingState = mCurrentState;
770 uint32_t Layer::getTransactionFlags(uint32_t flags) {
771 return android_atomic_and(~flags, &mTransactionFlags) & flags;
774 uint32_t Layer::setTransactionFlags(uint32_t flags) {
775 return android_atomic_or(flags, &mTransactionFlags);
778 bool Layer::setPosition(float x, float y) {
779 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
781 mCurrentState.sequence++;
782 mCurrentState.transform.set(x, y);
783 setTransactionFlags(eTransactionNeeded);
786 bool Layer::setLayer(uint32_t z) {
787 if (mCurrentState.z == z)
789 mCurrentState.sequence++;
791 setTransactionFlags(eTransactionNeeded);
794 bool Layer::setSize(uint32_t w, uint32_t h) {
795 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
797 mCurrentState.requested.w = w;
798 mCurrentState.requested.h = h;
799 setTransactionFlags(eTransactionNeeded);
802 bool Layer::setAlpha(uint8_t alpha) {
803 if (mCurrentState.alpha == alpha)
805 mCurrentState.sequence++;
806 mCurrentState.alpha = alpha;
807 setTransactionFlags(eTransactionNeeded);
810 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
811 mCurrentState.sequence++;
812 mCurrentState.transform.set(
813 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
814 setTransactionFlags(eTransactionNeeded);
817 bool Layer::setTransparentRegionHint(const Region& transparent) {
818 mCurrentState.requestedTransparentRegion = transparent;
819 setTransactionFlags(eTransactionNeeded);
822 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
823 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
824 if (mCurrentState.flags == newFlags)
826 mCurrentState.sequence++;
827 mCurrentState.flags = newFlags;
828 setTransactionFlags(eTransactionNeeded);
831 bool Layer::setCrop(const Rect& crop) {
832 if (mCurrentState.requested.crop == crop)
834 mCurrentState.sequence++;
835 mCurrentState.requested.crop = crop;
836 setTransactionFlags(eTransactionNeeded);
840 bool Layer::setLayerStack(uint32_t layerStack) {
841 if (mCurrentState.layerStack == layerStack)
843 mCurrentState.sequence++;
844 mCurrentState.layerStack = layerStack;
845 setTransactionFlags(eTransactionNeeded);
849 // ----------------------------------------------------------------------------
850 // pageflip handling...
851 // ----------------------------------------------------------------------------
853 bool Layer::onPreComposition() {
854 mRefreshPending = false;
855 return mQueuedFrames > 0;
858 void Layer::onPostComposition() {
859 if (mFrameLatencyNeeded) {
860 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
861 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
863 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
864 if (frameReadyFence->isValid()) {
865 mFrameTracker.setFrameReadyFence(frameReadyFence);
867 // There was no fence for this frame, so assume that it was ready
868 // to be presented at the desired present time.
869 mFrameTracker.setFrameReadyTime(desiredPresentTime);
872 const HWComposer& hwc = mFlinger->getHwComposer();
873 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
874 if (presentFence->isValid()) {
875 mFrameTracker.setActualPresentFence(presentFence);
877 // The HWC doesn't support present fences, so use the refresh
878 // timestamp instead.
879 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
880 mFrameTracker.setActualPresentTime(presentTime);
883 mFrameTracker.advanceFrame();
884 mFrameLatencyNeeded = false;
888 bool Layer::isVisible() const {
889 const Layer::State& s(mDrawingState);
890 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
891 && (mActiveBuffer != NULL);
894 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
898 Region outDirtyRegion;
899 if (mQueuedFrames > 0) {
901 // if we've already called updateTexImage() without going through
902 // a composition step, we have to skip this layer at this point
903 // because we cannot call updateTeximage() without a corresponding
904 // compositionComplete() call.
905 // we'll trigger an update in onPreComposition().
906 if (mRefreshPending) {
907 return outDirtyRegion;
910 // Capture the old state of the layer for comparisons later
911 const bool oldOpacity = isOpaque();
912 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
914 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
916 Layer::State& current;
917 bool& recomputeVisibleRegions;
918 Reject(Layer::State& front, Layer::State& current,
919 bool& recomputeVisibleRegions)
920 : front(front), current(current),
921 recomputeVisibleRegions(recomputeVisibleRegions) {
924 virtual bool reject(const sp<GraphicBuffer>& buf,
925 const IGraphicBufferConsumer::BufferItem& item) {
930 uint32_t bufWidth = buf->getWidth();
931 uint32_t bufHeight = buf->getHeight();
933 // check that we received a buffer of the right size
934 // (Take the buffer's orientation into account)
935 if (item.mTransform & Transform::ROT_90) {
936 swap(bufWidth, bufHeight);
939 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
940 if (front.active != front.requested) {
943 (bufWidth == front.requested.w &&
944 bufHeight == front.requested.h))
946 // Here we pretend the transaction happened by updating the
947 // current and drawing states. Drawing state is only accessed
948 // in this thread, no need to have it locked
949 front.active = front.requested;
951 // We also need to update the current state so that
952 // we don't end-up overwriting the drawing state with
953 // this stale current state during the next transaction
955 // NOTE: We don't need to hold the transaction lock here
956 // because State::active is only accessed from this thread.
957 current.active = front.active;
959 // recompute visible region
960 recomputeVisibleRegions = true;
963 ALOGD_IF(DEBUG_RESIZE,
964 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
965 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
966 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
967 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
968 front.active.w, front.active.h,
969 front.active.crop.left,
970 front.active.crop.top,
971 front.active.crop.right,
972 front.active.crop.bottom,
973 front.active.crop.getWidth(),
974 front.active.crop.getHeight(),
975 front.requested.w, front.requested.h,
976 front.requested.crop.left,
977 front.requested.crop.top,
978 front.requested.crop.right,
979 front.requested.crop.bottom,
980 front.requested.crop.getWidth(),
981 front.requested.crop.getHeight());
985 if (front.active.w != bufWidth ||
986 front.active.h != bufHeight) {
987 // reject this buffer
992 // if the transparent region has changed (this test is
993 // conservative, but that's fine, worst case we're doing
994 // a bit of extra work), we latch the new one and we
995 // trigger a visible-region recompute.
996 if (!front.activeTransparentRegion.isTriviallyEqual(
997 front.requestedTransparentRegion)) {
998 front.activeTransparentRegion = front.requestedTransparentRegion;
1000 // We also need to update the current state so that
1001 // we don't end-up overwriting the drawing state with
1002 // this stale current state during the next transaction
1004 // NOTE: We don't need to hold the transaction lock here
1005 // because State::active is only accessed from this thread.
1006 current.activeTransparentRegion = front.activeTransparentRegion;
1008 // recompute visible region
1009 recomputeVisibleRegions = true;
1017 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
1019 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1020 if (updateResult == BufferQueue::PRESENT_LATER) {
1021 // Producer doesn't want buffer to be displayed yet. Signal a
1022 // layer update so we check again at the next opportunity.
1023 mFlinger->signalLayerUpdate();
1024 return outDirtyRegion;
1027 // Decrement the queued-frames count. Signal another event if we
1028 // have more frames pending.
1029 if (android_atomic_dec(&mQueuedFrames) > 1) {
1030 mFlinger->signalLayerUpdate();
1033 if (updateResult != NO_ERROR) {
1034 // something happened!
1035 recomputeVisibleRegions = true;
1036 return outDirtyRegion;
1039 // update the active buffer
1040 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1041 if (mActiveBuffer == NULL) {
1042 // this can only happen if the very first buffer was rejected.
1043 return outDirtyRegion;
1046 mRefreshPending = true;
1047 mFrameLatencyNeeded = true;
1048 if (oldActiveBuffer == NULL) {
1049 // the first time we receive a buffer, we need to trigger a
1050 // geometry invalidation.
1051 recomputeVisibleRegions = true;
1054 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1055 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1056 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1057 if ((crop != mCurrentCrop) ||
1058 (transform != mCurrentTransform) ||
1059 (scalingMode != mCurrentScalingMode))
1061 mCurrentCrop = crop;
1062 mCurrentTransform = transform;
1063 mCurrentScalingMode = scalingMode;
1064 recomputeVisibleRegions = true;
1067 if (oldActiveBuffer != NULL) {
1068 uint32_t bufWidth = mActiveBuffer->getWidth();
1069 uint32_t bufHeight = mActiveBuffer->getHeight();
1070 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1071 bufHeight != uint32_t(oldActiveBuffer->height)) {
1072 recomputeVisibleRegions = true;
1076 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1077 if (oldOpacity != isOpaque()) {
1078 recomputeVisibleRegions = true;
1081 // FIXME: postedRegion should be dirty & bounds
1082 const Layer::State& s(getDrawingState());
1083 Region dirtyRegion(Rect(s.active.w, s.active.h));
1085 // transform the dirty region to window-manager space
1086 outDirtyRegion = (s.transform.transform(dirtyRegion));
1088 return outDirtyRegion;
1091 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1093 // TODO: should we do something special if mSecure is set?
1094 if (mProtectedByApp) {
1095 // need a hardware-protected path to external video sink
1096 usage |= GraphicBuffer::USAGE_PROTECTED;
1098 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1102 void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
1103 uint32_t orientation = 0;
1104 if (!mFlinger->mDebugDisableTransformHint) {
1105 // The transform hint is used to improve performance, but we can
1106 // only have a single transform hint, it cannot
1107 // apply to all displays.
1108 const Transform& planeTransform(hw->getTransform());
1109 orientation = planeTransform.getOrientation();
1110 if (orientation & Transform::ROT_INVALID) {
1114 mSurfaceFlingerConsumer->setTransformHint(orientation);
1117 // ----------------------------------------------------------------------------
1119 // ----------------------------------------------------------------------------
1121 void Layer::dump(String8& result, Colorizer& colorizer) const
1123 const Layer::State& s(getDrawingState());
1125 colorizer.colorize(result, Colorizer::GREEN);
1126 result.appendFormat(
1128 getTypeId(), this, getName().string());
1129 colorizer.reset(result);
1131 s.activeTransparentRegion.dump(result, "transparentRegion");
1132 visibleRegion.dump(result, "visibleRegion");
1133 sp<Client> client(mClientRef.promote());
1135 result.appendFormat( " "
1136 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1137 "isOpaque=%1d, invalidate=%1d, "
1138 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1140 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1141 s.active.crop.left, s.active.crop.top,
1142 s.active.crop.right, s.active.crop.bottom,
1143 isOpaque(), contentDirty,
1145 s.transform[0][0], s.transform[0][1],
1146 s.transform[1][0], s.transform[1][1],
1149 sp<const GraphicBuffer> buf0(mActiveBuffer);
1150 uint32_t w0=0, h0=0, s0=0, f0=0;
1152 w0 = buf0->getWidth();
1153 h0 = buf0->getHeight();
1154 s0 = buf0->getStride();
1157 result.appendFormat(
1159 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1160 " queued-frames=%d, mRefreshPending=%d\n",
1161 mFormat, w0, h0, s0,f0,
1162 mQueuedFrames, mRefreshPending);
1164 if (mSurfaceFlingerConsumer != 0) {
1165 mSurfaceFlingerConsumer->dump(result, " ");
1169 void Layer::dumpStats(String8& result) const {
1170 mFrameTracker.dump(result);
1173 void Layer::clearStats() {
1174 mFrameTracker.clear();
1177 void Layer::logFrameStats() {
1178 mFrameTracker.logAndResetStats(mName);
1181 // ---------------------------------------------------------------------------
1183 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1184 const sp<Layer>& layer)
1185 : mFlinger(flinger), mLayer(layer) {
1188 Layer::LayerCleaner::~LayerCleaner() {
1189 // destroy client resources
1190 mFlinger->onLayerDestroyed(mLayer);
1193 // ---------------------------------------------------------------------------
1194 }; // namespace android
1196 #if defined(__gl_h_)
1197 #error "don't include gl/gl.h in this file"
1200 #if defined(__gl2_h_)
1201 #error "don't include gl2/gl2.h in this file"