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