Layer.cpp revision 29c3f352797d9d2ddf055d8f888e7694ef8b3947
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/StopWatch.h>
31#include <utils/Trace.h>
32
33#include <ui/GraphicBuffer.h>
34#include <ui/PixelFormat.h>
35
36#include <gui/Surface.h>
37
38#include "clz.h"
39#include "Colorizer.h"
40#include "DisplayDevice.h"
41#include "GLExtensions.h"
42#include "Layer.h"
43#include "SurfaceFlinger.h"
44#include "SurfaceTextureLayer.h"
45
46#include "DisplayHardware/HWComposer.h"
47
48#define DEBUG_RESIZE    0
49
50namespace android {
51
52// ---------------------------------------------------------------------------
53
54int32_t Layer::sSequence = 1;
55
56Layer::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))),
60        mFlinger(flinger),
61        mTextureName(-1U),
62        mPremultipliedAlpha(true),
63        mName("unnamed"),
64        mDebug(false),
65        mFormat(PIXEL_FORMAT_NONE),
66        mGLExtensions(GLExtensions::getInstance()),
67        mOpaqueLayer(true),
68        mTransactionFlags(0),
69        mQueuedFrames(0),
70        mCurrentTransform(0),
71        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
72        mCurrentOpacity(true),
73        mRefreshPending(false),
74        mFrameLatencyNeeded(false),
75        mFiltering(false),
76        mNeedsFiltering(false),
77        mSecure(false),
78        mProtectedByApp(false),
79        mHasSurface(false),
80        mClientRef(client)
81{
82    mCurrentCrop.makeInvalid();
83    glGenTextures(1, &mTextureName);
84
85    uint32_t layerFlags = 0;
86    if (flags & ISurfaceComposerClient::eHidden)
87        layerFlags = layer_state_t::eLayerHidden;
88
89    if (flags & ISurfaceComposerClient::eNonPremultiplied)
90        mPremultipliedAlpha = false;
91
92    mName = name;
93
94    mCurrentState.active.w = w;
95    mCurrentState.active.h = h;
96    mCurrentState.active.crop.makeInvalid();
97    mCurrentState.z = 0;
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;
104
105    // drawing state & current state are identical
106    mDrawingState = mCurrentState;
107}
108
109void Layer::onFirstRef()
110{
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);
115
116    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
118    mSurfaceFlingerConsumer->setSynchronousMode(true);
119    mSurfaceFlingerConsumer->setName(mName);
120
121#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
122#warning "disabling triple buffering"
123    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
124#else
125    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
126#endif
127
128    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
129    updateTransformHint(hw);
130}
131
132Layer::~Layer() {
133    sp<Client> c(mClientRef.promote());
134    if (c != 0) {
135        c->detachLayer(this);
136    }
137    mFlinger->deleteTextureAsync(mTextureName);
138}
139
140// ---------------------------------------------------------------------------
141// callbacks
142// ---------------------------------------------------------------------------
143
144void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
145        HWComposer::HWCLayerInterface* layer) {
146    if (layer) {
147        layer->onDisplayed();
148        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
149    }
150}
151
152void Layer::onFrameAvailable() {
153    android_atomic_inc(&mQueuedFrames);
154    mFlinger->signalLayerUpdate();
155}
156
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)
160void Layer::onRemoved() {
161    mSurfaceFlingerConsumer->abandon();
162}
163
164// ---------------------------------------------------------------------------
165// set-up
166// ---------------------------------------------------------------------------
167
168String8 Layer::getName() const {
169    return mName;
170}
171
172status_t Layer::setBuffers( uint32_t w, uint32_t h,
173                            PixelFormat format, uint32_t flags)
174{
175    // this surfaces pixel format
176    PixelFormatInfo info;
177    status_t err = getPixelFormatInfo(format, &info);
178    if (err) {
179        ALOGE("unsupported pixelformat %d", format);
180        return err;
181    }
182
183    uint32_t const maxSurfaceDims = min(
184            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
185
186    // never allow a surface larger than what our underlying GL implementation
187    // can handle.
188    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
189        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
190        return BAD_VALUE;
191    }
192
193    mFormat = format;
194
195    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
196    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
197    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
198    mCurrentOpacity = getOpacityForFormat(format);
199
200    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
201    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
202    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
203
204    return NO_ERROR;
205}
206
207sp<IBinder> Layer::getHandle() {
208    Mutex::Autolock _l(mLock);
209
210    LOG_ALWAYS_FATAL_IF(mHasSurface,
211            "Layer::getHandle() has already been called");
212
213    mHasSurface = true;
214
215    /*
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.
219     *
220     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
221     * this layer when the handle is destroyed.
222     */
223
224    class Handle : public BBinder, public LayerCleaner {
225        wp<const Layer> mOwner;
226    public:
227        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
228            : LayerCleaner(flinger, layer), mOwner(layer) {
229        }
230    };
231
232    return new Handle(mFlinger, this);
233}
234
235sp<BufferQueue> Layer::getBufferQueue() const {
236    return mSurfaceFlingerConsumer->getBufferQueue();
237}
238
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();
244//    }
245//    return res;
246//}
247
248// ---------------------------------------------------------------------------
249// h/w composer set-up
250// ---------------------------------------------------------------------------
251
252Rect 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
269uint32_t Layer::getContentTransform() const {
270    return mCurrentTransform;
271}
272
273static Rect reduce(const Rect& win, const Region& exclude) {
274    if (CC_LIKELY(exclude.isEmpty())) {
275        return win;
276    }
277    if (exclude.isRect()) {
278        return win.reduce(exclude.getBounds());
279    }
280    return Region(win).subtract(exclude).getBounds();
281}
282
283Rect 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);
288    }
289    // subtract the transparent region and snap to the bounds
290    return reduce(win, s.activeTransparentRegion);
291}
292
293Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
294    /*
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.
300     */
301
302    // the content crop is the area of the content that gets scaled to the
303    // layer's size.
304    Rect crop(getContentCrop());
305
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());
309
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);
319
320    // paranoia: make sure the window-crop is constrained in the
321    // window's bounds
322    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
323
324    // subtract the transparent region and snap to the bounds
325    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
326
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;
339        }
340        const Rect winCrop = activeCrop.transform(
341                invTransform, s.active.w, s.active.h);
342
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);
347
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));
352
353        crop.left   += insetL;
354        crop.top    += insetT;
355        crop.right  -= insetR;
356        crop.bottom -= insetB;
357    }
358    return crop;
359}
360
361void Layer::setGeometry(
362    const sp<const DisplayDevice>& hw,
363        HWComposer::HWCLayerInterface& layer)
364{
365    layer.setDefaultState();
366
367    // enable this layer
368    layer.setSkip(false);
369
370    if (isSecure() && !hw->isSecure()) {
371        layer.setSkip(true);
372    }
373
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);
380    }
381
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);
390
391    /*
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)
397     */
398
399    const Transform bufferOrientation(mCurrentTransform);
400    const Transform transform(tr * s.transform * bufferOrientation);
401
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
406        layer.setSkip(true);
407    } else {
408        layer.setTransform(orientation);
409    }
410}
411
412void 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);
422
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);
426}
427
428void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
429        HWComposer::HWCLayerInterface& layer) {
430    int fenceFd = -1;
431
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.
434
435    if (layer.getCompositionType() == HWC_OVERLAY) {
436        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
437        if (fence->isValid()) {
438            fenceFd = fence->dup();
439            if (fenceFd == -1) {
440                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
441            }
442        }
443    }
444    layer.setAcquireFenceFd(fenceFd);
445}
446
447// ---------------------------------------------------------------------------
448// drawing...
449// ---------------------------------------------------------------------------
450
451void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
452    onDraw(hw, clip);
453}
454
455void Layer::draw(const sp<const DisplayDevice>& hw) {
456    onDraw( hw, Region(hw->bounds()) );
457}
458
459void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
460{
461    ATRACE_CALL();
462
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.
468
469        // If there is nothing under us, we paint the screen in black, otherwise
470        // we just skip this update.
471
472        // figure out if there is something below us
473        Region under;
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))
480                break;
481            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
482        }
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);
487        }
488        return;
489    }
490
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.
498    }
499
500    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
501
502    if (!blackOutLayer) {
503        // TODO: we could be more subtle with isFixedSize()
504        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
505
506        // Query the texture matrix given our current filtering mode.
507        float textureMatrix[16];
508        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
509        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
510
511        // Set things up for texturing.
512        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
513        GLenum filter = GL_NEAREST;
514        if (useFiltering) {
515            filter = GL_LINEAR;
516        }
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);
524    } else {
525        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
526        glMatrixMode(GL_TEXTURE);
527        glLoadIdentity();
528        glMatrixMode(GL_MODELVIEW);
529        glDisable(GL_TEXTURE_EXTERNAL_OES);
530        glEnable(GL_TEXTURE_2D);
531    }
532
533    drawWithOpenGL(hw, clip);
534
535    glDisable(GL_TEXTURE_EXTERNAL_OES);
536    glDisable(GL_TEXTURE_2D);
537}
538
539
540void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
541        GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
542{
543    const uint32_t fbHeight = hw->getHeight();
544    glColor4f(red,green,blue,alpha);
545
546    glDisable(GL_TEXTURE_EXTERNAL_OES);
547    glDisable(GL_TEXTURE_2D);
548    glDisable(GL_BLEND);
549
550    LayerMesh mesh;
551    computeGeometry(hw, &mesh);
552
553    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
554    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
555}
556
557void Layer::clearWithOpenGL(
558        const sp<const DisplayDevice>& hw, const Region& clip) const {
559    clearWithOpenGL(hw, clip, 0,0,0,0);
560}
561
562static 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
568    // through.
569    if (CC_UNLIKELY(alpha < 0xFF)) {
570        GLfloat floatAlpha = alpha * (1.0f / 255.0f);
571        if (premultipliedAlpha) {
572            glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
573        } else {
574            glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
575        }
576        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
577    } else {
578        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
579    }
580}
581
582static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) {
583    GLenum combineRGB;
584    GLenum combineAlpha;
585    GLenum src0Alpha;
586    GLfloat envColor[4];
587
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);
595    } else {
596        // Cv = Cs
597        // Av = opaque ? 1.0 : As
598        combineRGB   = GL_REPLACE;
599        combineAlpha = GL_REPLACE;
600        src0Alpha    = opaque ? GL_CONSTANT : GL_TEXTURE;
601        envColor[0]  = 1.0f;
602    }
603
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);
611    }
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);
618    }
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);
624    }
625}
626
627void Layer::drawWithOpenGL(
628        const sp<const DisplayDevice>& hw, const Region& clip) const {
629    const uint32_t fbHeight = hw->getHeight();
630    const State& s(drawingState());
631
632    if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) {
633        setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha);
634    } else {
635        setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha);
636    }
637
638    if (s.alpha < 0xFF || !isOpaque()) {
639        glEnable(GL_BLEND);
640        glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
641                    GL_ONE_MINUS_SRC_ALPHA);
642    } else {
643        glDisable(GL_BLEND);
644    }
645
646    LayerMesh mesh;
647    computeGeometry(hw, &mesh);
648
649    // TODO: we probably want to generate the texture coords with the mesh
650    // here we assume that we only have 4 vertices
651
652    struct TexCoords {
653        GLfloat u;
654        GLfloat v;
655    };
656
657
658    /*
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.
664     *
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.
671     */
672    const Rect win(computeBounds());
673
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);
678
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;
690    }
691
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());
696
697    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
698    glDisable(GL_BLEND);
699}
700
701void Layer::setFiltering(bool filtering) {
702    mFiltering = filtering;
703}
704
705bool Layer::getFiltering() const {
706    return mFiltering;
707}
708
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)
715
716bool Layer::getOpacityForFormat(uint32_t format)
717{
718    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
719        return true;
720    }
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);
725}
726
727// ----------------------------------------------------------------------------
728// local state
729// ----------------------------------------------------------------------------
730
731void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
732{
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);
739    }
740    // subtract the transparent region and snap to the bounds
741    win = reduce(win, s.activeTransparentRegion);
742    if (mesh) {
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];
749        }
750    }
751}
752
753bool Layer::isOpaque() const
754{
755    // if we don't have a buffer yet, we're translucent regardless of the
756    // layer's opaque flag.
757    if (mActiveBuffer == 0) {
758        return false;
759    }
760
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;
764}
765
766bool Layer::isProtected() const
767{
768    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
769    return (activeBuffer != 0) &&
770            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
771}
772
773bool Layer::isFixedSize() const {
774    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
775}
776
777bool Layer::isCropped() const {
778    return !mCurrentCrop.isEmpty();
779}
780
781bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
782    return mNeedsFiltering || hw->needsFiltering();
783}
784
785void Layer::setVisibleRegion(const Region& visibleRegion) {
786    // always called from main thread
787    this->visibleRegion = visibleRegion;
788}
789
790void Layer::setCoveredRegion(const Region& coveredRegion) {
791    // always called from main thread
792    this->coveredRegion = coveredRegion;
793}
794
795void Layer::setVisibleNonTransparentRegion(const Region&
796        setVisibleNonTransparentRegion) {
797    // always called from main thread
798    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
799}
800
801// ----------------------------------------------------------------------------
802// transaction
803// ----------------------------------------------------------------------------
804
805uint32_t Layer::doTransaction(uint32_t flags) {
806    ATRACE_CALL();
807
808    const Layer::State& front(drawingState());
809    const Layer::State& temp(currentState());
810
811    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
812                             (temp.requested.h != front.requested.h);
813
814    if (sizeChanged) {
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());
851
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);
856    }
857
858    if (!isFixedSize()) {
859
860        const bool resizePending = (temp.requested.w != temp.active.w) ||
861                                   (temp.requested.h != temp.active.h);
862
863        if (resizePending) {
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.
868            //
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.
872
873            flags |= eDontUpdateGeometryState;
874        }
875    }
876
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)  {
880    } else {
881        Layer::State& editTemp(currentState());
882        editTemp.active = temp.requested;
883    }
884
885    if (front.active != temp.active) {
886        // invalidate and recompute the visible regions if needed
887        flags |= Layer::eVisibleRegion;
888    }
889
890    if (temp.sequence != front.sequence) {
891        // invalidate and recompute the visible regions if needed
892        flags |= eVisibleRegion;
893        this->contentDirty = true;
894
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));
899    }
900
901    // Commit the transaction
902    commitTransaction();
903    return flags;
904}
905
906void Layer::commitTransaction() {
907    mDrawingState = mCurrentState;
908}
909
910uint32_t Layer::getTransactionFlags(uint32_t flags) {
911    return android_atomic_and(~flags, &mTransactionFlags) & flags;
912}
913
914uint32_t Layer::setTransactionFlags(uint32_t flags) {
915    return android_atomic_or(flags, &mTransactionFlags);
916}
917
918bool Layer::setPosition(float x, float y) {
919    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
920        return false;
921    mCurrentState.sequence++;
922    mCurrentState.transform.set(x, y);
923    setTransactionFlags(eTransactionNeeded);
924    return true;
925}
926bool Layer::setLayer(uint32_t z) {
927    if (mCurrentState.z == z)
928        return false;
929    mCurrentState.sequence++;
930    mCurrentState.z = z;
931    setTransactionFlags(eTransactionNeeded);
932    return true;
933}
934bool Layer::setSize(uint32_t w, uint32_t h) {
935    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
936        return false;
937    mCurrentState.requested.w = w;
938    mCurrentState.requested.h = h;
939    setTransactionFlags(eTransactionNeeded);
940    return true;
941}
942bool Layer::setAlpha(uint8_t alpha) {
943    if (mCurrentState.alpha == alpha)
944        return false;
945    mCurrentState.sequence++;
946    mCurrentState.alpha = alpha;
947    setTransactionFlags(eTransactionNeeded);
948    return true;
949}
950bool 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);
955    return true;
956}
957bool Layer::setTransparentRegionHint(const Region& transparent) {
958    mCurrentState.requestedTransparentRegion = transparent;
959    setTransactionFlags(eTransactionNeeded);
960    return true;
961}
962bool Layer::setFlags(uint8_t flags, uint8_t mask) {
963    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
964    if (mCurrentState.flags == newFlags)
965        return false;
966    mCurrentState.sequence++;
967    mCurrentState.flags = newFlags;
968    setTransactionFlags(eTransactionNeeded);
969    return true;
970}
971bool Layer::setCrop(const Rect& crop) {
972    if (mCurrentState.requested.crop == crop)
973        return false;
974    mCurrentState.sequence++;
975    mCurrentState.requested.crop = crop;
976    setTransactionFlags(eTransactionNeeded);
977    return true;
978}
979
980bool Layer::setLayerStack(uint32_t layerStack) {
981    if (mCurrentState.layerStack == layerStack)
982        return false;
983    mCurrentState.sequence++;
984    mCurrentState.layerStack = layerStack;
985    setTransactionFlags(eTransactionNeeded);
986    return true;
987}
988
989// ----------------------------------------------------------------------------
990// pageflip handling...
991// ----------------------------------------------------------------------------
992
993bool Layer::onPreComposition() {
994    mRefreshPending = false;
995    return mQueuedFrames > 0;
996}
997
998void Layer::onPostComposition() {
999    if (mFrameLatencyNeeded) {
1000        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
1001        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
1002
1003        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1004        if (frameReadyFence->isValid()) {
1005            mFrameTracker.setFrameReadyFence(frameReadyFence);
1006        } else {
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);
1010        }
1011
1012        const HWComposer& hwc = mFlinger->getHwComposer();
1013        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1014        if (presentFence->isValid()) {
1015            mFrameTracker.setActualPresentFence(presentFence);
1016        } else {
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);
1021        }
1022
1023        mFrameTracker.advanceFrame();
1024        mFrameLatencyNeeded = false;
1025    }
1026}
1027
1028bool Layer::isVisible() const {
1029    const Layer::State& s(mDrawingState);
1030    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1031            && (mActiveBuffer != NULL);
1032}
1033
1034Region Layer::latchBuffer(bool& recomputeVisibleRegions)
1035{
1036    ATRACE_CALL();
1037
1038    Region outDirtyRegion;
1039    if (mQueuedFrames > 0) {
1040
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;
1048        }
1049
1050        // Capture the old state of the layer for comparisons later
1051        const bool oldOpacity = isOpaque();
1052        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1053
1054        // signal another event if we have more frames pending
1055        if (android_atomic_dec(&mQueuedFrames) > 1) {
1056            mFlinger->signalLayerUpdate();
1057        }
1058
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) {
1067            }
1068
1069            virtual bool reject(const sp<GraphicBuffer>& buf,
1070                    const BufferQueue::BufferItem& item) {
1071                if (buf == NULL) {
1072                    return false;
1073                }
1074
1075                uint32_t bufWidth  = buf->getWidth();
1076                uint32_t bufHeight = buf->getHeight();
1077
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);
1082                }
1083
1084                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1085                if (front.active != front.requested) {
1086
1087                    if (isFixedSize ||
1088                            (bufWidth == front.requested.w &&
1089                             bufHeight == front.requested.h))
1090                    {
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;
1095
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
1099                        //
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;
1103
1104                        // recompute visible region
1105                        recomputeVisibleRegions = true;
1106                    }
1107
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());
1127                }
1128
1129                if (!isFixedSize) {
1130                    if (front.active.w != bufWidth ||
1131                        front.active.h != bufHeight) {
1132                        // reject this buffer
1133                        return true;
1134                    }
1135                }
1136
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;
1144
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
1148                    //
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;
1152
1153                    // recompute visible region
1154                    recomputeVisibleRegions = true;
1155                }
1156
1157                return false;
1158            }
1159        };
1160
1161
1162        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
1163
1164        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
1165            // something happened!
1166            recomputeVisibleRegions = true;
1167            return outDirtyRegion;
1168        }
1169
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;
1175        }
1176
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;
1183         }
1184
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))
1191        {
1192            mCurrentCrop = crop;
1193            mCurrentTransform = transform;
1194            mCurrentScalingMode = scalingMode;
1195            recomputeVisibleRegions = true;
1196        }
1197
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;
1204            }
1205        }
1206
1207        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1208        if (oldOpacity != isOpaque()) {
1209            recomputeVisibleRegions = true;
1210        }
1211
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);
1214
1215        // FIXME: postedRegion should be dirty & bounds
1216        const Layer::State& front(drawingState());
1217        Region dirtyRegion(Rect(front.active.w, front.active.h));
1218
1219        // transform the dirty region to window-manager space
1220        outDirtyRegion = (front.transform.transform(dirtyRegion));
1221    }
1222    return outDirtyRegion;
1223}
1224
1225uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1226{
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;
1231    }
1232    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1233    return usage;
1234}
1235
1236void 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) {
1245            orientation = 0;
1246        }
1247    }
1248    mSurfaceFlingerConsumer->setTransformHint(orientation);
1249}
1250
1251// ----------------------------------------------------------------------------
1252// debugging
1253// ----------------------------------------------------------------------------
1254
1255void Layer::dump(String8& result, Colorizer& colorizer) const
1256{
1257    const Layer::State& s(drawingState());
1258
1259    colorizer.colorize(result, Colorizer::GREEN);
1260    result.appendFormat(
1261            "+ %s %p (%s)\n",
1262            getTypeId(), this, getName().string());
1263    colorizer.reset(result);
1264
1265    s.activeTransparentRegion.dump(result, "transparentRegion");
1266    visibleRegion.dump(result, "visibleRegion");
1267    sp<Client> client(mClientRef.promote());
1268
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"
1273            "      client=%p\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,
1278            s.alpha, s.flags,
1279            s.transform[0][0], s.transform[0][1],
1280            s.transform[1][0], s.transform[1][1],
1281            client.get());
1282
1283    sp<const GraphicBuffer> buf0(mActiveBuffer);
1284    uint32_t w0=0, h0=0, s0=0, f0=0;
1285    if (buf0 != 0) {
1286        w0 = buf0->getWidth();
1287        h0 = buf0->getHeight();
1288        s0 = buf0->getStride();
1289        f0 = buf0->format;
1290    }
1291    result.appendFormat(
1292            "      "
1293            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1294            " queued-frames=%d, mRefreshPending=%d\n",
1295            mFormat, w0, h0, s0,f0,
1296            mQueuedFrames, mRefreshPending);
1297
1298    if (mSurfaceFlingerConsumer != 0) {
1299        mSurfaceFlingerConsumer->dump(result, "            ");
1300    }
1301}
1302
1303void Layer::dumpStats(String8& result) const {
1304    mFrameTracker.dump(result);
1305}
1306
1307void Layer::clearStats() {
1308    mFrameTracker.clear();
1309}
1310
1311// ---------------------------------------------------------------------------
1312
1313Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1314        const sp<Layer>& layer)
1315    : mFlinger(flinger), mLayer(layer) {
1316}
1317
1318Layer::LayerCleaner::~LayerCleaner() {
1319    // destroy client resources
1320    mFlinger->onLayerDestroyed(mLayer);
1321}
1322
1323// ---------------------------------------------------------------------------
1324
1325
1326}; // namespace android
1327