Layer.cpp revision 9f8386e1118c10dd4927f62637ec7162569bdbdc
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.get()) {
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        // XXX: Temporarily don't use the present fence from HWC to work
540        // around a driver bug.
541        presentFence.clear();
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    const nsecs_t period =
761            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
762    result.appendFormat("%lld\n", period);
763    mFrameTracker.dump(result);
764}
765
766void Layer::clearStats()
767{
768    LayerBaseClient::clearStats();
769    mFrameTracker.clear();
770}
771
772uint32_t Layer::getEffectiveUsage(uint32_t usage) const
773{
774    // TODO: should we do something special if mSecure is set?
775    if (mProtectedByApp) {
776        // need a hardware-protected path to external video sink
777        usage |= GraphicBuffer::USAGE_PROTECTED;
778    }
779    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
780    return usage;
781}
782
783void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
784    uint32_t orientation = 0;
785    if (!mFlinger->mDebugDisableTransformHint) {
786        // The transform hint is used to improve performance, but we can
787        // only have a single transform hint, it cannot
788        // apply to all displays.
789        const Transform& planeTransform(hw->getTransform());
790        orientation = planeTransform.getOrientation();
791        if (orientation & Transform::ROT_INVALID) {
792            orientation = 0;
793        }
794    }
795    mSurfaceFlingerConsumer->setTransformHint(orientation);
796}
797
798// ---------------------------------------------------------------------------
799
800
801}; // namespace android
802