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