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