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