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