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