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