Layer.cpp revision 03414a1cfe6c1222fd7723949bd622f9cba145aa
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        int winWidth = s.active.w;
327        int winHeight = s.active.h;
328        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
329            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
330                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
331            winWidth = s.active.h;
332            winHeight = s.active.w;
333        }
334        const Rect winCrop = activeCrop.transform(
335                invTransform, s.active.w, s.active.h);
336
337        // below, crop is intersected with winCrop expressed in crop's coordinate space
338        float xScale = crop.getWidth()  / float(winWidth);
339        float yScale = crop.getHeight() / float(winHeight);
340
341        float insetL = winCrop.left                 * xScale;
342        float insetT = winCrop.top                  * yScale;
343        float insetR = (winWidth  - winCrop.right ) * xScale;
344        float insetB = (winHeight - winCrop.bottom) * yScale;
345
346        crop.left   += insetL;
347        crop.top    += insetT;
348        crop.right  -= insetR;
349        crop.bottom -= insetB;
350    }
351    return crop;
352}
353
354void Layer::setGeometry(
355    const sp<const DisplayDevice>& hw,
356        HWComposer::HWCLayerInterface& layer)
357{
358    layer.setDefaultState();
359
360    // enable this layer
361    layer.setSkip(false);
362
363    if (isSecure() && !hw->isSecure()) {
364        layer.setSkip(true);
365    }
366
367    // this gives us only the "orientation" component of the transform
368    const State& s(getDrawingState());
369    if (!isOpaque(s) || s.alpha != 0xFF) {
370        layer.setBlending(mPremultipliedAlpha ?
371                HWC_BLENDING_PREMULT :
372                HWC_BLENDING_COVERAGE);
373    }
374
375    // apply the layer's transform, followed by the display's global transform
376    // here we're guaranteed that the layer's transform preserves rects
377    Rect frame(s.transform.transform(computeBounds()));
378    frame.intersect(hw->getViewport(), &frame);
379    const Transform& tr(hw->getTransform());
380    layer.setFrame(tr.transform(frame));
381    layer.setCrop(computeCrop(hw));
382    layer.setPlaneAlpha(s.alpha);
383
384    /*
385     * Transformations are applied in this order:
386     * 1) buffer orientation/flip/mirror
387     * 2) state transformation (window manager)
388     * 3) layer orientation (screen orientation)
389     * (NOTE: the matrices are multiplied in reverse order)
390     */
391
392    const Transform bufferOrientation(mCurrentTransform);
393    Transform transform(tr * s.transform * bufferOrientation);
394
395    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
396        /*
397         * the code below applies the display's inverse transform to the buffer
398         */
399        uint32_t invTransform = hw->getOrientationTransform();
400        // calculate the inverse transform
401        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
402            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
403                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
404        }
405        // and apply to the current transform
406        transform = transform * Transform(invTransform);
407    }
408
409    // this gives us only the "orientation" component of the transform
410    const uint32_t orientation = transform.getOrientation();
411    if (orientation & Transform::ROT_INVALID) {
412        // we can only handle simple transformation
413        layer.setSkip(true);
414    } else {
415        layer.setTransform(orientation);
416    }
417}
418
419void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
420        HWComposer::HWCLayerInterface& layer) {
421    // we have to set the visible region on every frame because
422    // we currently free it during onLayerDisplayed(), which is called
423    // after HWComposer::commit() -- every frame.
424    // Apply this display's projection's viewport to the visible region
425    // before giving it to the HWC HAL.
426    const Transform& tr = hw->getTransform();
427    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
428    layer.setVisibleRegionScreen(visible);
429
430    if (mSidebandStream.get()) {
431        layer.setSidebandStream(mSidebandStream);
432    } else {
433        // NOTE: buffer can be NULL if the client never drew into this
434        // layer yet, or if we ran out of memory
435        layer.setBuffer(mActiveBuffer);
436    }
437}
438
439void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
440        HWComposer::HWCLayerInterface& layer) {
441    int fenceFd = -1;
442
443    // TODO: there is a possible optimization here: we only need to set the
444    // acquire fence the first time a new buffer is acquired on EACH display.
445
446    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
447        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
448        if (fence->isValid()) {
449            fenceFd = fence->dup();
450            if (fenceFd == -1) {
451                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
452            }
453        }
454    }
455    layer.setAcquireFenceFd(fenceFd);
456}
457
458Rect Layer::getPosition(
459    const sp<const DisplayDevice>& hw)
460{
461    // this gives us only the "orientation" component of the transform
462    const State& s(getCurrentState());
463
464    // apply the layer's transform, followed by the display's global transform
465    // here we're guaranteed that the layer's transform preserves rects
466    Rect win(s.active.w, s.active.h);
467    if (!s.active.crop.isEmpty()) {
468        win.intersect(s.active.crop, &win);
469    }
470    // subtract the transparent region and snap to the bounds
471    Rect bounds = reduce(win, s.activeTransparentRegion);
472    Rect frame(s.transform.transform(bounds));
473    frame.intersect(hw->getViewport(), &frame);
474    const Transform& tr(hw->getTransform());
475    return Rect(tr.transform(frame));
476}
477
478// ---------------------------------------------------------------------------
479// drawing...
480// ---------------------------------------------------------------------------
481
482void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
483    onDraw(hw, clip, false);
484}
485
486void Layer::draw(const sp<const DisplayDevice>& hw,
487        bool useIdentityTransform) const {
488    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
489}
490
491void Layer::draw(const sp<const DisplayDevice>& hw) const {
492    onDraw(hw, Region(hw->bounds()), false);
493}
494
495void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
496        bool useIdentityTransform) const
497{
498    ATRACE_CALL();
499
500    if (CC_UNLIKELY(mActiveBuffer == 0)) {
501        // the texture has not been created yet, this Layer has
502        // in fact never been drawn into. This happens frequently with
503        // SurfaceView because the WindowManager can't know when the client
504        // has drawn the first time.
505
506        // If there is nothing under us, we paint the screen in black, otherwise
507        // we just skip this update.
508
509        // figure out if there is something below us
510        Region under;
511        const SurfaceFlinger::LayerVector& drawingLayers(
512                mFlinger->mDrawingState.layersSortedByZ);
513        const size_t count = drawingLayers.size();
514        for (size_t i=0 ; i<count ; ++i) {
515            const sp<Layer>& layer(drawingLayers[i]);
516            if (layer.get() == static_cast<Layer const*>(this))
517                break;
518            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
519        }
520        // if not everything below us is covered, we plug the holes!
521        Region holes(clip.subtract(under));
522        if (!holes.isEmpty()) {
523            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
524        }
525        return;
526    }
527
528    // Bind the current buffer to the GL texture, and wait for it to be
529    // ready for us to draw into.
530    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
531    if (err != NO_ERROR) {
532        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
533        // Go ahead and draw the buffer anyway; no matter what we do the screen
534        // is probably going to have something visibly wrong.
535    }
536
537    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
538
539    RenderEngine& engine(mFlinger->getRenderEngine());
540
541    if (!blackOutLayer) {
542        // TODO: we could be more subtle with isFixedSize()
543        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
544
545        // Query the texture matrix given our current filtering mode.
546        float textureMatrix[16];
547        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
548        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
549
550        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
551
552            /*
553             * the code below applies the display's inverse transform to the texture transform
554             */
555
556            // create a 4x4 transform matrix from the display transform flags
557            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
558            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
559            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
560
561            mat4 tr;
562            uint32_t transform = hw->getOrientationTransform();
563            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
564                tr = tr * rot90;
565            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
566                tr = tr * flipH;
567            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
568                tr = tr * flipV;
569
570            // calculate the inverse
571            tr = inverse(tr);
572
573            // and finally apply it to the original texture matrix
574            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
575            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
576        }
577
578        // Set things up for texturing.
579        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
580        mTexture.setFiltering(useFiltering);
581        mTexture.setMatrix(textureMatrix);
582
583        engine.setupLayerTexturing(mTexture);
584    } else {
585        engine.setupLayerBlackedOut();
586    }
587    drawWithOpenGL(hw, clip, useIdentityTransform);
588    engine.disableTexturing();
589}
590
591
592void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
593        const Region& /* clip */, float red, float green, float blue,
594        float alpha) const
595{
596    RenderEngine& engine(mFlinger->getRenderEngine());
597    computeGeometry(hw, mMesh, false);
598    engine.setupFillWithColor(red, green, blue, alpha);
599    engine.drawMesh(mMesh);
600}
601
602void Layer::clearWithOpenGL(
603        const sp<const DisplayDevice>& hw, const Region& clip) const {
604    clearWithOpenGL(hw, clip, 0,0,0,0);
605}
606
607void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
608        const Region& /* clip */, bool useIdentityTransform) const {
609    const uint32_t fbHeight = hw->getHeight();
610    const State& s(getDrawingState());
611
612    computeGeometry(hw, mMesh, useIdentityTransform);
613
614    /*
615     * NOTE: the way we compute the texture coordinates here produces
616     * different results than when we take the HWC path -- in the later case
617     * the "source crop" is rounded to texel boundaries.
618     * This can produce significantly different results when the texture
619     * is scaled by a large amount.
620     *
621     * The GL code below is more logical (imho), and the difference with
622     * HWC is due to a limitation of the HWC API to integers -- a question
623     * is suspend is whether we should ignore this problem or revert to
624     * GL composition when a buffer scaling is applied (maybe with some
625     * minimal value)? Or, we could make GL behave like HWC -- but this feel
626     * like more of a hack.
627     */
628    const Rect win(computeBounds());
629
630    float left   = float(win.left)   / float(s.active.w);
631    float top    = float(win.top)    / float(s.active.h);
632    float right  = float(win.right)  / float(s.active.w);
633    float bottom = float(win.bottom) / float(s.active.h);
634
635    // TODO: we probably want to generate the texture coords with the mesh
636    // here we assume that we only have 4 vertices
637    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
638    texCoords[0] = vec2(left, 1.0f - top);
639    texCoords[1] = vec2(left, 1.0f - bottom);
640    texCoords[2] = vec2(right, 1.0f - bottom);
641    texCoords[3] = vec2(right, 1.0f - top);
642
643    RenderEngine& engine(mFlinger->getRenderEngine());
644    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
645    engine.drawMesh(mMesh);
646    engine.disableBlending();
647}
648
649uint32_t Layer::getProducerStickyTransform() const {
650    int producerStickyTransform = 0;
651    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
652    if (ret != OK) {
653        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
654                strerror(-ret), ret);
655        return 0;
656    }
657    return static_cast<uint32_t>(producerStickyTransform);
658}
659
660void Layer::setFiltering(bool filtering) {
661    mFiltering = filtering;
662}
663
664bool Layer::getFiltering() const {
665    return mFiltering;
666}
667
668// As documented in libhardware header, formats in the range
669// 0x100 - 0x1FF are specific to the HAL implementation, and
670// are known to have no alpha channel
671// TODO: move definition for device-specific range into
672// hardware.h, instead of using hard-coded values here.
673#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
674
675bool Layer::getOpacityForFormat(uint32_t format) {
676    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
677        return true;
678    }
679    switch (format) {
680        case HAL_PIXEL_FORMAT_RGBA_8888:
681        case HAL_PIXEL_FORMAT_BGRA_8888:
682        case HAL_PIXEL_FORMAT_sRGB_A_8888:
683            return false;
684    }
685    // in all other case, we have no blending (also for unknown formats)
686    return true;
687}
688
689// ----------------------------------------------------------------------------
690// local state
691// ----------------------------------------------------------------------------
692
693void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
694        bool useIdentityTransform) const
695{
696    const Layer::State& s(getDrawingState());
697    const Transform tr(useIdentityTransform ?
698            hw->getTransform() : hw->getTransform() * s.transform);
699    const uint32_t hw_h = hw->getHeight();
700    Rect win(s.active.w, s.active.h);
701    if (!s.active.crop.isEmpty()) {
702        win.intersect(s.active.crop, &win);
703    }
704    // subtract the transparent region and snap to the bounds
705    win = reduce(win, s.activeTransparentRegion);
706
707    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
708    position[0] = tr.transform(win.left,  win.top);
709    position[1] = tr.transform(win.left,  win.bottom);
710    position[2] = tr.transform(win.right, win.bottom);
711    position[3] = tr.transform(win.right, win.top);
712    for (size_t i=0 ; i<4 ; i++) {
713        position[i].y = hw_h - position[i].y;
714    }
715}
716
717bool Layer::isOpaque(const Layer::State& s) const
718{
719    // if we don't have a buffer yet, we're translucent regardless of the
720    // layer's opaque flag.
721    if (mActiveBuffer == 0) {
722        return false;
723    }
724
725    // if the layer has the opaque flag, then we're always opaque,
726    // otherwise we use the current buffer's format.
727    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
728}
729
730bool Layer::isProtected() const
731{
732    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
733    return (activeBuffer != 0) &&
734            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
735}
736
737bool Layer::isFixedSize() const {
738    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
739}
740
741bool Layer::isCropped() const {
742    return !mCurrentCrop.isEmpty();
743}
744
745bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
746    return mNeedsFiltering || hw->needsFiltering();
747}
748
749void Layer::setVisibleRegion(const Region& visibleRegion) {
750    // always called from main thread
751    this->visibleRegion = visibleRegion;
752}
753
754void Layer::setCoveredRegion(const Region& coveredRegion) {
755    // always called from main thread
756    this->coveredRegion = coveredRegion;
757}
758
759void Layer::setVisibleNonTransparentRegion(const Region&
760        setVisibleNonTransparentRegion) {
761    // always called from main thread
762    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
763}
764
765// ----------------------------------------------------------------------------
766// transaction
767// ----------------------------------------------------------------------------
768
769uint32_t Layer::doTransaction(uint32_t flags) {
770    ATRACE_CALL();
771
772    const Layer::State& s(getDrawingState());
773    const Layer::State& c(getCurrentState());
774
775    const bool sizeChanged = (c.requested.w != s.requested.w) ||
776                             (c.requested.h != s.requested.h);
777
778    if (sizeChanged) {
779        // the size changed, we need to ask our client to request a new buffer
780        ALOGD_IF(DEBUG_RESIZE,
781                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
782                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
783                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
784                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
785                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
786                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
787                c.active.w, c.active.h,
788                c.active.crop.left,
789                c.active.crop.top,
790                c.active.crop.right,
791                c.active.crop.bottom,
792                c.active.crop.getWidth(),
793                c.active.crop.getHeight(),
794                c.requested.w, c.requested.h,
795                c.requested.crop.left,
796                c.requested.crop.top,
797                c.requested.crop.right,
798                c.requested.crop.bottom,
799                c.requested.crop.getWidth(),
800                c.requested.crop.getHeight(),
801                s.active.w, s.active.h,
802                s.active.crop.left,
803                s.active.crop.top,
804                s.active.crop.right,
805                s.active.crop.bottom,
806                s.active.crop.getWidth(),
807                s.active.crop.getHeight(),
808                s.requested.w, s.requested.h,
809                s.requested.crop.left,
810                s.requested.crop.top,
811                s.requested.crop.right,
812                s.requested.crop.bottom,
813                s.requested.crop.getWidth(),
814                s.requested.crop.getHeight());
815
816        // record the new size, form this point on, when the client request
817        // a buffer, it'll get the new size.
818        mSurfaceFlingerConsumer->setDefaultBufferSize(
819                c.requested.w, c.requested.h);
820    }
821
822    if (!isFixedSize()) {
823
824        const bool resizePending = (c.requested.w != c.active.w) ||
825                                   (c.requested.h != c.active.h);
826
827        if (resizePending) {
828            // don't let Layer::doTransaction update the drawing state
829            // if we have a pending resize, unless we are in fixed-size mode.
830            // the drawing state will be updated only once we receive a buffer
831            // with the correct size.
832            //
833            // in particular, we want to make sure the clip (which is part
834            // of the geometry state) is latched together with the size but is
835            // latched immediately when no resizing is involved.
836
837            flags |= eDontUpdateGeometryState;
838        }
839    }
840
841    // always set active to requested, unless we're asked not to
842    // this is used by Layer, which special cases resizes.
843    if (flags & eDontUpdateGeometryState)  {
844    } else {
845        Layer::State& editCurrentState(getCurrentState());
846        editCurrentState.active = c.requested;
847    }
848
849    if (s.active != c.active) {
850        // invalidate and recompute the visible regions if needed
851        flags |= Layer::eVisibleRegion;
852    }
853
854    if (c.sequence != s.sequence) {
855        // invalidate and recompute the visible regions if needed
856        flags |= eVisibleRegion;
857        this->contentDirty = true;
858
859        // we may use linear filtering, if the matrix scales us
860        const uint8_t type = c.transform.getType();
861        mNeedsFiltering = (!c.transform.preserveRects() ||
862                (type >= Transform::SCALE));
863    }
864
865    // Commit the transaction
866    commitTransaction();
867    return flags;
868}
869
870void Layer::commitTransaction() {
871    mDrawingState = mCurrentState;
872}
873
874uint32_t Layer::getTransactionFlags(uint32_t flags) {
875    return android_atomic_and(~flags, &mTransactionFlags) & flags;
876}
877
878uint32_t Layer::setTransactionFlags(uint32_t flags) {
879    return android_atomic_or(flags, &mTransactionFlags);
880}
881
882bool Layer::setPosition(float x, float y) {
883    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
884        return false;
885    mCurrentState.sequence++;
886    mCurrentState.transform.set(x, y);
887    setTransactionFlags(eTransactionNeeded);
888    return true;
889}
890bool Layer::setLayer(uint32_t z) {
891    if (mCurrentState.z == z)
892        return false;
893    mCurrentState.sequence++;
894    mCurrentState.z = z;
895    setTransactionFlags(eTransactionNeeded);
896    return true;
897}
898bool Layer::setSize(uint32_t w, uint32_t h) {
899    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
900        return false;
901    mCurrentState.requested.w = w;
902    mCurrentState.requested.h = h;
903    setTransactionFlags(eTransactionNeeded);
904    return true;
905}
906bool Layer::setAlpha(uint8_t alpha) {
907    if (mCurrentState.alpha == alpha)
908        return false;
909    mCurrentState.sequence++;
910    mCurrentState.alpha = alpha;
911    setTransactionFlags(eTransactionNeeded);
912    return true;
913}
914bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
915    mCurrentState.sequence++;
916    mCurrentState.transform.set(
917            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
918    setTransactionFlags(eTransactionNeeded);
919    return true;
920}
921bool Layer::setTransparentRegionHint(const Region& transparent) {
922    mCurrentState.requestedTransparentRegion = transparent;
923    setTransactionFlags(eTransactionNeeded);
924    return true;
925}
926bool Layer::setFlags(uint8_t flags, uint8_t mask) {
927    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
928    if (mCurrentState.flags == newFlags)
929        return false;
930    mCurrentState.sequence++;
931    mCurrentState.flags = newFlags;
932    setTransactionFlags(eTransactionNeeded);
933    return true;
934}
935bool Layer::setCrop(const Rect& crop) {
936    if (mCurrentState.requested.crop == crop)
937        return false;
938    mCurrentState.sequence++;
939    mCurrentState.requested.crop = crop;
940    setTransactionFlags(eTransactionNeeded);
941    return true;
942}
943
944bool Layer::setLayerStack(uint32_t layerStack) {
945    if (mCurrentState.layerStack == layerStack)
946        return false;
947    mCurrentState.sequence++;
948    mCurrentState.layerStack = layerStack;
949    setTransactionFlags(eTransactionNeeded);
950    return true;
951}
952
953// ----------------------------------------------------------------------------
954// pageflip handling...
955// ----------------------------------------------------------------------------
956
957bool Layer::onPreComposition() {
958    mRefreshPending = false;
959    return mQueuedFrames > 0 || mSidebandStreamChanged;
960}
961
962void Layer::onPostComposition() {
963    if (mFrameLatencyNeeded) {
964        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
965        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
966
967        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
968        if (frameReadyFence->isValid()) {
969            mFrameTracker.setFrameReadyFence(frameReadyFence);
970        } else {
971            // There was no fence for this frame, so assume that it was ready
972            // to be presented at the desired present time.
973            mFrameTracker.setFrameReadyTime(desiredPresentTime);
974        }
975
976        const HWComposer& hwc = mFlinger->getHwComposer();
977        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
978        if (presentFence->isValid()) {
979            mFrameTracker.setActualPresentFence(presentFence);
980        } else {
981            // The HWC doesn't support present fences, so use the refresh
982            // timestamp instead.
983            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
984            mFrameTracker.setActualPresentTime(presentTime);
985        }
986
987        mFrameTracker.advanceFrame();
988        mFrameLatencyNeeded = false;
989    }
990}
991
992bool Layer::isVisible() const {
993    const Layer::State& s(mDrawingState);
994    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
995            && (mActiveBuffer != NULL || mSidebandStream != NULL);
996}
997
998Region Layer::latchBuffer(bool& recomputeVisibleRegions)
999{
1000    ATRACE_CALL();
1001
1002    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1003        // mSidebandStreamChanged was true
1004        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
1005    }
1006
1007    Region outDirtyRegion;
1008    if (mQueuedFrames > 0) {
1009
1010        // if we've already called updateTexImage() without going through
1011        // a composition step, we have to skip this layer at this point
1012        // because we cannot call updateTeximage() without a corresponding
1013        // compositionComplete() call.
1014        // we'll trigger an update in onPreComposition().
1015        if (mRefreshPending) {
1016            return outDirtyRegion;
1017        }
1018
1019        // Capture the old state of the layer for comparisons later
1020        const State& s(getDrawingState());
1021        const bool oldOpacity = isOpaque(s);
1022        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1023
1024        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
1025            Layer::State& front;
1026            Layer::State& current;
1027            bool& recomputeVisibleRegions;
1028            bool stickyTransformSet;
1029            Reject(Layer::State& front, Layer::State& current,
1030                    bool& recomputeVisibleRegions, bool stickySet)
1031                : front(front), current(current),
1032                  recomputeVisibleRegions(recomputeVisibleRegions),
1033                  stickyTransformSet(stickySet) {
1034            }
1035
1036            virtual bool reject(const sp<GraphicBuffer>& buf,
1037                    const IGraphicBufferConsumer::BufferItem& item) {
1038                if (buf == NULL) {
1039                    return false;
1040                }
1041
1042                uint32_t bufWidth  = buf->getWidth();
1043                uint32_t bufHeight = buf->getHeight();
1044
1045                // check that we received a buffer of the right size
1046                // (Take the buffer's orientation into account)
1047                if (item.mTransform & Transform::ROT_90) {
1048                    swap(bufWidth, bufHeight);
1049                }
1050
1051                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
1052                if (front.active != front.requested) {
1053
1054                    if (isFixedSize ||
1055                            (bufWidth == front.requested.w &&
1056                             bufHeight == front.requested.h))
1057                    {
1058                        // Here we pretend the transaction happened by updating the
1059                        // current and drawing states. Drawing state is only accessed
1060                        // in this thread, no need to have it locked
1061                        front.active = front.requested;
1062
1063                        // We also need to update the current state so that
1064                        // we don't end-up overwriting the drawing state with
1065                        // this stale current state during the next transaction
1066                        //
1067                        // NOTE: We don't need to hold the transaction lock here
1068                        // because State::active is only accessed from this thread.
1069                        current.active = front.active;
1070
1071                        // recompute visible region
1072                        recomputeVisibleRegions = true;
1073                    }
1074
1075                    ALOGD_IF(DEBUG_RESIZE,
1076                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
1077                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1078                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
1079                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
1080                            front.active.w, front.active.h,
1081                            front.active.crop.left,
1082                            front.active.crop.top,
1083                            front.active.crop.right,
1084                            front.active.crop.bottom,
1085                            front.active.crop.getWidth(),
1086                            front.active.crop.getHeight(),
1087                            front.requested.w, front.requested.h,
1088                            front.requested.crop.left,
1089                            front.requested.crop.top,
1090                            front.requested.crop.right,
1091                            front.requested.crop.bottom,
1092                            front.requested.crop.getWidth(),
1093                            front.requested.crop.getHeight());
1094                }
1095
1096                if (!isFixedSize && !stickyTransformSet) {
1097                    if (front.active.w != bufWidth ||
1098                        front.active.h != bufHeight) {
1099                        // reject this buffer
1100                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1101                                bufWidth, bufHeight, front.active.w, front.active.h);
1102                        return true;
1103                    }
1104                }
1105
1106                // if the transparent region has changed (this test is
1107                // conservative, but that's fine, worst case we're doing
1108                // a bit of extra work), we latch the new one and we
1109                // trigger a visible-region recompute.
1110                if (!front.activeTransparentRegion.isTriviallyEqual(
1111                        front.requestedTransparentRegion)) {
1112                    front.activeTransparentRegion = front.requestedTransparentRegion;
1113
1114                    // We also need to update the current state so that
1115                    // we don't end-up overwriting the drawing state with
1116                    // this stale current state during the next transaction
1117                    //
1118                    // NOTE: We don't need to hold the transaction lock here
1119                    // because State::active is only accessed from this thread.
1120                    current.activeTransparentRegion = front.activeTransparentRegion;
1121
1122                    // recompute visible region
1123                    recomputeVisibleRegions = true;
1124                }
1125
1126                return false;
1127            }
1128        };
1129
1130        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
1131                getProducerStickyTransform() != 0);
1132
1133        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
1134                mFlinger->mPrimaryDispSync);
1135        if (updateResult == BufferQueue::PRESENT_LATER) {
1136            // Producer doesn't want buffer to be displayed yet.  Signal a
1137            // layer update so we check again at the next opportunity.
1138            mFlinger->signalLayerUpdate();
1139            return outDirtyRegion;
1140        }
1141
1142        // Decrement the queued-frames count.  Signal another event if we
1143        // have more frames pending.
1144        if (android_atomic_dec(&mQueuedFrames) > 1) {
1145            mFlinger->signalLayerUpdate();
1146        }
1147
1148        if (updateResult != NO_ERROR) {
1149            // something happened!
1150            recomputeVisibleRegions = true;
1151            return outDirtyRegion;
1152        }
1153
1154        // update the active buffer
1155        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1156        if (mActiveBuffer == NULL) {
1157            // this can only happen if the very first buffer was rejected.
1158            return outDirtyRegion;
1159        }
1160
1161        mRefreshPending = true;
1162        mFrameLatencyNeeded = true;
1163        if (oldActiveBuffer == NULL) {
1164             // the first time we receive a buffer, we need to trigger a
1165             // geometry invalidation.
1166            recomputeVisibleRegions = true;
1167         }
1168
1169        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1170        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1171        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1172        if ((crop != mCurrentCrop) ||
1173            (transform != mCurrentTransform) ||
1174            (scalingMode != mCurrentScalingMode))
1175        {
1176            mCurrentCrop = crop;
1177            mCurrentTransform = transform;
1178            mCurrentScalingMode = scalingMode;
1179            recomputeVisibleRegions = true;
1180        }
1181
1182        if (oldActiveBuffer != NULL) {
1183            uint32_t bufWidth  = mActiveBuffer->getWidth();
1184            uint32_t bufHeight = mActiveBuffer->getHeight();
1185            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1186                bufHeight != uint32_t(oldActiveBuffer->height)) {
1187                recomputeVisibleRegions = true;
1188            }
1189        }
1190
1191        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1192        if (oldOpacity != isOpaque(s)) {
1193            recomputeVisibleRegions = true;
1194        }
1195
1196        // FIXME: postedRegion should be dirty & bounds
1197        Region dirtyRegion(Rect(s.active.w, s.active.h));
1198
1199        // transform the dirty region to window-manager space
1200        outDirtyRegion = (s.transform.transform(dirtyRegion));
1201    }
1202    return outDirtyRegion;
1203}
1204
1205uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1206{
1207    // TODO: should we do something special if mSecure is set?
1208    if (mProtectedByApp) {
1209        // need a hardware-protected path to external video sink
1210        usage |= GraphicBuffer::USAGE_PROTECTED;
1211    }
1212    if (mPotentialCursor) {
1213        usage |= GraphicBuffer::USAGE_CURSOR;
1214    }
1215    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1216    return usage;
1217}
1218
1219void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
1220    uint32_t orientation = 0;
1221    if (!mFlinger->mDebugDisableTransformHint) {
1222        // The transform hint is used to improve performance, but we can
1223        // only have a single transform hint, it cannot
1224        // apply to all displays.
1225        const Transform& planeTransform(hw->getTransform());
1226        orientation = planeTransform.getOrientation();
1227        if (orientation & Transform::ROT_INVALID) {
1228            orientation = 0;
1229        }
1230    }
1231    mSurfaceFlingerConsumer->setTransformHint(orientation);
1232}
1233
1234// ----------------------------------------------------------------------------
1235// debugging
1236// ----------------------------------------------------------------------------
1237
1238void Layer::dump(String8& result, Colorizer& colorizer) const
1239{
1240    const Layer::State& s(getDrawingState());
1241
1242    colorizer.colorize(result, Colorizer::GREEN);
1243    result.appendFormat(
1244            "+ %s %p (%s)\n",
1245            getTypeId(), this, getName().string());
1246    colorizer.reset(result);
1247
1248    s.activeTransparentRegion.dump(result, "transparentRegion");
1249    visibleRegion.dump(result, "visibleRegion");
1250    sp<Client> client(mClientRef.promote());
1251
1252    result.appendFormat(            "      "
1253            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1254            "isOpaque=%1d, invalidate=%1d, "
1255            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1256            "      client=%p\n",
1257            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1258            s.active.crop.left, s.active.crop.top,
1259            s.active.crop.right, s.active.crop.bottom,
1260            isOpaque(s), contentDirty,
1261            s.alpha, s.flags,
1262            s.transform[0][0], s.transform[0][1],
1263            s.transform[1][0], s.transform[1][1],
1264            client.get());
1265
1266    sp<const GraphicBuffer> buf0(mActiveBuffer);
1267    uint32_t w0=0, h0=0, s0=0, f0=0;
1268    if (buf0 != 0) {
1269        w0 = buf0->getWidth();
1270        h0 = buf0->getHeight();
1271        s0 = buf0->getStride();
1272        f0 = buf0->format;
1273    }
1274    result.appendFormat(
1275            "      "
1276            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1277            " queued-frames=%d, mRefreshPending=%d\n",
1278            mFormat, w0, h0, s0,f0,
1279            mQueuedFrames, mRefreshPending);
1280
1281    if (mSurfaceFlingerConsumer != 0) {
1282        mSurfaceFlingerConsumer->dump(result, "            ");
1283    }
1284}
1285
1286void Layer::dumpFrameStats(String8& result) const {
1287    mFrameTracker.dumpStats(result);
1288}
1289
1290void Layer::clearFrameStats() {
1291    mFrameTracker.clearStats();
1292}
1293
1294void Layer::logFrameStats() {
1295    mFrameTracker.logAndResetStats(mName);
1296}
1297
1298void Layer::getFrameStats(FrameStats* outStats) const {
1299    mFrameTracker.getStats(outStats);
1300}
1301
1302// ---------------------------------------------------------------------------
1303
1304Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1305        const sp<Layer>& layer)
1306    : mFlinger(flinger), mLayer(layer) {
1307}
1308
1309Layer::LayerCleaner::~LayerCleaner() {
1310    // destroy client resources
1311    mFlinger->onLayerDestroyed(mLayer);
1312}
1313
1314// ---------------------------------------------------------------------------
1315}; // namespace android
1316
1317#if defined(__gl_h_)
1318#error "don't include gl/gl.h in this file"
1319#endif
1320
1321#if defined(__gl2_h_)
1322#error "don't include gl2/gl2.h in this file"
1323#endif
1324