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