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