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