Layer.cpp revision 0cd545f14261d829513e0d6e8fa5e4e4f3372b3d
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(hwc_layer_t* hwcl)
263{
264    LayerBaseClient::setGeometry(hwcl);
265
266    hwcl->flags &= ~HWC_SKIP_LAYER;
267
268    // we can't do alpha-fade with the hwc HAL
269    const State& s(drawingState());
270    if (s.alpha < 0xFF) {
271        hwcl->flags = HWC_SKIP_LAYER;
272    }
273
274    /*
275     * Transformations are applied in this order:
276     * 1) buffer orientation/flip/mirror
277     * 2) state transformation (window manager)
278     * 3) layer orientation (screen orientation)
279     * mTransform is already the composition of (2) and (3)
280     * (NOTE: the matrices are multiplied in reverse order)
281     */
282
283    const Transform bufferOrientation(mCurrentTransform);
284    const Transform tr(mTransform * bufferOrientation);
285
286    // this gives us only the "orientation" component of the transform
287    const uint32_t finalTransform = tr.getOrientation();
288
289    // we can only handle simple transformation
290    if (finalTransform & Transform::ROT_INVALID) {
291        hwcl->flags = HWC_SKIP_LAYER;
292    } else {
293        hwcl->transform = finalTransform;
294    }
295
296    Rect crop = computeBufferCrop();
297    hwcl->sourceCrop.left   = crop.left;
298    hwcl->sourceCrop.top    = crop.top;
299    hwcl->sourceCrop.right  = crop.right;
300    hwcl->sourceCrop.bottom = crop.bottom;
301}
302
303void Layer::setPerFrameData(hwc_layer_t* hwcl) {
304    const sp<GraphicBuffer>& buffer(mActiveBuffer);
305    if (buffer == NULL) {
306        // this can happen if the client never drew into this layer yet,
307        // or if we ran out of memory. In that case, don't let
308        // HWC handle it.
309        hwcl->flags |= HWC_SKIP_LAYER;
310        hwcl->handle = NULL;
311    } else {
312        hwcl->handle = buffer->handle;
313    }
314}
315
316void Layer::onDraw(const Region& clip) const
317{
318    ATRACE_CALL();
319
320    if (CC_UNLIKELY(mActiveBuffer == 0)) {
321        // the texture has not been created yet, this Layer has
322        // in fact never been drawn into. This happens frequently with
323        // SurfaceView because the WindowManager can't know when the client
324        // has drawn the first time.
325
326        // If there is nothing under us, we paint the screen in black, otherwise
327        // we just skip this update.
328
329        // figure out if there is something below us
330        Region under;
331        const SurfaceFlinger::LayerVector& drawingLayers(
332                mFlinger->mDrawingState.layersSortedByZ);
333        const size_t count = drawingLayers.size();
334        for (size_t i=0 ; i<count ; ++i) {
335            const sp<LayerBase>& layer(drawingLayers[i]);
336            if (layer.get() == static_cast<LayerBase const*>(this))
337                break;
338            under.orSelf(layer->visibleRegionScreen);
339        }
340        // if not everything below us is covered, we plug the holes!
341        Region holes(clip.subtract(under));
342        if (!holes.isEmpty()) {
343            clearWithOpenGL(holes, 0, 0, 0, 1);
344        }
345        return;
346    }
347
348    if (!isProtected()) {
349        // TODO: we could be more subtle with isFixedSize()
350        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
351
352        // Query the texture matrix given our current filtering mode.
353        float textureMatrix[16];
354        mSurfaceTexture->setFilteringEnabled(useFiltering);
355        mSurfaceTexture->getTransformMatrix(textureMatrix);
356
357        // Set things up for texturing.
358        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
359        GLenum filter = GL_NEAREST;
360        if (useFiltering) {
361            filter = GL_LINEAR;
362        }
363        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
364        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
365        glMatrixMode(GL_TEXTURE);
366        glLoadMatrixf(textureMatrix);
367        glMatrixMode(GL_MODELVIEW);
368        glDisable(GL_TEXTURE_2D);
369        glEnable(GL_TEXTURE_EXTERNAL_OES);
370    } else {
371        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
372        glMatrixMode(GL_TEXTURE);
373        glLoadIdentity();
374        glMatrixMode(GL_MODELVIEW);
375        glDisable(GL_TEXTURE_EXTERNAL_OES);
376        glEnable(GL_TEXTURE_2D);
377    }
378
379    drawWithOpenGL(clip);
380
381    glDisable(GL_TEXTURE_EXTERNAL_OES);
382    glDisable(GL_TEXTURE_2D);
383}
384
385// As documented in libhardware header, formats in the range
386// 0x100 - 0x1FF are specific to the HAL implementation, and
387// are known to have no alpha channel
388// TODO: move definition for device-specific range into
389// hardware.h, instead of using hard-coded values here.
390#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
391
392bool Layer::getOpacityForFormat(uint32_t format)
393{
394    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
395        return true;
396    }
397    PixelFormatInfo info;
398    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
399    // in case of error (unknown format), we assume no blending
400    return (err || info.h_alpha <= info.l_alpha);
401}
402
403
404bool Layer::isOpaque() const
405{
406    // if we don't have a buffer yet, we're translucent regardless of the
407    // layer's opaque flag.
408    if (mActiveBuffer == 0) {
409        return false;
410    }
411
412    // if the layer has the opaque flag, then we're always opaque,
413    // otherwise we use the current buffer's format.
414    return mOpaqueLayer || mCurrentOpacity;
415}
416
417bool Layer::isProtected() const
418{
419    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
420    return (activeBuffer != 0) &&
421            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
422}
423
424uint32_t Layer::doTransaction(uint32_t flags)
425{
426    ATRACE_CALL();
427
428    const Layer::State& front(drawingState());
429    const Layer::State& temp(currentState());
430
431    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
432                             (temp.requested.h != front.requested.h);
433
434    if (sizeChanged) {
435        // the size changed, we need to ask our client to request a new buffer
436        ALOGD_IF(DEBUG_RESIZE,
437                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
438                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
439                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
440                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
441                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
442                this, mCurrentScalingMode,
443                temp.active.w, temp.active.h,
444                temp.active.crop.left,
445                temp.active.crop.top,
446                temp.active.crop.right,
447                temp.active.crop.bottom,
448                temp.active.crop.getWidth(),
449                temp.active.crop.getHeight(),
450                temp.requested.w, temp.requested.h,
451                temp.requested.crop.left,
452                temp.requested.crop.top,
453                temp.requested.crop.right,
454                temp.requested.crop.bottom,
455                temp.requested.crop.getWidth(),
456                temp.requested.crop.getHeight(),
457                front.active.w, front.active.h,
458                front.active.crop.left,
459                front.active.crop.top,
460                front.active.crop.right,
461                front.active.crop.bottom,
462                front.active.crop.getWidth(),
463                front.active.crop.getHeight(),
464                front.requested.w, front.requested.h,
465                front.requested.crop.left,
466                front.requested.crop.top,
467                front.requested.crop.right,
468                front.requested.crop.bottom,
469                front.requested.crop.getWidth(),
470                front.requested.crop.getHeight());
471
472        // record the new size, form this point on, when the client request
473        // a buffer, it'll get the new size.
474        mSurfaceTexture->setDefaultBufferSize(
475                temp.requested.w, temp.requested.h);
476    }
477
478    if (!isFixedSize()) {
479
480        const bool resizePending = (temp.requested.w != temp.active.w) ||
481                                   (temp.requested.h != temp.active.h);
482
483        if (resizePending) {
484            // don't let LayerBase::doTransaction update the drawing state
485            // if we have a pending resize, unless we are in fixed-size mode.
486            // the drawing state will be updated only once we receive a buffer
487            // with the correct size.
488            //
489            // in particular, we want to make sure the clip (which is part
490            // of the geometry state) is latched together with the size but is
491            // latched immediately when no resizing is involved.
492
493            flags |= eDontUpdateGeometryState;
494        }
495    }
496
497    return LayerBase::doTransaction(flags);
498}
499
500bool Layer::isFixedSize() const {
501    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
502}
503
504bool Layer::isCropped() const {
505    return !mCurrentCrop.isEmpty();
506}
507
508// ----------------------------------------------------------------------------
509// pageflip handling...
510// ----------------------------------------------------------------------------
511
512bool Layer::onPreComposition() {
513    mRefreshPending = false;
514    return mQueuedFrames > 0;
515}
516
517void Layer::lockPageFlip(bool& recomputeVisibleRegions)
518{
519    ATRACE_CALL();
520
521    if (mQueuedFrames > 0) {
522
523        // if we've already called updateTexImage() without going through
524        // a composition step, we have to skip this layer at this point
525        // because we cannot call updateTeximage() without a corresponding
526        // compositionComplete() call.
527        // we'll trigger an update in onPreComposition().
528        if (mRefreshPending) {
529            mPostedDirtyRegion.clear();
530            return;
531        }
532
533        // Capture the old state of the layer for comparisons later
534        const bool oldOpacity = isOpaque();
535        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
536
537        // signal another event if we have more frames pending
538        if (android_atomic_dec(&mQueuedFrames) > 1) {
539            mFlinger->signalLayerUpdate();
540        }
541
542        struct Reject : public SurfaceTexture::BufferRejecter {
543            Layer::State& front;
544            Layer::State& current;
545            bool& recomputeVisibleRegions;
546            Reject(Layer::State& front, Layer::State& current,
547                    bool& recomputeVisibleRegions)
548                : front(front), current(current),
549                  recomputeVisibleRegions(recomputeVisibleRegions) {
550            }
551
552            virtual bool reject(const sp<GraphicBuffer>& buf,
553                    const BufferQueue::BufferItem& item) {
554                if (buf == NULL) {
555                    return false;
556                }
557
558                uint32_t bufWidth  = buf->getWidth();
559                uint32_t bufHeight = buf->getHeight();
560
561                // check that we received a buffer of the right size
562                // (Take the buffer's orientation into account)
563                if (item.mTransform & Transform::ROT_90) {
564                    swap(bufWidth, bufHeight);
565                }
566
567
568                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
569                if (front.active != front.requested) {
570
571                    if (isFixedSize ||
572                            (bufWidth == front.requested.w &&
573                             bufHeight == front.requested.h))
574                    {
575                        // Here we pretend the transaction happened by updating the
576                        // current and drawing states. Drawing state is only accessed
577                        // in this thread, no need to have it locked
578                        front.active = front.requested;
579
580                        // We also need to update the current state so that
581                        // we don't end-up overwriting the drawing state with
582                        // this stale current state during the next transaction
583                        //
584                        // NOTE: We don't need to hold the transaction lock here
585                        // because State::active is only accessed from this thread.
586                        current.active = front.active;
587
588                        // recompute visible region
589                        recomputeVisibleRegions = true;
590                    }
591
592                    ALOGD_IF(DEBUG_RESIZE,
593                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
594                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
595                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
596                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
597                            front.active.w, front.active.h,
598                            front.active.crop.left,
599                            front.active.crop.top,
600                            front.active.crop.right,
601                            front.active.crop.bottom,
602                            front.active.crop.getWidth(),
603                            front.active.crop.getHeight(),
604                            front.requested.w, front.requested.h,
605                            front.requested.crop.left,
606                            front.requested.crop.top,
607                            front.requested.crop.right,
608                            front.requested.crop.bottom,
609                            front.requested.crop.getWidth(),
610                            front.requested.crop.getHeight());
611                }
612
613                if (!isFixedSize) {
614                    if (front.active.w != bufWidth ||
615                        front.active.h != bufHeight) {
616                        // reject this buffer
617                        return true;
618                    }
619                }
620                return false;
621            }
622        };
623
624
625        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
626
627        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
628            // something happened!
629            recomputeVisibleRegions = true;
630            return;
631        }
632
633        // update the active buffer
634        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
635        if (mActiveBuffer == NULL) {
636            // this can only happen if the very first buffer was rejected.
637            return;
638        }
639
640        mRefreshPending = true;
641        mFrameLatencyNeeded = true;
642        if (oldActiveBuffer == NULL) {
643             // the first time we receive a buffer, we need to trigger a
644             // geometry invalidation.
645             mFlinger->invalidateHwcGeometry();
646         }
647
648        Rect crop(mSurfaceTexture->getCurrentCrop());
649        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
650        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
651        if ((crop != mCurrentCrop) ||
652            (transform != mCurrentTransform) ||
653            (scalingMode != mCurrentScalingMode))
654        {
655            mCurrentCrop = crop;
656            mCurrentTransform = transform;
657            mCurrentScalingMode = scalingMode;
658            mFlinger->invalidateHwcGeometry();
659        }
660
661        if (oldActiveBuffer != NULL) {
662            uint32_t bufWidth  = mActiveBuffer->getWidth();
663            uint32_t bufHeight = mActiveBuffer->getHeight();
664            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
665                bufHeight != uint32_t(oldActiveBuffer->height)) {
666                mFlinger->invalidateHwcGeometry();
667            }
668        }
669
670        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
671        if (oldOpacity != isOpaque()) {
672            recomputeVisibleRegions = true;
673        }
674
675        // FIXME: mPostedDirtyRegion = dirty & bounds
676        const Layer::State& front(drawingState());
677        mPostedDirtyRegion.set(front.active.w, front.active.h);
678
679        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
680        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
681    }
682}
683
684void Layer::unlockPageFlip(
685        const Transform& planeTransform, Region& outDirtyRegion)
686{
687    ATRACE_CALL();
688
689    Region postedRegion(mPostedDirtyRegion);
690    if (!postedRegion.isEmpty()) {
691        mPostedDirtyRegion.clear();
692        if (!visibleRegionScreen.isEmpty()) {
693            // The dirty region is given in the layer's coordinate space
694            // transform the dirty region by the surface's transformation
695            // and the global transformation.
696            const Layer::State& s(drawingState());
697            const Transform tr(planeTransform * s.transform);
698            postedRegion = tr.transform(postedRegion);
699
700            // At this point, the dirty region is in screen space.
701            // Make sure it's constrained by the visible region (which
702            // is in screen space as well).
703            postedRegion.andSelf(visibleRegionScreen);
704            outDirtyRegion.orSelf(postedRegion);
705        }
706    }
707}
708
709void Layer::dump(String8& result, char* buffer, size_t SIZE) const
710{
711    LayerBaseClient::dump(result, buffer, SIZE);
712
713    sp<const GraphicBuffer> buf0(mActiveBuffer);
714    uint32_t w0=0, h0=0, s0=0, f0=0;
715    if (buf0 != 0) {
716        w0 = buf0->getWidth();
717        h0 = buf0->getHeight();
718        s0 = buf0->getStride();
719        f0 = buf0->format;
720    }
721    snprintf(buffer, SIZE,
722            "      "
723            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
724            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
725            mFormat, w0, h0, s0,f0,
726            getTransformHint(), mQueuedFrames, mRefreshPending);
727
728    result.append(buffer);
729
730    if (mSurfaceTexture != 0) {
731        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
732    }
733}
734
735void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
736{
737    LayerBaseClient::dumpStats(result, buffer, SIZE);
738    const size_t o = mFrameLatencyOffset;
739    const DisplayHardware& hw(graphicPlane(0).displayHardware());
740    const nsecs_t period = hw.getRefreshPeriod();
741    result.appendFormat("%lld\n", period);
742    for (size_t i=0 ; i<128 ; i++) {
743        const size_t index = (o+i) % 128;
744        const nsecs_t time_app   = mFrameStats[index].timestamp;
745        const nsecs_t time_set   = mFrameStats[index].set;
746        const nsecs_t time_vsync = mFrameStats[index].vsync;
747        result.appendFormat("%lld\t%lld\t%lld\n",
748                time_app,
749                time_vsync,
750                time_set);
751    }
752    result.append("\n");
753}
754
755void Layer::clearStats()
756{
757    LayerBaseClient::clearStats();
758    memset(mFrameStats, 0, sizeof(mFrameStats));
759}
760
761uint32_t Layer::getEffectiveUsage(uint32_t usage) const
762{
763    // TODO: should we do something special if mSecure is set?
764    if (mProtectedByApp) {
765        // need a hardware-protected path to external video sink
766        usage |= GraphicBuffer::USAGE_PROTECTED;
767    }
768    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
769    return usage;
770}
771
772uint32_t Layer::getTransformHint() const {
773    uint32_t orientation = 0;
774    if (!mFlinger->mDebugDisableTransformHint) {
775        orientation = getPlaneOrientation();
776        if (orientation & Transform::ROT_INVALID) {
777            orientation = 0;
778        }
779    }
780    return orientation;
781}
782
783// ---------------------------------------------------------------------------
784
785
786}; // namespace android
787