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