Layer.cpp revision 4b0eba949cc026ffb2c75313042d8a7bcb3fcf86
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        if (presentFence != NULL) {
543            mFrameTracker.setActualPresentFence(presentFence);
544        } else {
545            // The HWC doesn't support present fences, so use the refresh
546            // timestamp instead.
547            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
548            mFrameTracker.setActualPresentTime(presentTime);
549        }
550
551        mFrameTracker.advanceFrame();
552        mFrameLatencyNeeded = false;
553    }
554}
555
556bool Layer::isVisible() const {
557    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
558}
559
560Region Layer::latchBuffer(bool& recomputeVisibleRegions)
561{
562    ATRACE_CALL();
563
564    Region outDirtyRegion;
565    if (mQueuedFrames > 0) {
566
567        // if we've already called updateTexImage() without going through
568        // a composition step, we have to skip this layer at this point
569        // because we cannot call updateTeximage() without a corresponding
570        // compositionComplete() call.
571        // we'll trigger an update in onPreComposition().
572        if (mRefreshPending) {
573            return outDirtyRegion;
574        }
575
576        // Capture the old state of the layer for comparisons later
577        const bool oldOpacity = isOpaque();
578        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
579
580        // signal another event if we have more frames pending
581        if (android_atomic_dec(&mQueuedFrames) > 1) {
582            mFlinger->signalLayerUpdate();
583        }
584
585        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
586            Layer::State& front;
587            Layer::State& current;
588            bool& recomputeVisibleRegions;
589            Reject(Layer::State& front, Layer::State& current,
590                    bool& recomputeVisibleRegions)
591                : front(front), current(current),
592                  recomputeVisibleRegions(recomputeVisibleRegions) {
593            }
594
595            virtual bool reject(const sp<GraphicBuffer>& buf,
596                    const BufferQueue::BufferItem& item) {
597                if (buf == NULL) {
598                    return false;
599                }
600
601                uint32_t bufWidth  = buf->getWidth();
602                uint32_t bufHeight = buf->getHeight();
603
604                // check that we received a buffer of the right size
605                // (Take the buffer's orientation into account)
606                if (item.mTransform & Transform::ROT_90) {
607                    swap(bufWidth, bufHeight);
608                }
609
610
611                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
612                if (front.active != front.requested) {
613
614                    if (isFixedSize ||
615                            (bufWidth == front.requested.w &&
616                             bufHeight == front.requested.h))
617                    {
618                        // Here we pretend the transaction happened by updating the
619                        // current and drawing states. Drawing state is only accessed
620                        // in this thread, no need to have it locked
621                        front.active = front.requested;
622
623                        // We also need to update the current state so that
624                        // we don't end-up overwriting the drawing state with
625                        // this stale current state during the next transaction
626                        //
627                        // NOTE: We don't need to hold the transaction lock here
628                        // because State::active is only accessed from this thread.
629                        current.active = front.active;
630
631                        // recompute visible region
632                        recomputeVisibleRegions = true;
633                    }
634
635                    ALOGD_IF(DEBUG_RESIZE,
636                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
637                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
638                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
639                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
640                            front.active.w, front.active.h,
641                            front.active.crop.left,
642                            front.active.crop.top,
643                            front.active.crop.right,
644                            front.active.crop.bottom,
645                            front.active.crop.getWidth(),
646                            front.active.crop.getHeight(),
647                            front.requested.w, front.requested.h,
648                            front.requested.crop.left,
649                            front.requested.crop.top,
650                            front.requested.crop.right,
651                            front.requested.crop.bottom,
652                            front.requested.crop.getWidth(),
653                            front.requested.crop.getHeight());
654                }
655
656                if (!isFixedSize) {
657                    if (front.active.w != bufWidth ||
658                        front.active.h != bufHeight) {
659                        // reject this buffer
660                        return true;
661                    }
662                }
663                return false;
664            }
665        };
666
667
668        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
669
670        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
671            // something happened!
672            recomputeVisibleRegions = true;
673            return outDirtyRegion;
674        }
675
676        // update the active buffer
677        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
678        if (mActiveBuffer == NULL) {
679            // this can only happen if the very first buffer was rejected.
680            return outDirtyRegion;
681        }
682
683        mRefreshPending = true;
684        mFrameLatencyNeeded = true;
685        if (oldActiveBuffer == NULL) {
686             // the first time we receive a buffer, we need to trigger a
687             // geometry invalidation.
688            recomputeVisibleRegions = true;
689         }
690
691        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
692        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
693        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
694        if ((crop != mCurrentCrop) ||
695            (transform != mCurrentTransform) ||
696            (scalingMode != mCurrentScalingMode))
697        {
698            mCurrentCrop = crop;
699            mCurrentTransform = transform;
700            mCurrentScalingMode = scalingMode;
701            recomputeVisibleRegions = true;
702        }
703
704        if (oldActiveBuffer != NULL) {
705            uint32_t bufWidth  = mActiveBuffer->getWidth();
706            uint32_t bufHeight = mActiveBuffer->getHeight();
707            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
708                bufHeight != uint32_t(oldActiveBuffer->height)) {
709                recomputeVisibleRegions = true;
710            }
711        }
712
713        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
714        if (oldOpacity != isOpaque()) {
715            recomputeVisibleRegions = true;
716        }
717
718        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
719        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
720
721        // FIXME: postedRegion should be dirty & bounds
722        const Layer::State& front(drawingState());
723        Region dirtyRegion(Rect(front.active.w, front.active.h));
724
725        // transform the dirty region to window-manager space
726        outDirtyRegion = (front.transform.transform(dirtyRegion));
727    }
728    return outDirtyRegion;
729}
730
731void Layer::dump(String8& result, char* buffer, size_t SIZE) const
732{
733    LayerBaseClient::dump(result, buffer, SIZE);
734
735    sp<const GraphicBuffer> buf0(mActiveBuffer);
736    uint32_t w0=0, h0=0, s0=0, f0=0;
737    if (buf0 != 0) {
738        w0 = buf0->getWidth();
739        h0 = buf0->getHeight();
740        s0 = buf0->getStride();
741        f0 = buf0->format;
742    }
743    snprintf(buffer, SIZE,
744            "      "
745            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
746            " queued-frames=%d, mRefreshPending=%d\n",
747            mFormat, w0, h0, s0,f0,
748            mQueuedFrames, mRefreshPending);
749
750    result.append(buffer);
751
752    if (mSurfaceFlingerConsumer != 0) {
753        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
754    }
755}
756
757void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
758{
759    LayerBaseClient::dumpStats(result, buffer, SIZE);
760    mFrameTracker.dump(result);
761}
762
763void Layer::clearStats()
764{
765    LayerBaseClient::clearStats();
766    mFrameTracker.clear();
767}
768
769uint32_t Layer::getEffectiveUsage(uint32_t usage) const
770{
771    // TODO: should we do something special if mSecure is set?
772    if (mProtectedByApp) {
773        // need a hardware-protected path to external video sink
774        usage |= GraphicBuffer::USAGE_PROTECTED;
775    }
776    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
777    return usage;
778}
779
780void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
781    uint32_t orientation = 0;
782    if (!mFlinger->mDebugDisableTransformHint) {
783        // The transform hint is used to improve performance, but we can
784        // only have a single transform hint, it cannot
785        // apply to all displays.
786        const Transform& planeTransform(hw->getTransform());
787        orientation = planeTransform.getOrientation();
788        if (orientation & Transform::ROT_INVALID) {
789            orientation = 0;
790        }
791    }
792    mSurfaceFlingerConsumer->setTransformHint(orientation);
793}
794
795// ---------------------------------------------------------------------------
796
797
798}; // namespace android
799