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