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