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