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