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