Layer.cpp revision 882e3a39ed770b335a203e233b57127fde1c839e
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/StopWatch.h>
31#include <utils/Trace.h>
32
33#include <ui/GraphicBuffer.h>
34#include <ui/PixelFormat.h>
35
36#include <gui/Surface.h>
37
38#include "clz.h"
39#include "DisplayDevice.h"
40#include "GLExtensions.h"
41#include "Layer.h"
42#include "SurfaceFlinger.h"
43#include "SurfaceTextureLayer.h"
44
45#include "DisplayHardware/HWComposer.h"
46
47#define DEBUG_RESIZE    0
48
49namespace android {
50
51// ---------------------------------------------------------------------------
52
53Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
54    :   LayerBaseClient(flinger, client),
55        mTextureName(-1U),
56        mQueuedFrames(0),
57        mCurrentTransform(0),
58        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
59        mCurrentOpacity(true),
60        mRefreshPending(false),
61        mFrameLatencyNeeded(false),
62        mFormat(PIXEL_FORMAT_NONE),
63        mGLExtensions(GLExtensions::getInstance()),
64        mOpaqueLayer(true),
65        mSecure(false),
66        mProtectedByApp(false)
67{
68    mCurrentCrop.makeInvalid();
69    glGenTextures(1, &mTextureName);
70}
71
72void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
73        HWComposer::HWCLayerInterface* layer) {
74    LayerBaseClient::onLayerDisplayed(hw, layer);
75    if (layer) {
76        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
77    }
78}
79
80void Layer::onFirstRef()
81{
82    LayerBaseClient::onFirstRef();
83
84    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
85    sp<BufferQueue> bq = new SurfaceTextureLayer();
86    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
87            GL_TEXTURE_EXTERNAL_OES, false, bq);
88
89    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
90    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
91    mSurfaceFlingerConsumer->setSynchronousMode(true);
92
93#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
94#warning "disabling triple buffering"
95    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
96#else
97    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
98#endif
99
100    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
101    updateTransformHint(hw);
102}
103
104Layer::~Layer()
105{
106    mFlinger->deleteTextureAsync(mTextureName);
107}
108
109void Layer::onFrameAvailable() {
110    android_atomic_inc(&mQueuedFrames);
111    mFlinger->signalLayerUpdate();
112}
113
114// called with SurfaceFlinger::mStateLock as soon as the layer is entered
115// in the purgatory list
116void Layer::onRemoved()
117{
118    mSurfaceFlingerConsumer->abandon();
119}
120
121void Layer::setName(const String8& name) {
122    LayerBase::setName(name);
123    mSurfaceFlingerConsumer->setName(name);
124}
125
126sp<ISurface> Layer::createSurface()
127{
128    /*
129     * This class provides an implementation of BnSurface (the "native" or
130     * "remote" side of the Binder IPC interface ISurface), and mixes in
131     * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
132     * this layer when the BSurface is destroyed.
133     *
134     * The idea is to provide a handle to the Layer through ISurface that
135     * is cleaned up automatically when the last reference to the ISurface
136     * goes away.  (The references will be held on the "proxy" side, while
137     * the Layer exists on the "native" side.)
138     *
139     * The Layer has a reference to an instance of SurfaceFlinger's variant
140     * of GLConsumer, which holds a reference to the BufferQueue.  The
141     * getSurfaceTexture() call returns a Binder interface reference for
142     * the producer interface of the buffer queue associated with the Layer.
143     */
144    class BSurface : public BnSurface, public LayerCleaner {
145        wp<const Layer> mOwner;
146        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
147            sp<IGraphicBufferProducer> res;
148            sp<const Layer> that( mOwner.promote() );
149            if (that != NULL) {
150                res = that->mSurfaceFlingerConsumer->getBufferQueue();
151            }
152            return res;
153        }
154    public:
155        BSurface(const sp<SurfaceFlinger>& flinger,
156                const sp<Layer>& layer)
157            : LayerCleaner(flinger, layer), mOwner(layer) { }
158    };
159    sp<ISurface> sur(new BSurface(mFlinger, this));
160    return sur;
161}
162
163wp<IBinder> Layer::getSurfaceTextureBinder() const
164{
165    return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
166}
167
168status_t Layer::setBuffers( uint32_t w, uint32_t h,
169                            PixelFormat format, uint32_t flags)
170{
171    // this surfaces pixel format
172    PixelFormatInfo info;
173    status_t err = getPixelFormatInfo(format, &info);
174    if (err) {
175        ALOGE("unsupported pixelformat %d", format);
176        return err;
177    }
178
179    uint32_t const maxSurfaceDims = min(
180            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
181
182    // never allow a surface larger than what our underlying GL implementation
183    // can handle.
184    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
185        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
186        return BAD_VALUE;
187    }
188
189    mFormat = format;
190
191    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
192    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
193    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
194    mCurrentOpacity = getOpacityForFormat(format);
195
196    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
197    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
198    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
199
200    return NO_ERROR;
201}
202
203Rect Layer::computeBufferCrop() const {
204    // Start with the SurfaceFlingerConsumer's buffer crop...
205    Rect crop;
206    if (!mCurrentCrop.isEmpty()) {
207        crop = mCurrentCrop;
208    } else  if (mActiveBuffer != NULL){
209        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
210    } else {
211        crop.makeInvalid();
212        return crop;
213    }
214
215    // ... then reduce that in the same proportions as the window crop reduces
216    // the window size.
217    const State& s(drawingState());
218    if (!s.active.crop.isEmpty()) {
219        // Transform the window crop to match the buffer coordinate system,
220        // which means using the inverse of the current transform set on the
221        // SurfaceFlingerConsumer.
222        uint32_t invTransform = mCurrentTransform;
223        int winWidth = s.active.w;
224        int winHeight = s.active.h;
225        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
226            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
227                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
228            winWidth = s.active.h;
229            winHeight = s.active.w;
230        }
231        Rect winCrop = s.active.crop.transform(invTransform,
232                s.active.w, s.active.h);
233
234        float xScale = float(crop.width()) / float(winWidth);
235        float yScale = float(crop.height()) / float(winHeight);
236        crop.left += int(ceilf(float(winCrop.left) * xScale));
237        crop.top += int(ceilf(float(winCrop.top) * yScale));
238        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
239        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
240    }
241
242    return crop;
243}
244
245void Layer::setGeometry(
246    const sp<const DisplayDevice>& hw,
247        HWComposer::HWCLayerInterface& layer)
248{
249    LayerBaseClient::setGeometry(hw, layer);
250
251    // enable this layer
252    layer.setSkip(false);
253
254    // we can't do alpha-fade with the hwc HAL
255    const State& s(drawingState());
256    if (s.alpha < 0xFF) {
257        layer.setSkip(true);
258    }
259
260    if (isSecure() && !hw->isSecure()) {
261        layer.setSkip(true);
262    }
263
264    /*
265     * Transformations are applied in this order:
266     * 1) buffer orientation/flip/mirror
267     * 2) state transformation (window manager)
268     * 3) layer orientation (screen orientation)
269     * (NOTE: the matrices are multiplied in reverse order)
270     */
271
272    const Transform bufferOrientation(mCurrentTransform);
273    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
274
275    // this gives us only the "orientation" component of the transform
276    const uint32_t finalTransform = tr.getOrientation();
277
278    // we can only handle simple transformation
279    if (finalTransform & Transform::ROT_INVALID) {
280        layer.setSkip(true);
281    } else {
282        layer.setTransform(finalTransform);
283    }
284    layer.setCrop(computeBufferCrop());
285}
286
287void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
288        HWComposer::HWCLayerInterface& layer) {
289    LayerBaseClient::setPerFrameData(hw, layer);
290    // NOTE: buffer can be NULL if the client never drew into this
291    // layer yet, or if we ran out of memory
292    layer.setBuffer(mActiveBuffer);
293}
294
295void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
296        HWComposer::HWCLayerInterface& layer) {
297    int fenceFd = -1;
298
299    // TODO: there is a possible optimization here: we only need to set the
300    // acquire fence the first time a new buffer is acquired on EACH display.
301
302    if (layer.getCompositionType() == HWC_OVERLAY) {
303        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
304        if (fence.get()) {
305            fenceFd = fence->dup();
306            if (fenceFd == -1) {
307                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
308            }
309        }
310    }
311    layer.setAcquireFenceFd(fenceFd);
312}
313
314void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
315{
316    ATRACE_CALL();
317
318    if (CC_UNLIKELY(mActiveBuffer == 0)) {
319        // the texture has not been created yet, this Layer has
320        // in fact never been drawn into. This happens frequently with
321        // SurfaceView because the WindowManager can't know when the client
322        // has drawn the first time.
323
324        // If there is nothing under us, we paint the screen in black, otherwise
325        // we just skip this update.
326
327        // figure out if there is something below us
328        Region under;
329        const SurfaceFlinger::LayerVector& drawingLayers(
330                mFlinger->mDrawingState.layersSortedByZ);
331        const size_t count = drawingLayers.size();
332        for (size_t i=0 ; i<count ; ++i) {
333            const sp<LayerBase>& layer(drawingLayers[i]);
334            if (layer.get() == static_cast<LayerBase const*>(this))
335                break;
336            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
337        }
338        // if not everything below us is covered, we plug the holes!
339        Region holes(clip.subtract(under));
340        if (!holes.isEmpty()) {
341            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
342        }
343        return;
344    }
345
346    // Bind the current buffer to the GL texture, and wait for it to be
347    // ready for us to draw into.
348    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
349    if (err != NO_ERROR) {
350        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
351        // Go ahead and draw the buffer anyway; no matter what we do the screen
352        // is probably going to have something visibly wrong.
353    }
354
355    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
356
357    if (!blackOutLayer) {
358        // TODO: we could be more subtle with isFixedSize()
359        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
360
361        // Query the texture matrix given our current filtering mode.
362        float textureMatrix[16];
363        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
364        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
365
366        // Set things up for texturing.
367        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
368        GLenum filter = GL_NEAREST;
369        if (useFiltering) {
370            filter = GL_LINEAR;
371        }
372        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
373        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
374        glMatrixMode(GL_TEXTURE);
375        glLoadMatrixf(textureMatrix);
376        glMatrixMode(GL_MODELVIEW);
377        glDisable(GL_TEXTURE_2D);
378        glEnable(GL_TEXTURE_EXTERNAL_OES);
379    } else {
380        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
381        glMatrixMode(GL_TEXTURE);
382        glLoadIdentity();
383        glMatrixMode(GL_MODELVIEW);
384        glDisable(GL_TEXTURE_EXTERNAL_OES);
385        glEnable(GL_TEXTURE_2D);
386    }
387
388    drawWithOpenGL(hw, clip);
389
390    glDisable(GL_TEXTURE_EXTERNAL_OES);
391    glDisable(GL_TEXTURE_2D);
392}
393
394// As documented in libhardware header, formats in the range
395// 0x100 - 0x1FF are specific to the HAL implementation, and
396// are known to have no alpha channel
397// TODO: move definition for device-specific range into
398// hardware.h, instead of using hard-coded values here.
399#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
400
401bool Layer::getOpacityForFormat(uint32_t format)
402{
403    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
404        return true;
405    }
406    PixelFormatInfo info;
407    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
408    // in case of error (unknown format), we assume no blending
409    return (err || info.h_alpha <= info.l_alpha);
410}
411
412
413bool Layer::isOpaque() const
414{
415    // if we don't have a buffer yet, we're translucent regardless of the
416    // layer's opaque flag.
417    if (mActiveBuffer == 0) {
418        return false;
419    }
420
421    // if the layer has the opaque flag, then we're always opaque,
422    // otherwise we use the current buffer's format.
423    return mOpaqueLayer || mCurrentOpacity;
424}
425
426bool Layer::isProtected() const
427{
428    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
429    return (activeBuffer != 0) &&
430            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
431}
432
433uint32_t Layer::doTransaction(uint32_t flags)
434{
435    ATRACE_CALL();
436
437    const Layer::State& front(drawingState());
438    const Layer::State& temp(currentState());
439
440    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
441                             (temp.requested.h != front.requested.h);
442
443    if (sizeChanged) {
444        // the size changed, we need to ask our client to request a new buffer
445        ALOGD_IF(DEBUG_RESIZE,
446                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
447                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
448                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
449                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
450                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
451                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
452                temp.active.w, temp.active.h,
453                temp.active.crop.left,
454                temp.active.crop.top,
455                temp.active.crop.right,
456                temp.active.crop.bottom,
457                temp.active.crop.getWidth(),
458                temp.active.crop.getHeight(),
459                temp.requested.w, temp.requested.h,
460                temp.requested.crop.left,
461                temp.requested.crop.top,
462                temp.requested.crop.right,
463                temp.requested.crop.bottom,
464                temp.requested.crop.getWidth(),
465                temp.requested.crop.getHeight(),
466                front.active.w, front.active.h,
467                front.active.crop.left,
468                front.active.crop.top,
469                front.active.crop.right,
470                front.active.crop.bottom,
471                front.active.crop.getWidth(),
472                front.active.crop.getHeight(),
473                front.requested.w, front.requested.h,
474                front.requested.crop.left,
475                front.requested.crop.top,
476                front.requested.crop.right,
477                front.requested.crop.bottom,
478                front.requested.crop.getWidth(),
479                front.requested.crop.getHeight());
480
481        // record the new size, form this point on, when the client request
482        // a buffer, it'll get the new size.
483        mSurfaceFlingerConsumer->setDefaultBufferSize(
484                temp.requested.w, temp.requested.h);
485    }
486
487    if (!isFixedSize()) {
488
489        const bool resizePending = (temp.requested.w != temp.active.w) ||
490                                   (temp.requested.h != temp.active.h);
491
492        if (resizePending) {
493            // don't let LayerBase::doTransaction update the drawing state
494            // if we have a pending resize, unless we are in fixed-size mode.
495            // the drawing state will be updated only once we receive a buffer
496            // with the correct size.
497            //
498            // in particular, we want to make sure the clip (which is part
499            // of the geometry state) is latched together with the size but is
500            // latched immediately when no resizing is involved.
501
502            flags |= eDontUpdateGeometryState;
503        }
504    }
505
506    return LayerBase::doTransaction(flags);
507}
508
509bool Layer::isFixedSize() const {
510    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
511}
512
513bool Layer::isCropped() const {
514    return !mCurrentCrop.isEmpty();
515}
516
517// ----------------------------------------------------------------------------
518// pageflip handling...
519// ----------------------------------------------------------------------------
520
521bool Layer::onPreComposition() {
522    mRefreshPending = false;
523    return mQueuedFrames > 0;
524}
525
526void Layer::onPostComposition() {
527    if (mFrameLatencyNeeded) {
528        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
529        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
530
531        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
532        if (frameReadyFence != NULL) {
533            mFrameTracker.setFrameReadyFence(frameReadyFence);
534        } else {
535            // There was no fence for this frame, so assume that it was ready
536            // to be presented at the desired present time.
537            mFrameTracker.setFrameReadyTime(desiredPresentTime);
538        }
539
540        const HWComposer& hwc = mFlinger->getHwComposer();
541        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
542        // XXX: Temporarily don't use the present fence from HWC to work
543        // around a driver bug.
544        presentFence.clear();
545        if (presentFence != NULL) {
546            mFrameTracker.setActualPresentFence(presentFence);
547        } else {
548            // The HWC doesn't support present fences, so use the refresh
549            // timestamp instead.
550            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
551            mFrameTracker.setActualPresentTime(presentTime);
552        }
553
554        mFrameTracker.advanceFrame();
555        mFrameLatencyNeeded = false;
556    }
557}
558
559bool Layer::isVisible() const {
560    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
561}
562
563Region Layer::latchBuffer(bool& recomputeVisibleRegions)
564{
565    ATRACE_CALL();
566
567    Region outDirtyRegion;
568    if (mQueuedFrames > 0) {
569
570        // if we've already called updateTexImage() without going through
571        // a composition step, we have to skip this layer at this point
572        // because we cannot call updateTeximage() without a corresponding
573        // compositionComplete() call.
574        // we'll trigger an update in onPreComposition().
575        if (mRefreshPending) {
576            return outDirtyRegion;
577        }
578
579        // Capture the old state of the layer for comparisons later
580        const bool oldOpacity = isOpaque();
581        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
582
583        // signal another event if we have more frames pending
584        if (android_atomic_dec(&mQueuedFrames) > 1) {
585            mFlinger->signalLayerUpdate();
586        }
587
588        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
589            Layer::State& front;
590            Layer::State& current;
591            bool& recomputeVisibleRegions;
592            Reject(Layer::State& front, Layer::State& current,
593                    bool& recomputeVisibleRegions)
594                : front(front), current(current),
595                  recomputeVisibleRegions(recomputeVisibleRegions) {
596            }
597
598            virtual bool reject(const sp<GraphicBuffer>& buf,
599                    const BufferQueue::BufferItem& item) {
600                if (buf == NULL) {
601                    return false;
602                }
603
604                uint32_t bufWidth  = buf->getWidth();
605                uint32_t bufHeight = buf->getHeight();
606
607                // check that we received a buffer of the right size
608                // (Take the buffer's orientation into account)
609                if (item.mTransform & Transform::ROT_90) {
610                    swap(bufWidth, bufHeight);
611                }
612
613
614                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
615                if (front.active != front.requested) {
616
617                    if (isFixedSize ||
618                            (bufWidth == front.requested.w &&
619                             bufHeight == front.requested.h))
620                    {
621                        // Here we pretend the transaction happened by updating the
622                        // current and drawing states. Drawing state is only accessed
623                        // in this thread, no need to have it locked
624                        front.active = front.requested;
625
626                        // We also need to update the current state so that
627                        // we don't end-up overwriting the drawing state with
628                        // this stale current state during the next transaction
629                        //
630                        // NOTE: We don't need to hold the transaction lock here
631                        // because State::active is only accessed from this thread.
632                        current.active = front.active;
633
634                        // recompute visible region
635                        recomputeVisibleRegions = true;
636                    }
637
638                    ALOGD_IF(DEBUG_RESIZE,
639                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
640                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
641                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
642                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
643                            front.active.w, front.active.h,
644                            front.active.crop.left,
645                            front.active.crop.top,
646                            front.active.crop.right,
647                            front.active.crop.bottom,
648                            front.active.crop.getWidth(),
649                            front.active.crop.getHeight(),
650                            front.requested.w, front.requested.h,
651                            front.requested.crop.left,
652                            front.requested.crop.top,
653                            front.requested.crop.right,
654                            front.requested.crop.bottom,
655                            front.requested.crop.getWidth(),
656                            front.requested.crop.getHeight());
657                }
658
659                if (!isFixedSize) {
660                    if (front.active.w != bufWidth ||
661                        front.active.h != bufHeight) {
662                        // reject this buffer
663                        return true;
664                    }
665                }
666                return false;
667            }
668        };
669
670
671        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
672
673        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
674            // something happened!
675            recomputeVisibleRegions = true;
676            return outDirtyRegion;
677        }
678
679        // update the active buffer
680        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
681        if (mActiveBuffer == NULL) {
682            // this can only happen if the very first buffer was rejected.
683            return outDirtyRegion;
684        }
685
686        mRefreshPending = true;
687        mFrameLatencyNeeded = true;
688        if (oldActiveBuffer == NULL) {
689             // the first time we receive a buffer, we need to trigger a
690             // geometry invalidation.
691            recomputeVisibleRegions = true;
692         }
693
694        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
695        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
696        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
697        if ((crop != mCurrentCrop) ||
698            (transform != mCurrentTransform) ||
699            (scalingMode != mCurrentScalingMode))
700        {
701            mCurrentCrop = crop;
702            mCurrentTransform = transform;
703            mCurrentScalingMode = scalingMode;
704            recomputeVisibleRegions = true;
705        }
706
707        if (oldActiveBuffer != NULL) {
708            uint32_t bufWidth  = mActiveBuffer->getWidth();
709            uint32_t bufHeight = mActiveBuffer->getHeight();
710            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
711                bufHeight != uint32_t(oldActiveBuffer->height)) {
712                recomputeVisibleRegions = true;
713            }
714        }
715
716        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
717        if (oldOpacity != isOpaque()) {
718            recomputeVisibleRegions = true;
719        }
720
721        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
722        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
723
724        // FIXME: postedRegion should be dirty & bounds
725        const Layer::State& front(drawingState());
726        Region dirtyRegion(Rect(front.active.w, front.active.h));
727
728        // transform the dirty region to window-manager space
729        outDirtyRegion = (front.transform.transform(dirtyRegion));
730    }
731    return outDirtyRegion;
732}
733
734void Layer::dump(String8& result, char* buffer, size_t SIZE) const
735{
736    LayerBaseClient::dump(result, buffer, SIZE);
737
738    sp<const GraphicBuffer> buf0(mActiveBuffer);
739    uint32_t w0=0, h0=0, s0=0, f0=0;
740    if (buf0 != 0) {
741        w0 = buf0->getWidth();
742        h0 = buf0->getHeight();
743        s0 = buf0->getStride();
744        f0 = buf0->format;
745    }
746    snprintf(buffer, SIZE,
747            "      "
748            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
749            " queued-frames=%d, mRefreshPending=%d\n",
750            mFormat, w0, h0, s0,f0,
751            mQueuedFrames, mRefreshPending);
752
753    result.append(buffer);
754
755    if (mSurfaceFlingerConsumer != 0) {
756        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
757    }
758}
759
760void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
761{
762    LayerBaseClient::dumpStats(result, buffer, SIZE);
763    const nsecs_t period =
764            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
765    result.appendFormat("%lld\n", period);
766    mFrameTracker.dump(result);
767}
768
769void Layer::clearStats()
770{
771    LayerBaseClient::clearStats();
772    mFrameTracker.clear();
773}
774
775uint32_t Layer::getEffectiveUsage(uint32_t usage) const
776{
777    // TODO: should we do something special if mSecure is set?
778    if (mProtectedByApp) {
779        // need a hardware-protected path to external video sink
780        usage |= GraphicBuffer::USAGE_PROTECTED;
781    }
782    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
783    return usage;
784}
785
786void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
787    uint32_t orientation = 0;
788    if (!mFlinger->mDebugDisableTransformHint) {
789        // The transform hint is used to improve performance, but we can
790        // only have a single transform hint, it cannot
791        // apply to all displays.
792        const Transform& planeTransform(hw->getTransform());
793        orientation = planeTransform.getOrientation();
794        if (orientation & Transform::ROT_INVALID) {
795            orientation = 0;
796        }
797    }
798    mSurfaceFlingerConsumer->setTransformHint(orientation);
799}
800
801// ---------------------------------------------------------------------------
802
803
804}; // namespace android
805