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"
41 #include "GLExtensions.h"
43 #include "SurfaceFlinger.h"
44 #include "SurfaceTextureLayer.h"
46 #include "DisplayHardware/HWComposer.h"
48 #define DEBUG_RESIZE 0
52 // ---------------------------------------------------------------------------
54 int32_t Layer::sSequence = 1;
56 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
57 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
58 : contentDirty(false),
59 sequence(uint32_t(android_atomic_inc(&sSequence))),
62 mPremultipliedAlpha(true),
65 mFormat(PIXEL_FORMAT_NONE),
66 mGLExtensions(GLExtensions::getInstance()),
71 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
72 mCurrentOpacity(true),
73 mRefreshPending(false),
74 mFrameLatencyNeeded(false),
76 mNeedsFiltering(false),
78 mProtectedByApp(false),
82 mCurrentCrop.makeInvalid();
83 glGenTextures(1, &mTextureName);
85 uint32_t layerFlags = 0;
86 if (flags & ISurfaceComposerClient::eHidden)
87 layerFlags = layer_state_t::eLayerHidden;
89 if (flags & ISurfaceComposerClient::eNonPremultiplied)
90 mPremultipliedAlpha = false;
94 mCurrentState.active.w = w;
95 mCurrentState.active.h = h;
96 mCurrentState.active.crop.makeInvalid();
98 mCurrentState.alpha = 0xFF;
99 mCurrentState.layerStack = 0;
100 mCurrentState.flags = layerFlags;
101 mCurrentState.sequence = 0;
102 mCurrentState.transform.set(0, 0);
103 mCurrentState.requested = mCurrentState.active;
105 // drawing state & current state are identical
106 mDrawingState = mCurrentState;
109 void Layer::onFirstRef()
111 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
112 sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
113 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
114 GL_TEXTURE_EXTERNAL_OES, false, bq);
116 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
118 mSurfaceFlingerConsumer->setSynchronousMode(true);
119 mSurfaceFlingerConsumer->setName(mName);
121 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
122 #warning "disabling triple buffering"
123 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
128 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
129 updateTransformHint(hw);
133 sp<Client> c(mClientRef.promote());
135 c->detachLayer(this);
137 mFlinger->deleteTextureAsync(mTextureName);
140 // ---------------------------------------------------------------------------
142 // ---------------------------------------------------------------------------
144 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
145 HWComposer::HWCLayerInterface* layer) {
147 layer->onDisplayed();
148 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
152 void Layer::onFrameAvailable() {
153 android_atomic_inc(&mQueuedFrames);
154 mFlinger->signalLayerUpdate();
157 // called with SurfaceFlinger::mStateLock from the drawing thread after
158 // the layer has been remove from the current state list (and just before
159 // it's removed from the drawing state list)
160 void Layer::onRemoved() {
161 mSurfaceFlingerConsumer->abandon();
164 // ---------------------------------------------------------------------------
166 // ---------------------------------------------------------------------------
168 String8 Layer::getName() const {
172 status_t Layer::setBuffers( uint32_t w, uint32_t h,
173 PixelFormat format, uint32_t flags)
175 // this surfaces pixel format
176 PixelFormatInfo info;
177 status_t err = getPixelFormatInfo(format, &info);
179 ALOGE("unsupported pixelformat %d", format);
183 uint32_t const maxSurfaceDims = min(
184 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
186 // never allow a surface larger than what our underlying GL implementation
188 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
189 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
195 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
196 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
197 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
198 mCurrentOpacity = getOpacityForFormat(format);
200 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
201 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
202 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
207 sp<IBinder> Layer::getHandle() {
208 Mutex::Autolock _l(mLock);
210 LOG_ALWAYS_FATAL_IF(mHasSurface,
211 "Layer::getHandle() has already been called");
216 * The layer handle is just a BBinder object passed to the client
217 * (remote process) -- we don't keep any reference on our side such that
218 * the dtor is called when the remote side let go of its reference.
220 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
221 * this layer when the handle is destroyed.
224 class Handle : public BBinder, public LayerCleaner {
225 wp<const Layer> mOwner;
227 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
228 : LayerCleaner(flinger, layer), mOwner(layer) {
232 return new Handle(mFlinger, this);
235 sp<BufferQueue> Layer::getBufferQueue() const {
236 return mSurfaceFlingerConsumer->getBufferQueue();
239 //virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
240 // sp<IGraphicBufferProducer> res;
241 // sp<const Layer> that( mOwner.promote() );
242 // if (that != NULL) {
243 // res = that->mSurfaceFlingerConsumer->getBufferQueue();
248 // ---------------------------------------------------------------------------
249 // h/w composer set-up
250 // ---------------------------------------------------------------------------
252 Rect Layer::getContentCrop() const {
253 // this is the crop rectangle that applies to the buffer
254 // itself (as opposed to the window)
256 if (!mCurrentCrop.isEmpty()) {
257 // if the buffer crop is defined, we use that
259 } else if (mActiveBuffer != NULL) {
260 // otherwise we use the whole buffer
261 crop = mActiveBuffer->getBounds();
263 // if we don't have a buffer yet, we use an empty/invalid crop
269 uint32_t Layer::getContentTransform() const {
270 return mCurrentTransform;
273 static Rect reduce(const Rect& win, const Region& exclude) {
274 if (CC_LIKELY(exclude.isEmpty())) {
277 if (exclude.isRect()) {
278 return win.reduce(exclude.getBounds());
280 return Region(win).subtract(exclude).getBounds();
283 Rect Layer::computeBounds() const {
284 const Layer::State& s(drawingState());
285 Rect win(s.active.w, s.active.h);
286 if (!s.active.crop.isEmpty()) {
287 win.intersect(s.active.crop, &win);
289 // subtract the transparent region and snap to the bounds
290 return reduce(win, s.activeTransparentRegion);
293 Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
295 * The way we compute the crop (aka. texture coordinates when we have a
296 * Layer) produces a different output from the GL code in
297 * drawWithOpenGL() due to HWC being limited to integers. The difference
298 * can be large if getContentTransform() contains a large scale factor.
299 * See comments in drawWithOpenGL() for more details.
302 // the content crop is the area of the content that gets scaled to the
304 Rect crop(getContentCrop());
306 // the active.crop is the area of the window that gets cropped, but not
307 // scaled in any ways.
308 const State& s(drawingState());
310 // apply the projection's clipping to the window crop in
311 // layerstack space, and convert-back to layer space.
312 // if there are no window scaling (or content scaling) involved,
313 // this operation will map to full pixels in the buffer.
314 // NOTE: should we revert to GL composition if a scaling is involved
315 // since it cannot be represented in the HWC API?
316 Rect activeCrop(s.transform.transform(s.active.crop));
317 activeCrop.intersect(hw->getViewport(), &activeCrop);
318 activeCrop = s.transform.inverse().transform(activeCrop);
320 // paranoia: make sure the window-crop is constrained in the
322 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
324 // subtract the transparent region and snap to the bounds
325 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
327 if (!activeCrop.isEmpty()) {
328 // Transform the window crop to match the buffer coordinate system,
329 // which means using the inverse of the current transform set on the
330 // SurfaceFlingerConsumer.
331 uint32_t invTransform = getContentTransform();
332 int winWidth = s.active.w;
333 int winHeight = s.active.h;
334 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
335 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
336 NATIVE_WINDOW_TRANSFORM_FLIP_H;
337 winWidth = s.active.h;
338 winHeight = s.active.w;
340 const Rect winCrop = activeCrop.transform(
341 invTransform, s.active.w, s.active.h);
343 // the code below essentially performs a scaled intersection
344 // of crop and winCrop
345 float xScale = float(crop.width()) / float(winWidth);
346 float yScale = float(crop.height()) / float(winHeight);
348 int insetL = int(ceilf( winCrop.left * xScale));
349 int insetT = int(ceilf( winCrop.top * yScale));
350 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
351 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
355 crop.right -= insetR;
356 crop.bottom -= insetB;
361 void Layer::setGeometry(
362 const sp<const DisplayDevice>& hw,
363 HWComposer::HWCLayerInterface& layer)
365 layer.setDefaultState();
368 layer.setSkip(false);
370 if (isSecure() && !hw->isSecure()) {
374 // this gives us only the "orientation" component of the transform
375 const State& s(drawingState());
376 if (!isOpaque() || s.alpha != 0xFF) {
377 layer.setBlending(mPremultipliedAlpha ?
378 HWC_BLENDING_PREMULT :
379 HWC_BLENDING_COVERAGE);
382 // apply the layer's transform, followed by the display's global transform
383 // here we're guaranteed that the layer's transform preserves rects
384 Rect frame(s.transform.transform(computeBounds()));
385 frame.intersect(hw->getViewport(), &frame);
386 const Transform& tr(hw->getTransform());
387 layer.setFrame(tr.transform(frame));
388 layer.setCrop(computeCrop(hw));
389 layer.setPlaneAlpha(s.alpha);
392 * Transformations are applied in this order:
393 * 1) buffer orientation/flip/mirror
394 * 2) state transformation (window manager)
395 * 3) layer orientation (screen orientation)
396 * (NOTE: the matrices are multiplied in reverse order)
399 const Transform bufferOrientation(mCurrentTransform);
400 const Transform transform(tr * s.transform * bufferOrientation);
402 // this gives us only the "orientation" component of the transform
403 const uint32_t orientation = transform.getOrientation();
404 if (orientation & Transform::ROT_INVALID) {
405 // we can only handle simple transformation
408 layer.setTransform(orientation);
412 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
413 HWComposer::HWCLayerInterface& layer) {
414 // we have to set the visible region on every frame because
415 // we currently free it during onLayerDisplayed(), which is called
416 // after HWComposer::commit() -- every frame.
417 // Apply this display's projection's viewport to the visible region
418 // before giving it to the HWC HAL.
419 const Transform& tr = hw->getTransform();
420 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
421 layer.setVisibleRegionScreen(visible);
423 // NOTE: buffer can be NULL if the client never drew into this
424 // layer yet, or if we ran out of memory
425 layer.setBuffer(mActiveBuffer);
428 void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
429 HWComposer::HWCLayerInterface& layer) {
432 // TODO: there is a possible optimization here: we only need to set the
433 // acquire fence the first time a new buffer is acquired on EACH display.
435 if (layer.getCompositionType() == HWC_OVERLAY) {
436 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
437 if (fence->isValid()) {
438 fenceFd = fence->dup();
440 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
444 layer.setAcquireFenceFd(fenceFd);
447 // ---------------------------------------------------------------------------
449 // ---------------------------------------------------------------------------
451 void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
455 void Layer::draw(const sp<const DisplayDevice>& hw) {
456 onDraw( hw, Region(hw->bounds()) );
459 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
463 if (CC_UNLIKELY(mActiveBuffer == 0)) {
464 // the texture has not been created yet, this Layer has
465 // in fact never been drawn into. This happens frequently with
466 // SurfaceView because the WindowManager can't know when the client
467 // has drawn the first time.
469 // If there is nothing under us, we paint the screen in black, otherwise
470 // we just skip this update.
472 // figure out if there is something below us
474 const SurfaceFlinger::LayerVector& drawingLayers(
475 mFlinger->mDrawingState.layersSortedByZ);
476 const size_t count = drawingLayers.size();
477 for (size_t i=0 ; i<count ; ++i) {
478 const sp<Layer>& layer(drawingLayers[i]);
479 if (layer.get() == static_cast<Layer const*>(this))
481 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
483 // if not everything below us is covered, we plug the holes!
484 Region holes(clip.subtract(under));
485 if (!holes.isEmpty()) {
486 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
491 // Bind the current buffer to the GL texture, and wait for it to be
492 // ready for us to draw into.
493 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
494 if (err != NO_ERROR) {
495 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
496 // Go ahead and draw the buffer anyway; no matter what we do the screen
497 // is probably going to have something visibly wrong.
500 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
502 if (!blackOutLayer) {
503 // TODO: we could be more subtle with isFixedSize()
504 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
506 // Query the texture matrix given our current filtering mode.
507 float textureMatrix[16];
508 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
509 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
511 // Set things up for texturing.
512 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
513 GLenum filter = GL_NEAREST;
517 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
518 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
519 glMatrixMode(GL_TEXTURE);
520 glLoadMatrixf(textureMatrix);
521 glMatrixMode(GL_MODELVIEW);
522 glDisable(GL_TEXTURE_2D);
523 glEnable(GL_TEXTURE_EXTERNAL_OES);
525 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
526 glMatrixMode(GL_TEXTURE);
528 glMatrixMode(GL_MODELVIEW);
529 glDisable(GL_TEXTURE_EXTERNAL_OES);
530 glEnable(GL_TEXTURE_2D);
533 drawWithOpenGL(hw, clip);
535 glDisable(GL_TEXTURE_EXTERNAL_OES);
536 glDisable(GL_TEXTURE_2D);
540 void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
541 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
543 const uint32_t fbHeight = hw->getHeight();
544 glColor4f(red,green,blue,alpha);
546 glDisable(GL_TEXTURE_EXTERNAL_OES);
547 glDisable(GL_TEXTURE_2D);
551 computeGeometry(hw, &mesh);
553 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
554 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
557 void Layer::clearWithOpenGL(
558 const sp<const DisplayDevice>& hw, const Region& clip) const {
559 clearWithOpenGL(hw, clip, 0,0,0,0);
562 static void setupOpenGL10(bool premultipliedAlpha, bool opaque, int alpha) {
563 // OpenGL ES 1.0 doesn't support texture combiners.
564 // This path doesn't properly handle opaque layers that have non-opaque
565 // alpha values. The alpha channel will be copied into the framebuffer or
566 // screenshot, so if the framebuffer or screenshot is blended on top of
567 // something else, whatever is below the window will incorrectly show
569 if (CC_UNLIKELY(alpha < 0xFF)) {
570 GLfloat floatAlpha = alpha * (1.0f / 255.0f);
571 if (premultipliedAlpha) {
572 glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
574 glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
576 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
578 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
582 static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) {
588 if (CC_UNLIKELY(alpha < 0xFF)) {
589 // Cv = premultiplied ? Cs*alpha : Cs
590 // Av = !opaque ? alpha*As : 1.0
591 combineRGB = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
592 combineAlpha = !opaque ? GL_MODULATE : GL_REPLACE;
593 src0Alpha = GL_CONSTANT;
594 envColor[0] = alpha * (1.0f / 255.0f);
597 // Av = opaque ? 1.0 : As
598 combineRGB = GL_REPLACE;
599 combineAlpha = GL_REPLACE;
600 src0Alpha = opaque ? GL_CONSTANT : GL_TEXTURE;
604 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
605 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB);
606 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
607 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
608 if (combineRGB == GL_MODULATE) {
609 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
610 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
612 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha);
613 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha);
614 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
615 if (combineAlpha == GL_MODULATE) {
616 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
617 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
619 if (combineRGB == GL_MODULATE || src0Alpha == GL_CONSTANT) {
620 envColor[1] = envColor[0];
621 envColor[2] = envColor[0];
622 envColor[3] = envColor[0];
623 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
627 void Layer::drawWithOpenGL(
628 const sp<const DisplayDevice>& hw, const Region& clip) const {
629 const uint32_t fbHeight = hw->getHeight();
630 const State& s(drawingState());
632 if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) {
633 setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha);
635 setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha);
638 if (s.alpha < 0xFF || !isOpaque()) {
640 glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
641 GL_ONE_MINUS_SRC_ALPHA);
647 computeGeometry(hw, &mesh);
649 // TODO: we probably want to generate the texture coords with the mesh
650 // here we assume that we only have 4 vertices
659 * NOTE: the way we compute the texture coordinates here produces
660 * different results than when we take the HWC path -- in the later case
661 * the "source crop" is rounded to texel boundaries.
662 * This can produce significantly different results when the texture
663 * is scaled by a large amount.
665 * The GL code below is more logical (imho), and the difference with
666 * HWC is due to a limitation of the HWC API to integers -- a question
667 * is suspend is wether we should ignore this problem or revert to
668 * GL composition when a buffer scaling is applied (maybe with some
669 * minimal value)? Or, we could make GL behave like HWC -- but this feel
670 * like more of a hack.
672 const Rect win(computeBounds());
674 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
675 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
676 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
677 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
679 TexCoords texCoords[4];
680 texCoords[0].u = left;
681 texCoords[0].v = top;
682 texCoords[1].u = left;
683 texCoords[1].v = bottom;
684 texCoords[2].u = right;
685 texCoords[2].v = bottom;
686 texCoords[3].u = right;
687 texCoords[3].v = top;
688 for (int i = 0; i < 4; i++) {
689 texCoords[i].v = 1.0f - texCoords[i].v;
692 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
693 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
694 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
695 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
697 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
701 void Layer::setFiltering(bool filtering) {
702 mFiltering = filtering;
705 bool Layer::getFiltering() const {
709 // As documented in libhardware header, formats in the range
710 // 0x100 - 0x1FF are specific to the HAL implementation, and
711 // are known to have no alpha channel
712 // TODO: move definition for device-specific range into
713 // hardware.h, instead of using hard-coded values here.
714 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
716 bool Layer::getOpacityForFormat(uint32_t format)
718 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
721 PixelFormatInfo info;
722 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
723 // in case of error (unknown format), we assume no blending
724 return (err || info.h_alpha <= info.l_alpha);
727 // ----------------------------------------------------------------------------
729 // ----------------------------------------------------------------------------
731 void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
733 const Layer::State& s(drawingState());
734 const Transform tr(hw->getTransform() * s.transform);
735 const uint32_t hw_h = hw->getHeight();
736 Rect win(s.active.w, s.active.h);
737 if (!s.active.crop.isEmpty()) {
738 win.intersect(s.active.crop, &win);
740 // subtract the transparent region and snap to the bounds
741 win = reduce(win, s.activeTransparentRegion);
743 tr.transform(mesh->mVertices[0], win.left, win.top);
744 tr.transform(mesh->mVertices[1], win.left, win.bottom);
745 tr.transform(mesh->mVertices[2], win.right, win.bottom);
746 tr.transform(mesh->mVertices[3], win.right, win.top);
747 for (size_t i=0 ; i<4 ; i++) {
748 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
753 bool Layer::isOpaque() const
755 // if we don't have a buffer yet, we're translucent regardless of the
756 // layer's opaque flag.
757 if (mActiveBuffer == 0) {
761 // if the layer has the opaque flag, then we're always opaque,
762 // otherwise we use the current buffer's format.
763 return mOpaqueLayer || mCurrentOpacity;
766 bool Layer::isProtected() const
768 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
769 return (activeBuffer != 0) &&
770 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
773 bool Layer::isFixedSize() const {
774 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
777 bool Layer::isCropped() const {
778 return !mCurrentCrop.isEmpty();
781 bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
782 return mNeedsFiltering || hw->needsFiltering();
785 void Layer::setVisibleRegion(const Region& visibleRegion) {
786 // always called from main thread
787 this->visibleRegion = visibleRegion;
790 void Layer::setCoveredRegion(const Region& coveredRegion) {
791 // always called from main thread
792 this->coveredRegion = coveredRegion;
795 void Layer::setVisibleNonTransparentRegion(const Region&
796 setVisibleNonTransparentRegion) {
797 // always called from main thread
798 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
801 // ----------------------------------------------------------------------------
803 // ----------------------------------------------------------------------------
805 uint32_t Layer::doTransaction(uint32_t flags) {
808 const Layer::State& front(drawingState());
809 const Layer::State& temp(currentState());
811 const bool sizeChanged = (temp.requested.w != front.requested.w) ||
812 (temp.requested.h != front.requested.h);
815 // the size changed, we need to ask our client to request a new buffer
816 ALOGD_IF(DEBUG_RESIZE,
817 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
818 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
819 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
820 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
821 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
822 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
823 temp.active.w, temp.active.h,
824 temp.active.crop.left,
825 temp.active.crop.top,
826 temp.active.crop.right,
827 temp.active.crop.bottom,
828 temp.active.crop.getWidth(),
829 temp.active.crop.getHeight(),
830 temp.requested.w, temp.requested.h,
831 temp.requested.crop.left,
832 temp.requested.crop.top,
833 temp.requested.crop.right,
834 temp.requested.crop.bottom,
835 temp.requested.crop.getWidth(),
836 temp.requested.crop.getHeight(),
837 front.active.w, front.active.h,
838 front.active.crop.left,
839 front.active.crop.top,
840 front.active.crop.right,
841 front.active.crop.bottom,
842 front.active.crop.getWidth(),
843 front.active.crop.getHeight(),
844 front.requested.w, front.requested.h,
845 front.requested.crop.left,
846 front.requested.crop.top,
847 front.requested.crop.right,
848 front.requested.crop.bottom,
849 front.requested.crop.getWidth(),
850 front.requested.crop.getHeight());
852 // record the new size, form this point on, when the client request
853 // a buffer, it'll get the new size.
854 mSurfaceFlingerConsumer->setDefaultBufferSize(
855 temp.requested.w, temp.requested.h);
858 if (!isFixedSize()) {
860 const bool resizePending = (temp.requested.w != temp.active.w) ||
861 (temp.requested.h != temp.active.h);
864 // don't let Layer::doTransaction update the drawing state
865 // if we have a pending resize, unless we are in fixed-size mode.
866 // the drawing state will be updated only once we receive a buffer
867 // with the correct size.
869 // in particular, we want to make sure the clip (which is part
870 // of the geometry state) is latched together with the size but is
871 // latched immediately when no resizing is involved.
873 flags |= eDontUpdateGeometryState;
877 // always set active to requested, unless we're asked not to
878 // this is used by Layer, which special cases resizes.
879 if (flags & eDontUpdateGeometryState) {
881 Layer::State& editTemp(currentState());
882 editTemp.active = temp.requested;
885 if (front.active != temp.active) {
886 // invalidate and recompute the visible regions if needed
887 flags |= Layer::eVisibleRegion;
890 if (temp.sequence != front.sequence) {
891 // invalidate and recompute the visible regions if needed
892 flags |= eVisibleRegion;
893 this->contentDirty = true;
895 // we may use linear filtering, if the matrix scales us
896 const uint8_t type = temp.transform.getType();
897 mNeedsFiltering = (!temp.transform.preserveRects() ||
898 (type >= Transform::SCALE));
901 // Commit the transaction
906 void Layer::commitTransaction() {
907 mDrawingState = mCurrentState;
910 uint32_t Layer::getTransactionFlags(uint32_t flags) {
911 return android_atomic_and(~flags, &mTransactionFlags) & flags;
914 uint32_t Layer::setTransactionFlags(uint32_t flags) {
915 return android_atomic_or(flags, &mTransactionFlags);
918 bool Layer::setPosition(float x, float y) {
919 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
921 mCurrentState.sequence++;
922 mCurrentState.transform.set(x, y);
923 setTransactionFlags(eTransactionNeeded);
926 bool Layer::setLayer(uint32_t z) {
927 if (mCurrentState.z == z)
929 mCurrentState.sequence++;
931 setTransactionFlags(eTransactionNeeded);
934 bool Layer::setSize(uint32_t w, uint32_t h) {
935 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
937 mCurrentState.requested.w = w;
938 mCurrentState.requested.h = h;
939 setTransactionFlags(eTransactionNeeded);
942 bool Layer::setAlpha(uint8_t alpha) {
943 if (mCurrentState.alpha == alpha)
945 mCurrentState.sequence++;
946 mCurrentState.alpha = alpha;
947 setTransactionFlags(eTransactionNeeded);
950 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
951 mCurrentState.sequence++;
952 mCurrentState.transform.set(
953 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
954 setTransactionFlags(eTransactionNeeded);
957 bool Layer::setTransparentRegionHint(const Region& transparent) {
958 mCurrentState.requestedTransparentRegion = transparent;
959 setTransactionFlags(eTransactionNeeded);
962 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
963 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
964 if (mCurrentState.flags == newFlags)
966 mCurrentState.sequence++;
967 mCurrentState.flags = newFlags;
968 setTransactionFlags(eTransactionNeeded);
971 bool Layer::setCrop(const Rect& crop) {
972 if (mCurrentState.requested.crop == crop)
974 mCurrentState.sequence++;
975 mCurrentState.requested.crop = crop;
976 setTransactionFlags(eTransactionNeeded);
980 bool Layer::setLayerStack(uint32_t layerStack) {
981 if (mCurrentState.layerStack == layerStack)
983 mCurrentState.sequence++;
984 mCurrentState.layerStack = layerStack;
985 setTransactionFlags(eTransactionNeeded);
989 // ----------------------------------------------------------------------------
990 // pageflip handling...
991 // ----------------------------------------------------------------------------
993 bool Layer::onPreComposition() {
994 mRefreshPending = false;
995 return mQueuedFrames > 0;
998 void Layer::onPostComposition() {
999 if (mFrameLatencyNeeded) {
1000 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
1001 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1003 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1004 if (frameReadyFence->isValid()) {
1005 mFrameTracker.setFrameReadyFence(frameReadyFence);
1007 // There was no fence for this frame, so assume that it was ready
1008 // to be presented at the desired present time.
1009 mFrameTracker.setFrameReadyTime(desiredPresentTime);
1012 const HWComposer& hwc = mFlinger->getHwComposer();
1013 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1014 if (presentFence->isValid()) {
1015 mFrameTracker.setActualPresentFence(presentFence);
1017 // The HWC doesn't support present fences, so use the refresh
1018 // timestamp instead.
1019 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
1020 mFrameTracker.setActualPresentTime(presentTime);
1023 mFrameTracker.advanceFrame();
1024 mFrameLatencyNeeded = false;
1028 bool Layer::isVisible() const {
1029 const Layer::State& s(mDrawingState);
1030 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1031 && (mActiveBuffer != NULL);
1034 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
1038 Region outDirtyRegion;
1039 if (mQueuedFrames > 0) {
1041 // if we've already called updateTexImage() without going through
1042 // a composition step, we have to skip this layer at this point
1043 // because we cannot call updateTeximage() without a corresponding
1044 // compositionComplete() call.
1045 // we'll trigger an update in onPreComposition().
1046 if (mRefreshPending) {
1047 return outDirtyRegion;
1050 // Capture the old state of the layer for comparisons later
1051 const bool oldOpacity = isOpaque();
1052 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1054 // signal another event if we have more frames pending
1055 if (android_atomic_dec(&mQueuedFrames) > 1) {
1056 mFlinger->signalLayerUpdate();
1059 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
1060 Layer::State& front;
1061 Layer::State& current;
1062 bool& recomputeVisibleRegions;
1063 Reject(Layer::State& front, Layer::State& current,
1064 bool& recomputeVisibleRegions)
1065 : front(front), current(current),
1066 recomputeVisibleRegions(recomputeVisibleRegions) {
1069 virtual bool reject(const sp<GraphicBuffer>& buf,
1070 const BufferQueue::BufferItem& item) {
1075 uint32_t bufWidth = buf->getWidth();
1076 uint32_t bufHeight = buf->getHeight();
1078 // check that we received a buffer of the right size
1079 // (Take the buffer's orientation into account)
1080 if (item.mTransform & Transform::ROT_90) {
1081 swap(bufWidth, bufHeight);
1084 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1085 if (front.active != front.requested) {
1088 (bufWidth == front.requested.w &&
1089 bufHeight == front.requested.h))
1091 // Here we pretend the transaction happened by updating the
1092 // current and drawing states. Drawing state is only accessed
1093 // in this thread, no need to have it locked
1094 front.active = front.requested;
1096 // We also need to update the current state so that
1097 // we don't end-up overwriting the drawing state with
1098 // this stale current state during the next transaction
1100 // NOTE: We don't need to hold the transaction lock here
1101 // because State::active is only accessed from this thread.
1102 current.active = front.active;
1104 // recompute visible region
1105 recomputeVisibleRegions = true;
1108 ALOGD_IF(DEBUG_RESIZE,
1109 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
1110 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1111 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
1112 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
1113 front.active.w, front.active.h,
1114 front.active.crop.left,
1115 front.active.crop.top,
1116 front.active.crop.right,
1117 front.active.crop.bottom,
1118 front.active.crop.getWidth(),
1119 front.active.crop.getHeight(),
1120 front.requested.w, front.requested.h,
1121 front.requested.crop.left,
1122 front.requested.crop.top,
1123 front.requested.crop.right,
1124 front.requested.crop.bottom,
1125 front.requested.crop.getWidth(),
1126 front.requested.crop.getHeight());
1130 if (front.active.w != bufWidth ||
1131 front.active.h != bufHeight) {
1132 // reject this buffer
1137 // if the transparent region has changed (this test is
1138 // conservative, but that's fine, worst case we're doing
1139 // a bit of extra work), we latch the new one and we
1140 // trigger a visible-region recompute.
1141 if (!front.activeTransparentRegion.isTriviallyEqual(
1142 front.requestedTransparentRegion)) {
1143 front.activeTransparentRegion = front.requestedTransparentRegion;
1145 // We also need to update the current state so that
1146 // we don't end-up overwriting the drawing state with
1147 // this stale current state during the next transaction
1149 // NOTE: We don't need to hold the transaction lock here
1150 // because State::active is only accessed from this thread.
1151 current.activeTransparentRegion = front.activeTransparentRegion;
1153 // recompute visible region
1154 recomputeVisibleRegions = true;
1162 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
1164 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
1165 // something happened!
1166 recomputeVisibleRegions = true;
1167 return outDirtyRegion;
1170 // update the active buffer
1171 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1172 if (mActiveBuffer == NULL) {
1173 // this can only happen if the very first buffer was rejected.
1174 return outDirtyRegion;
1177 mRefreshPending = true;
1178 mFrameLatencyNeeded = true;
1179 if (oldActiveBuffer == NULL) {
1180 // the first time we receive a buffer, we need to trigger a
1181 // geometry invalidation.
1182 recomputeVisibleRegions = true;
1185 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1186 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1187 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1188 if ((crop != mCurrentCrop) ||
1189 (transform != mCurrentTransform) ||
1190 (scalingMode != mCurrentScalingMode))
1192 mCurrentCrop = crop;
1193 mCurrentTransform = transform;
1194 mCurrentScalingMode = scalingMode;
1195 recomputeVisibleRegions = true;
1198 if (oldActiveBuffer != NULL) {
1199 uint32_t bufWidth = mActiveBuffer->getWidth();
1200 uint32_t bufHeight = mActiveBuffer->getHeight();
1201 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1202 bufHeight != uint32_t(oldActiveBuffer->height)) {
1203 recomputeVisibleRegions = true;
1207 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1208 if (oldOpacity != isOpaque()) {
1209 recomputeVisibleRegions = true;
1212 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1213 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1215 // FIXME: postedRegion should be dirty & bounds
1216 const Layer::State& front(drawingState());
1217 Region dirtyRegion(Rect(front.active.w, front.active.h));
1219 // transform the dirty region to window-manager space
1220 outDirtyRegion = (front.transform.transform(dirtyRegion));
1222 return outDirtyRegion;
1225 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1227 // TODO: should we do something special if mSecure is set?
1228 if (mProtectedByApp) {
1229 // need a hardware-protected path to external video sink
1230 usage |= GraphicBuffer::USAGE_PROTECTED;
1232 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1236 void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
1237 uint32_t orientation = 0;
1238 if (!mFlinger->mDebugDisableTransformHint) {
1239 // The transform hint is used to improve performance, but we can
1240 // only have a single transform hint, it cannot
1241 // apply to all displays.
1242 const Transform& planeTransform(hw->getTransform());
1243 orientation = planeTransform.getOrientation();
1244 if (orientation & Transform::ROT_INVALID) {
1248 mSurfaceFlingerConsumer->setTransformHint(orientation);
1251 // ----------------------------------------------------------------------------
1253 // ----------------------------------------------------------------------------
1255 void Layer::dump(String8& result, Colorizer& colorizer) const
1257 const Layer::State& s(drawingState());
1259 colorizer.colorize(result, Colorizer::GREEN);
1260 result.appendFormat(
1262 getTypeId(), this, getName().string());
1263 colorizer.reset(result);
1265 s.activeTransparentRegion.dump(result, "transparentRegion");
1266 visibleRegion.dump(result, "visibleRegion");
1267 sp<Client> client(mClientRef.promote());
1269 result.appendFormat( " "
1270 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1271 "isOpaque=%1d, invalidate=%1d, "
1272 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1274 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1275 s.active.crop.left, s.active.crop.top,
1276 s.active.crop.right, s.active.crop.bottom,
1277 isOpaque(), contentDirty,
1279 s.transform[0][0], s.transform[0][1],
1280 s.transform[1][0], s.transform[1][1],
1283 sp<const GraphicBuffer> buf0(mActiveBuffer);
1284 uint32_t w0=0, h0=0, s0=0, f0=0;
1286 w0 = buf0->getWidth();
1287 h0 = buf0->getHeight();
1288 s0 = buf0->getStride();
1291 result.appendFormat(
1293 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1294 " queued-frames=%d, mRefreshPending=%d\n",
1295 mFormat, w0, h0, s0,f0,
1296 mQueuedFrames, mRefreshPending);
1298 if (mSurfaceFlingerConsumer != 0) {
1299 mSurfaceFlingerConsumer->dump(result, " ");
1303 void Layer::dumpStats(String8& result) const {
1304 mFrameTracker.dump(result);
1307 void Layer::clearStats() {
1308 mFrameTracker.clear();
1311 // ---------------------------------------------------------------------------
1313 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1314 const sp<Layer>& layer)
1315 : mFlinger(flinger), mLayer(layer) {
1318 Layer::LayerCleaner::~LayerCleaner() {
1319 // destroy client resources
1320 mFlinger->onLayerDestroyed(mLayer);
1323 // ---------------------------------------------------------------------------
1326 }; // namespace android