Layer.cpp revision 1df8c345854155cbbcb9f80de9d12d66ea70ac08
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    if (isSecure() && !hw->isSecure()) {
255        layer.setSkip(true);
256    }
257
258    const State& s(drawingState());
259    layer.setPlaneAlpha(s.alpha);
260
261    /*
262     * Transformations are applied in this order:
263     * 1) buffer orientation/flip/mirror
264     * 2) state transformation (window manager)
265     * 3) layer orientation (screen orientation)
266     * (NOTE: the matrices are multiplied in reverse order)
267     */
268
269    const Transform bufferOrientation(mCurrentTransform);
270    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
271
272    // this gives us only the "orientation" component of the transform
273    const uint32_t finalTransform = tr.getOrientation();
274
275    // we can only handle simple transformation
276    if (finalTransform & Transform::ROT_INVALID) {
277        layer.setSkip(true);
278    } else {
279        layer.setTransform(finalTransform);
280    }
281    layer.setCrop(computeBufferCrop());
282}
283
284void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
285        HWComposer::HWCLayerInterface& layer) {
286    LayerBaseClient::setPerFrameData(hw, layer);
287    // NOTE: buffer can be NULL if the client never drew into this
288    // layer yet, or if we ran out of memory
289    layer.setBuffer(mActiveBuffer);
290}
291
292void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
293        HWComposer::HWCLayerInterface& layer) {
294    int fenceFd = -1;
295
296    // TODO: there is a possible optimization here: we only need to set the
297    // acquire fence the first time a new buffer is acquired on EACH display.
298
299    if (layer.getCompositionType() == HWC_OVERLAY) {
300        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
301        if (fence->isValid()) {
302            fenceFd = fence->dup();
303            if (fenceFd == -1) {
304                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
305            }
306        }
307    }
308    layer.setAcquireFenceFd(fenceFd);
309}
310
311void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
312{
313    ATRACE_CALL();
314
315    if (CC_UNLIKELY(mActiveBuffer == 0)) {
316        // the texture has not been created yet, this Layer has
317        // in fact never been drawn into. This happens frequently with
318        // SurfaceView because the WindowManager can't know when the client
319        // has drawn the first time.
320
321        // If there is nothing under us, we paint the screen in black, otherwise
322        // we just skip this update.
323
324        // figure out if there is something below us
325        Region under;
326        const SurfaceFlinger::LayerVector& drawingLayers(
327                mFlinger->mDrawingState.layersSortedByZ);
328        const size_t count = drawingLayers.size();
329        for (size_t i=0 ; i<count ; ++i) {
330            const sp<LayerBase>& layer(drawingLayers[i]);
331            if (layer.get() == static_cast<LayerBase const*>(this))
332                break;
333            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
334        }
335        // if not everything below us is covered, we plug the holes!
336        Region holes(clip.subtract(under));
337        if (!holes.isEmpty()) {
338            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
339        }
340        return;
341    }
342
343    // Bind the current buffer to the GL texture, and wait for it to be
344    // ready for us to draw into.
345    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
346    if (err != NO_ERROR) {
347        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
348        // Go ahead and draw the buffer anyway; no matter what we do the screen
349        // is probably going to have something visibly wrong.
350    }
351
352    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
353
354    if (!blackOutLayer) {
355        // TODO: we could be more subtle with isFixedSize()
356        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
357
358        // Query the texture matrix given our current filtering mode.
359        float textureMatrix[16];
360        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
361        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
362
363        // Set things up for texturing.
364        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
365        GLenum filter = GL_NEAREST;
366        if (useFiltering) {
367            filter = GL_LINEAR;
368        }
369        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
370        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
371        glMatrixMode(GL_TEXTURE);
372        glLoadMatrixf(textureMatrix);
373        glMatrixMode(GL_MODELVIEW);
374        glDisable(GL_TEXTURE_2D);
375        glEnable(GL_TEXTURE_EXTERNAL_OES);
376    } else {
377        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
378        glMatrixMode(GL_TEXTURE);
379        glLoadIdentity();
380        glMatrixMode(GL_MODELVIEW);
381        glDisable(GL_TEXTURE_EXTERNAL_OES);
382        glEnable(GL_TEXTURE_2D);
383    }
384
385    drawWithOpenGL(hw, clip);
386
387    glDisable(GL_TEXTURE_EXTERNAL_OES);
388    glDisable(GL_TEXTURE_2D);
389}
390
391// As documented in libhardware header, formats in the range
392// 0x100 - 0x1FF are specific to the HAL implementation, and
393// are known to have no alpha channel
394// TODO: move definition for device-specific range into
395// hardware.h, instead of using hard-coded values here.
396#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
397
398bool Layer::getOpacityForFormat(uint32_t format)
399{
400    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
401        return true;
402    }
403    PixelFormatInfo info;
404    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
405    // in case of error (unknown format), we assume no blending
406    return (err || info.h_alpha <= info.l_alpha);
407}
408
409
410bool Layer::isOpaque() const
411{
412    // if we don't have a buffer yet, we're translucent regardless of the
413    // layer's opaque flag.
414    if (mActiveBuffer == 0) {
415        return false;
416    }
417
418    // if the layer has the opaque flag, then we're always opaque,
419    // otherwise we use the current buffer's format.
420    return mOpaqueLayer || mCurrentOpacity;
421}
422
423bool Layer::isProtected() const
424{
425    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
426    return (activeBuffer != 0) &&
427            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
428}
429
430uint32_t Layer::doTransaction(uint32_t flags)
431{
432    ATRACE_CALL();
433
434    const Layer::State& front(drawingState());
435    const Layer::State& temp(currentState());
436
437    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
438                             (temp.requested.h != front.requested.h);
439
440    if (sizeChanged) {
441        // the size changed, we need to ask our client to request a new buffer
442        ALOGD_IF(DEBUG_RESIZE,
443                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
444                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
445                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
446                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
447                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
448                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
449                temp.active.w, temp.active.h,
450                temp.active.crop.left,
451                temp.active.crop.top,
452                temp.active.crop.right,
453                temp.active.crop.bottom,
454                temp.active.crop.getWidth(),
455                temp.active.crop.getHeight(),
456                temp.requested.w, temp.requested.h,
457                temp.requested.crop.left,
458                temp.requested.crop.top,
459                temp.requested.crop.right,
460                temp.requested.crop.bottom,
461                temp.requested.crop.getWidth(),
462                temp.requested.crop.getHeight(),
463                front.active.w, front.active.h,
464                front.active.crop.left,
465                front.active.crop.top,
466                front.active.crop.right,
467                front.active.crop.bottom,
468                front.active.crop.getWidth(),
469                front.active.crop.getHeight(),
470                front.requested.w, front.requested.h,
471                front.requested.crop.left,
472                front.requested.crop.top,
473                front.requested.crop.right,
474                front.requested.crop.bottom,
475                front.requested.crop.getWidth(),
476                front.requested.crop.getHeight());
477
478        // record the new size, form this point on, when the client request
479        // a buffer, it'll get the new size.
480        mSurfaceFlingerConsumer->setDefaultBufferSize(
481                temp.requested.w, temp.requested.h);
482    }
483
484    if (!isFixedSize()) {
485
486        const bool resizePending = (temp.requested.w != temp.active.w) ||
487                                   (temp.requested.h != temp.active.h);
488
489        if (resizePending) {
490            // don't let LayerBase::doTransaction update the drawing state
491            // if we have a pending resize, unless we are in fixed-size mode.
492            // the drawing state will be updated only once we receive a buffer
493            // with the correct size.
494            //
495            // in particular, we want to make sure the clip (which is part
496            // of the geometry state) is latched together with the size but is
497            // latched immediately when no resizing is involved.
498
499            flags |= eDontUpdateGeometryState;
500        }
501    }
502
503    return LayerBase::doTransaction(flags);
504}
505
506bool Layer::isFixedSize() const {
507    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
508}
509
510bool Layer::isCropped() const {
511    return !mCurrentCrop.isEmpty();
512}
513
514// ----------------------------------------------------------------------------
515// pageflip handling...
516// ----------------------------------------------------------------------------
517
518bool Layer::onPreComposition() {
519    mRefreshPending = false;
520    return mQueuedFrames > 0;
521}
522
523void Layer::onPostComposition() {
524    if (mFrameLatencyNeeded) {
525        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
526        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
527
528        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
529        if (frameReadyFence != NULL) {
530            mFrameTracker.setFrameReadyFence(frameReadyFence);
531        } else {
532            // There was no fence for this frame, so assume that it was ready
533            // to be presented at the desired present time.
534            mFrameTracker.setFrameReadyTime(desiredPresentTime);
535        }
536
537        const HWComposer& hwc = mFlinger->getHwComposer();
538        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
539        if (presentFence != NULL) {
540            mFrameTracker.setActualPresentFence(presentFence);
541        } else {
542            // The HWC doesn't support present fences, so use the refresh
543            // timestamp instead.
544            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
545            mFrameTracker.setActualPresentTime(presentTime);
546        }
547
548        mFrameTracker.advanceFrame();
549        mFrameLatencyNeeded = false;
550    }
551}
552
553bool Layer::isVisible() const {
554    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
555}
556
557Region Layer::latchBuffer(bool& recomputeVisibleRegions)
558{
559    ATRACE_CALL();
560
561    Region outDirtyRegion;
562    if (mQueuedFrames > 0) {
563
564        // if we've already called updateTexImage() without going through
565        // a composition step, we have to skip this layer at this point
566        // because we cannot call updateTeximage() without a corresponding
567        // compositionComplete() call.
568        // we'll trigger an update in onPreComposition().
569        if (mRefreshPending) {
570            return outDirtyRegion;
571        }
572
573        // Capture the old state of the layer for comparisons later
574        const bool oldOpacity = isOpaque();
575        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
576
577        // signal another event if we have more frames pending
578        if (android_atomic_dec(&mQueuedFrames) > 1) {
579            mFlinger->signalLayerUpdate();
580        }
581
582        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
583            Layer::State& front;
584            Layer::State& current;
585            bool& recomputeVisibleRegions;
586            Reject(Layer::State& front, Layer::State& current,
587                    bool& recomputeVisibleRegions)
588                : front(front), current(current),
589                  recomputeVisibleRegions(recomputeVisibleRegions) {
590            }
591
592            virtual bool reject(const sp<GraphicBuffer>& buf,
593                    const BufferQueue::BufferItem& item) {
594                if (buf == NULL) {
595                    return false;
596                }
597
598                uint32_t bufWidth  = buf->getWidth();
599                uint32_t bufHeight = buf->getHeight();
600
601                // check that we received a buffer of the right size
602                // (Take the buffer's orientation into account)
603                if (item.mTransform & Transform::ROT_90) {
604                    swap(bufWidth, bufHeight);
605                }
606
607
608                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
609                if (front.active != front.requested) {
610
611                    if (isFixedSize ||
612                            (bufWidth == front.requested.w &&
613                             bufHeight == front.requested.h))
614                    {
615                        // Here we pretend the transaction happened by updating the
616                        // current and drawing states. Drawing state is only accessed
617                        // in this thread, no need to have it locked
618                        front.active = front.requested;
619
620                        // We also need to update the current state so that
621                        // we don't end-up overwriting the drawing state with
622                        // this stale current state during the next transaction
623                        //
624                        // NOTE: We don't need to hold the transaction lock here
625                        // because State::active is only accessed from this thread.
626                        current.active = front.active;
627
628                        // recompute visible region
629                        recomputeVisibleRegions = true;
630                    }
631
632                    ALOGD_IF(DEBUG_RESIZE,
633                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
634                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
635                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
636                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
637                            front.active.w, front.active.h,
638                            front.active.crop.left,
639                            front.active.crop.top,
640                            front.active.crop.right,
641                            front.active.crop.bottom,
642                            front.active.crop.getWidth(),
643                            front.active.crop.getHeight(),
644                            front.requested.w, front.requested.h,
645                            front.requested.crop.left,
646                            front.requested.crop.top,
647                            front.requested.crop.right,
648                            front.requested.crop.bottom,
649                            front.requested.crop.getWidth(),
650                            front.requested.crop.getHeight());
651                }
652
653                if (!isFixedSize) {
654                    if (front.active.w != bufWidth ||
655                        front.active.h != bufHeight) {
656                        // reject this buffer
657                        return true;
658                    }
659                }
660                return false;
661            }
662        };
663
664
665        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
666
667        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
668            // something happened!
669            recomputeVisibleRegions = true;
670            return outDirtyRegion;
671        }
672
673        // update the active buffer
674        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
675        if (mActiveBuffer == NULL) {
676            // this can only happen if the very first buffer was rejected.
677            return outDirtyRegion;
678        }
679
680        mRefreshPending = true;
681        mFrameLatencyNeeded = true;
682        if (oldActiveBuffer == NULL) {
683             // the first time we receive a buffer, we need to trigger a
684             // geometry invalidation.
685            recomputeVisibleRegions = true;
686         }
687
688        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
689        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
690        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
691        if ((crop != mCurrentCrop) ||
692            (transform != mCurrentTransform) ||
693            (scalingMode != mCurrentScalingMode))
694        {
695            mCurrentCrop = crop;
696            mCurrentTransform = transform;
697            mCurrentScalingMode = scalingMode;
698            recomputeVisibleRegions = true;
699        }
700
701        if (oldActiveBuffer != NULL) {
702            uint32_t bufWidth  = mActiveBuffer->getWidth();
703            uint32_t bufHeight = mActiveBuffer->getHeight();
704            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
705                bufHeight != uint32_t(oldActiveBuffer->height)) {
706                recomputeVisibleRegions = true;
707            }
708        }
709
710        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
711        if (oldOpacity != isOpaque()) {
712            recomputeVisibleRegions = true;
713        }
714
715        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
716        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
717
718        // FIXME: postedRegion should be dirty & bounds
719        const Layer::State& front(drawingState());
720        Region dirtyRegion(Rect(front.active.w, front.active.h));
721
722        // transform the dirty region to window-manager space
723        outDirtyRegion = (front.transform.transform(dirtyRegion));
724    }
725    return outDirtyRegion;
726}
727
728void Layer::dump(String8& result, char* buffer, size_t SIZE) const
729{
730    LayerBaseClient::dump(result, buffer, SIZE);
731
732    sp<const GraphicBuffer> buf0(mActiveBuffer);
733    uint32_t w0=0, h0=0, s0=0, f0=0;
734    if (buf0 != 0) {
735        w0 = buf0->getWidth();
736        h0 = buf0->getHeight();
737        s0 = buf0->getStride();
738        f0 = buf0->format;
739    }
740    snprintf(buffer, SIZE,
741            "      "
742            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
743            " queued-frames=%d, mRefreshPending=%d\n",
744            mFormat, w0, h0, s0,f0,
745            mQueuedFrames, mRefreshPending);
746
747    result.append(buffer);
748
749    if (mSurfaceFlingerConsumer != 0) {
750        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
751    }
752}
753
754void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
755{
756    LayerBaseClient::dumpStats(result, buffer, SIZE);
757    mFrameTracker.dump(result);
758}
759
760void Layer::clearStats()
761{
762    LayerBaseClient::clearStats();
763    mFrameTracker.clear();
764}
765
766uint32_t Layer::getEffectiveUsage(uint32_t usage) const
767{
768    // TODO: should we do something special if mSecure is set?
769    if (mProtectedByApp) {
770        // need a hardware-protected path to external video sink
771        usage |= GraphicBuffer::USAGE_PROTECTED;
772    }
773    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
774    return usage;
775}
776
777void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
778    uint32_t orientation = 0;
779    if (!mFlinger->mDebugDisableTransformHint) {
780        // The transform hint is used to improve performance, but we can
781        // only have a single transform hint, it cannot
782        // apply to all displays.
783        const Transform& planeTransform(hw->getTransform());
784        orientation = planeTransform.getOrientation();
785        if (orientation & Transform::ROT_INVALID) {
786            orientation = 0;
787        }
788    }
789    mSurfaceFlingerConsumer->setTransformHint(orientation);
790}
791
792// ---------------------------------------------------------------------------
793
794
795}; // namespace android
796