Layer.cpp revision 4fec873a98f7b4380720cd1ad006f74c8cdc73da
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    // the display's pixel format
186    // XXX: we shouldn't rely on the DisplayHardware to do this
187    const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
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    mFormat = format;
199
200    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
201    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
202    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
203    mCurrentOpacity = getOpacityForFormat(format);
204
205    mSurfaceTexture->setDefaultBufferSize(w, h);
206    mSurfaceTexture->setDefaultBufferFormat(format);
207    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
208
209    return NO_ERROR;
210}
211
212Rect Layer::computeBufferCrop() const {
213    // Start with the SurfaceTexture's buffer crop...
214    Rect crop;
215    if (!mCurrentCrop.isEmpty()) {
216        crop = mCurrentCrop;
217    } else  if (mActiveBuffer != NULL){
218        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
219    } else {
220        crop.makeInvalid();
221        return crop;
222    }
223
224    // ... then reduce that in the same proportions as the window crop reduces
225    // the window size.
226    const State& s(drawingState());
227    if (!s.active.crop.isEmpty()) {
228        // Transform the window crop to match the buffer coordinate system,
229        // which means using the inverse of the current transform set on the
230        // SurfaceTexture.
231        uint32_t invTransform = mCurrentTransform;
232        int winWidth = s.active.w;
233        int winHeight = s.active.h;
234        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
235            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
236                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
237            winWidth = s.active.h;
238            winHeight = s.active.w;
239        }
240        Rect winCrop = s.active.crop.transform(invTransform,
241                s.active.w, s.active.h);
242
243        float xScale = float(crop.width()) / float(winWidth);
244        float yScale = float(crop.height()) / float(winHeight);
245        crop.left += int(ceilf(float(winCrop.left) * xScale));
246        crop.top += int(ceilf(float(winCrop.top) * yScale));
247        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
248        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
249    }
250
251    return crop;
252}
253
254void Layer::setGeometry(
255        const DisplayHardware& hw,
256        HWComposer::HWCLayerInterface& layer)
257{
258    LayerBaseClient::setGeometry(hw, layer);
259
260    // enable this layer
261    layer.setSkip(false);
262
263    // we can't do alpha-fade with the hwc HAL
264    const State& s(drawingState());
265    if (s.alpha < 0xFF) {
266        layer.setSkip(true);
267    }
268
269    /*
270     * Transformations are applied in this order:
271     * 1) buffer orientation/flip/mirror
272     * 2) state transformation (window manager)
273     * 3) layer orientation (screen orientation)
274     * (NOTE: the matrices are multiplied in reverse order)
275     */
276
277    const Transform bufferOrientation(mCurrentTransform);
278    const Transform tr(hw.getTransform() * s.transform * bufferOrientation);
279
280    // this gives us only the "orientation" component of the transform
281    const uint32_t finalTransform = tr.getOrientation();
282
283    // we can only handle simple transformation
284    if (finalTransform & Transform::ROT_INVALID) {
285        layer.setSkip(true);
286    } else {
287        layer.setTransform(finalTransform);
288    }
289    layer.setCrop(computeBufferCrop());
290}
291
292void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
293    const sp<GraphicBuffer>& buffer(mActiveBuffer);
294    // NOTE: buffer can be NULL if the client never drew into this
295    // layer yet, or if we ran out of memory
296    layer.setBuffer(buffer);
297}
298
299void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
300    int fenceFd = -1;
301    if (mNeedHwcFence) {
302        sp<Fence> fence = mSurfaceTexture->getCurrentFence();
303        if (fence.get()) {
304            fenceFd = fence->dup();
305            if (fenceFd == -1) {
306                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
307            }
308        }
309        mNeedHwcFence = false;
310    }
311    layer.setAcquireFenceFd(fenceFd);
312}
313
314void Layer::onDraw(const DisplayHardware& hw, const Region& clip) const
315{
316    ATRACE_CALL();
317
318    if (CC_UNLIKELY(mActiveBuffer == 0)) {
319        // the texture has not been created yet, this Layer has
320        // in fact never been drawn into. This happens frequently with
321        // SurfaceView because the WindowManager can't know when the client
322        // has drawn the first time.
323
324        // If there is nothing under us, we paint the screen in black, otherwise
325        // we just skip this update.
326
327        // figure out if there is something below us
328        Region under;
329        const SurfaceFlinger::LayerVector& drawingLayers(
330                mFlinger->mDrawingState.layersSortedByZ);
331        const size_t count = drawingLayers.size();
332        for (size_t i=0 ; i<count ; ++i) {
333            const sp<LayerBase>& layer(drawingLayers[i]);
334            if (layer.get() == static_cast<LayerBase const*>(this))
335                break;
336            under.orSelf( hw.getTransform().transform(layer->visibleRegion) );
337        }
338        // if not everything below us is covered, we plug the holes!
339        Region holes(clip.subtract(under));
340        if (!holes.isEmpty()) {
341            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
342        }
343        return;
344    }
345
346    // TODO: replace this with a server-side wait
347    sp<Fence> fence = mSurfaceTexture->getCurrentFence();
348    if (fence.get()) {
349        status_t err = fence->wait(Fence::TIMEOUT_NEVER);
350        ALOGW_IF(err != OK, "Layer::onDraw: failed waiting for fence: %d", err);
351        // Go ahead and draw the buffer anyway; no matter what we do the screen
352        // is probably going to have something visibly wrong.
353    }
354
355    if (!isProtected()) {
356        // TODO: we could be more subtle with isFixedSize()
357        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
358
359        // Query the texture matrix given our current filtering mode.
360        float textureMatrix[16];
361        mSurfaceTexture->setFilteringEnabled(useFiltering);
362        mSurfaceTexture->getTransformMatrix(textureMatrix);
363
364        // Set things up for texturing.
365        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
366        GLenum filter = GL_NEAREST;
367        if (useFiltering) {
368            filter = GL_LINEAR;
369        }
370        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
371        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
372        glMatrixMode(GL_TEXTURE);
373        glLoadMatrixf(textureMatrix);
374        glMatrixMode(GL_MODELVIEW);
375        glDisable(GL_TEXTURE_2D);
376        glEnable(GL_TEXTURE_EXTERNAL_OES);
377    } else {
378        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
379        glMatrixMode(GL_TEXTURE);
380        glLoadIdentity();
381        glMatrixMode(GL_MODELVIEW);
382        glDisable(GL_TEXTURE_EXTERNAL_OES);
383        glEnable(GL_TEXTURE_2D);
384    }
385
386    drawWithOpenGL(hw, clip);
387
388    glDisable(GL_TEXTURE_EXTERNAL_OES);
389    glDisable(GL_TEXTURE_2D);
390}
391
392// As documented in libhardware header, formats in the range
393// 0x100 - 0x1FF are specific to the HAL implementation, and
394// are known to have no alpha channel
395// TODO: move definition for device-specific range into
396// hardware.h, instead of using hard-coded values here.
397#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
398
399bool Layer::getOpacityForFormat(uint32_t format)
400{
401    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
402        return true;
403    }
404    PixelFormatInfo info;
405    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
406    // in case of error (unknown format), we assume no blending
407    return (err || info.h_alpha <= info.l_alpha);
408}
409
410
411bool Layer::isOpaque() const
412{
413    // if we don't have a buffer yet, we're translucent regardless of the
414    // layer's opaque flag.
415    if (mActiveBuffer == 0) {
416        return false;
417    }
418
419    // if the layer has the opaque flag, then we're always opaque,
420    // otherwise we use the current buffer's format.
421    return mOpaqueLayer || mCurrentOpacity;
422}
423
424bool Layer::isProtected() const
425{
426    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
427    return (activeBuffer != 0) &&
428            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
429}
430
431uint32_t Layer::doTransaction(uint32_t flags)
432{
433    ATRACE_CALL();
434
435    const Layer::State& front(drawingState());
436    const Layer::State& temp(currentState());
437
438    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
439                             (temp.requested.h != front.requested.h);
440
441    if (sizeChanged) {
442        // the size changed, we need to ask our client to request a new buffer
443        ALOGD_IF(DEBUG_RESIZE,
444                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
445                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
446                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
447                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
448                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
449                this, mCurrentScalingMode,
450                temp.active.w, temp.active.h,
451                temp.active.crop.left,
452                temp.active.crop.top,
453                temp.active.crop.right,
454                temp.active.crop.bottom,
455                temp.active.crop.getWidth(),
456                temp.active.crop.getHeight(),
457                temp.requested.w, temp.requested.h,
458                temp.requested.crop.left,
459                temp.requested.crop.top,
460                temp.requested.crop.right,
461                temp.requested.crop.bottom,
462                temp.requested.crop.getWidth(),
463                temp.requested.crop.getHeight(),
464                front.active.w, front.active.h,
465                front.active.crop.left,
466                front.active.crop.top,
467                front.active.crop.right,
468                front.active.crop.bottom,
469                front.active.crop.getWidth(),
470                front.active.crop.getHeight(),
471                front.requested.w, front.requested.h,
472                front.requested.crop.left,
473                front.requested.crop.top,
474                front.requested.crop.right,
475                front.requested.crop.bottom,
476                front.requested.crop.getWidth(),
477                front.requested.crop.getHeight());
478
479        // record the new size, form this point on, when the client request
480        // a buffer, it'll get the new size.
481        mSurfaceTexture->setDefaultBufferSize(
482                temp.requested.w, temp.requested.h);
483    }
484
485    if (!isFixedSize()) {
486
487        const bool resizePending = (temp.requested.w != temp.active.w) ||
488                                   (temp.requested.h != temp.active.h);
489
490        if (resizePending) {
491            // don't let LayerBase::doTransaction update the drawing state
492            // if we have a pending resize, unless we are in fixed-size mode.
493            // the drawing state will be updated only once we receive a buffer
494            // with the correct size.
495            //
496            // in particular, we want to make sure the clip (which is part
497            // of the geometry state) is latched together with the size but is
498            // latched immediately when no resizing is involved.
499
500            flags |= eDontUpdateGeometryState;
501        }
502    }
503
504    return LayerBase::doTransaction(flags);
505}
506
507bool Layer::isFixedSize() const {
508    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
509}
510
511bool Layer::isCropped() const {
512    return !mCurrentCrop.isEmpty();
513}
514
515// ----------------------------------------------------------------------------
516// pageflip handling...
517// ----------------------------------------------------------------------------
518
519bool Layer::onPreComposition() {
520    mRefreshPending = false;
521    return mQueuedFrames > 0;
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                            "lockPageFlip: (layer=%p), 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                            this, 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        // XXX: not sure if setTransformHint belongs here
635        // it should only be needed when the main screen orientation changes
636        mSurfaceTexture->setTransformHint(getTransformHint());
637
638        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
639            // something happened!
640            recomputeVisibleRegions = true;
641            return outDirtyRegion;
642        }
643
644        // update the active buffer
645        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
646        if (mActiveBuffer == NULL) {
647            // this can only happen if the very first buffer was rejected.
648            return outDirtyRegion;
649        }
650
651        mRefreshPending = true;
652        mFrameLatencyNeeded = true;
653        mNeedHwcFence = true;
654        if (oldActiveBuffer == NULL) {
655             // the first time we receive a buffer, we need to trigger a
656             // geometry invalidation.
657             mFlinger->invalidateHwcGeometry();
658         }
659
660        Rect crop(mSurfaceTexture->getCurrentCrop());
661        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
662        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
663        if ((crop != mCurrentCrop) ||
664            (transform != mCurrentTransform) ||
665            (scalingMode != mCurrentScalingMode))
666        {
667            mCurrentCrop = crop;
668            mCurrentTransform = transform;
669            mCurrentScalingMode = scalingMode;
670            mFlinger->invalidateHwcGeometry();
671        }
672
673        if (oldActiveBuffer != NULL) {
674            uint32_t bufWidth  = mActiveBuffer->getWidth();
675            uint32_t bufHeight = mActiveBuffer->getHeight();
676            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
677                bufHeight != uint32_t(oldActiveBuffer->height)) {
678                mFlinger->invalidateHwcGeometry();
679            }
680        }
681
682        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
683        if (oldOpacity != isOpaque()) {
684            recomputeVisibleRegions = true;
685        }
686
687        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
688        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
689
690        // FIXME: postedRegion should be dirty & bounds
691        const Layer::State& front(drawingState());
692        Region dirtyRegion(Rect(front.active.w, front.active.h));
693
694        // transform the dirty region to window-manager space
695        outDirtyRegion = (front.transform.transform(dirtyRegion));
696    }
697    return outDirtyRegion;
698}
699
700void Layer::dump(String8& result, char* buffer, size_t SIZE) const
701{
702    LayerBaseClient::dump(result, buffer, SIZE);
703
704    sp<const GraphicBuffer> buf0(mActiveBuffer);
705    uint32_t w0=0, h0=0, s0=0, f0=0;
706    if (buf0 != 0) {
707        w0 = buf0->getWidth();
708        h0 = buf0->getHeight();
709        s0 = buf0->getStride();
710        f0 = buf0->format;
711    }
712    snprintf(buffer, SIZE,
713            "      "
714            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
715            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
716            mFormat, w0, h0, s0,f0,
717            getTransformHint(), mQueuedFrames, mRefreshPending);
718
719    result.append(buffer);
720
721    if (mSurfaceTexture != 0) {
722        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
723    }
724}
725
726void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
727{
728    LayerBaseClient::dumpStats(result, buffer, SIZE);
729    const size_t o = mFrameLatencyOffset;
730    const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
731    const nsecs_t period = hw.getRefreshPeriod();
732    result.appendFormat("%lld\n", period);
733    for (size_t i=0 ; i<128 ; i++) {
734        const size_t index = (o+i) % 128;
735        const nsecs_t time_app   = mFrameStats[index].timestamp;
736        const nsecs_t time_set   = mFrameStats[index].set;
737        const nsecs_t time_vsync = mFrameStats[index].vsync;
738        result.appendFormat("%lld\t%lld\t%lld\n",
739                time_app,
740                time_vsync,
741                time_set);
742    }
743    result.append("\n");
744}
745
746void Layer::clearStats()
747{
748    LayerBaseClient::clearStats();
749    memset(mFrameStats, 0, sizeof(mFrameStats));
750}
751
752uint32_t Layer::getEffectiveUsage(uint32_t usage) const
753{
754    // TODO: should we do something special if mSecure is set?
755    if (mProtectedByApp) {
756        // need a hardware-protected path to external video sink
757        usage |= GraphicBuffer::USAGE_PROTECTED;
758    }
759    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
760    return usage;
761}
762
763uint32_t Layer::getTransformHint() const {
764    uint32_t orientation = 0;
765    if (!mFlinger->mDebugDisableTransformHint) {
766        // The transform hint is used to improve performance on the main
767        // display -- we can only have a single transform hint, it cannot
768        // apply to all displays.
769        // This is why we use the default display here. This is not an
770        // oversight.
771        const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
772        const Transform& planeTransform(hw.getTransform());
773        orientation = planeTransform.getOrientation();
774        if (orientation & Transform::ROT_INVALID) {
775            orientation = 0;
776        }
777    }
778    return orientation;
779}
780
781// ---------------------------------------------------------------------------
782
783
784}; // namespace android
785