Layer.cpp revision c5c5a14c06de249d8e0445fd24699e1d9aa04549
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
305void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
306    int fenceFd = -1;
307    if (mNeedHwcFence) {
308        sp<Fence> fence = mSurfaceTexture->getCurrentFence();
309        if (fence.get()) {
310            fenceFd = fence->dup();
311            if (fenceFd == -1) {
312                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
313            }
314        }
315        mNeedHwcFence = false;
316    }
317    layer.setAcquireFenceFd(fenceFd);
318}
319
320void Layer::onDraw(const DisplayHardware& hw, const Region& clip) const
321{
322    ATRACE_CALL();
323
324    if (CC_UNLIKELY(mActiveBuffer == 0)) {
325        // the texture has not been created yet, this Layer has
326        // in fact never been drawn into. This happens frequently with
327        // SurfaceView because the WindowManager can't know when the client
328        // has drawn the first time.
329
330        // If there is nothing under us, we paint the screen in black, otherwise
331        // we just skip this update.
332
333        // figure out if there is something below us
334        Region under;
335        const SurfaceFlinger::LayerVector& drawingLayers(
336                mFlinger->mDrawingState.layersSortedByZ);
337        const size_t count = drawingLayers.size();
338        for (size_t i=0 ; i<count ; ++i) {
339            const sp<LayerBase>& layer(drawingLayers[i]);
340            if (layer.get() == static_cast<LayerBase const*>(this))
341                break;
342            under.orSelf(layer->visibleRegionScreen);
343        }
344        // if not everything below us is covered, we plug the holes!
345        Region holes(clip.subtract(under));
346        if (!holes.isEmpty()) {
347            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
348        }
349        return;
350    }
351
352    // TODO: replace this with a server-side wait
353    sp<Fence> fence = mSurfaceTexture->getCurrentFence();
354    if (fence.get()) {
355        status_t err = fence->wait(Fence::TIMEOUT_NEVER);
356        ALOGW_IF(err != OK, "Layer::onDraw: failed waiting for fence: %d", err);
357        // Go ahead and draw the buffer anyway; no matter what we do the screen
358        // is probably going to have something visibly wrong.
359    }
360
361    if (!isProtected()) {
362        // TODO: we could be more subtle with isFixedSize()
363        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
364
365        // Query the texture matrix given our current filtering mode.
366        float textureMatrix[16];
367        mSurfaceTexture->setFilteringEnabled(useFiltering);
368        mSurfaceTexture->getTransformMatrix(textureMatrix);
369
370        // Set things up for texturing.
371        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
372        GLenum filter = GL_NEAREST;
373        if (useFiltering) {
374            filter = GL_LINEAR;
375        }
376        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
377        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
378        glMatrixMode(GL_TEXTURE);
379        glLoadMatrixf(textureMatrix);
380        glMatrixMode(GL_MODELVIEW);
381        glDisable(GL_TEXTURE_2D);
382        glEnable(GL_TEXTURE_EXTERNAL_OES);
383    } else {
384        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
385        glMatrixMode(GL_TEXTURE);
386        glLoadIdentity();
387        glMatrixMode(GL_MODELVIEW);
388        glDisable(GL_TEXTURE_EXTERNAL_OES);
389        glEnable(GL_TEXTURE_2D);
390    }
391
392    drawWithOpenGL(hw, clip);
393
394    glDisable(GL_TEXTURE_EXTERNAL_OES);
395    glDisable(GL_TEXTURE_2D);
396}
397
398// As documented in libhardware header, formats in the range
399// 0x100 - 0x1FF are specific to the HAL implementation, and
400// are known to have no alpha channel
401// TODO: move definition for device-specific range into
402// hardware.h, instead of using hard-coded values here.
403#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
404
405bool Layer::getOpacityForFormat(uint32_t format)
406{
407    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
408        return true;
409    }
410    PixelFormatInfo info;
411    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
412    // in case of error (unknown format), we assume no blending
413    return (err || info.h_alpha <= info.l_alpha);
414}
415
416
417bool Layer::isOpaque() const
418{
419    // if we don't have a buffer yet, we're translucent regardless of the
420    // layer's opaque flag.
421    if (mActiveBuffer == 0) {
422        return false;
423    }
424
425    // if the layer has the opaque flag, then we're always opaque,
426    // otherwise we use the current buffer's format.
427    return mOpaqueLayer || mCurrentOpacity;
428}
429
430bool Layer::isProtected() const
431{
432    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
433    return (activeBuffer != 0) &&
434            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
435}
436
437uint32_t Layer::doTransaction(uint32_t flags)
438{
439    ATRACE_CALL();
440
441    const Layer::State& front(drawingState());
442    const Layer::State& temp(currentState());
443
444    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
445                             (temp.requested.h != front.requested.h);
446
447    if (sizeChanged) {
448        // the size changed, we need to ask our client to request a new buffer
449        ALOGD_IF(DEBUG_RESIZE,
450                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
451                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
452                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
453                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
454                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
455                this, mCurrentScalingMode,
456                temp.active.w, temp.active.h,
457                temp.active.crop.left,
458                temp.active.crop.top,
459                temp.active.crop.right,
460                temp.active.crop.bottom,
461                temp.active.crop.getWidth(),
462                temp.active.crop.getHeight(),
463                temp.requested.w, temp.requested.h,
464                temp.requested.crop.left,
465                temp.requested.crop.top,
466                temp.requested.crop.right,
467                temp.requested.crop.bottom,
468                temp.requested.crop.getWidth(),
469                temp.requested.crop.getHeight(),
470                front.active.w, front.active.h,
471                front.active.crop.left,
472                front.active.crop.top,
473                front.active.crop.right,
474                front.active.crop.bottom,
475                front.active.crop.getWidth(),
476                front.active.crop.getHeight(),
477                front.requested.w, front.requested.h,
478                front.requested.crop.left,
479                front.requested.crop.top,
480                front.requested.crop.right,
481                front.requested.crop.bottom,
482                front.requested.crop.getWidth(),
483                front.requested.crop.getHeight());
484
485        // record the new size, form this point on, when the client request
486        // a buffer, it'll get the new size.
487        mSurfaceTexture->setDefaultBufferSize(
488                temp.requested.w, temp.requested.h);
489    }
490
491    if (!isFixedSize()) {
492
493        const bool resizePending = (temp.requested.w != temp.active.w) ||
494                                   (temp.requested.h != temp.active.h);
495
496        if (resizePending) {
497            // don't let LayerBase::doTransaction update the drawing state
498            // if we have a pending resize, unless we are in fixed-size mode.
499            // the drawing state will be updated only once we receive a buffer
500            // with the correct size.
501            //
502            // in particular, we want to make sure the clip (which is part
503            // of the geometry state) is latched together with the size but is
504            // latched immediately when no resizing is involved.
505
506            flags |= eDontUpdateGeometryState;
507        }
508    }
509
510    return LayerBase::doTransaction(flags);
511}
512
513bool Layer::isFixedSize() const {
514    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
515}
516
517bool Layer::isCropped() const {
518    return !mCurrentCrop.isEmpty();
519}
520
521// ----------------------------------------------------------------------------
522// pageflip handling...
523// ----------------------------------------------------------------------------
524
525bool Layer::onPreComposition() {
526    mRefreshPending = false;
527    return mQueuedFrames > 0;
528}
529
530void Layer::lockPageFlip(bool& recomputeVisibleRegions)
531{
532    ATRACE_CALL();
533
534    if (mQueuedFrames > 0) {
535
536        // if we've already called updateTexImage() without going through
537        // a composition step, we have to skip this layer at this point
538        // because we cannot call updateTeximage() without a corresponding
539        // compositionComplete() call.
540        // we'll trigger an update in onPreComposition().
541        if (mRefreshPending) {
542            mPostedDirtyRegion.clear();
543            return;
544        }
545
546        // Capture the old state of the layer for comparisons later
547        const bool oldOpacity = isOpaque();
548        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
549
550        // signal another event if we have more frames pending
551        if (android_atomic_dec(&mQueuedFrames) > 1) {
552            mFlinger->signalLayerUpdate();
553        }
554
555        struct Reject : public SurfaceTexture::BufferRejecter {
556            Layer::State& front;
557            Layer::State& current;
558            bool& recomputeVisibleRegions;
559            Reject(Layer::State& front, Layer::State& current,
560                    bool& recomputeVisibleRegions)
561                : front(front), current(current),
562                  recomputeVisibleRegions(recomputeVisibleRegions) {
563            }
564
565            virtual bool reject(const sp<GraphicBuffer>& buf,
566                    const BufferQueue::BufferItem& item) {
567                if (buf == NULL) {
568                    return false;
569                }
570
571                uint32_t bufWidth  = buf->getWidth();
572                uint32_t bufHeight = buf->getHeight();
573
574                // check that we received a buffer of the right size
575                // (Take the buffer's orientation into account)
576                if (item.mTransform & Transform::ROT_90) {
577                    swap(bufWidth, bufHeight);
578                }
579
580
581                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
582                if (front.active != front.requested) {
583
584                    if (isFixedSize ||
585                            (bufWidth == front.requested.w &&
586                             bufHeight == front.requested.h))
587                    {
588                        // Here we pretend the transaction happened by updating the
589                        // current and drawing states. Drawing state is only accessed
590                        // in this thread, no need to have it locked
591                        front.active = front.requested;
592
593                        // We also need to update the current state so that
594                        // we don't end-up overwriting the drawing state with
595                        // this stale current state during the next transaction
596                        //
597                        // NOTE: We don't need to hold the transaction lock here
598                        // because State::active is only accessed from this thread.
599                        current.active = front.active;
600
601                        // recompute visible region
602                        recomputeVisibleRegions = true;
603                    }
604
605                    ALOGD_IF(DEBUG_RESIZE,
606                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
607                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
608                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
609                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
610                            front.active.w, front.active.h,
611                            front.active.crop.left,
612                            front.active.crop.top,
613                            front.active.crop.right,
614                            front.active.crop.bottom,
615                            front.active.crop.getWidth(),
616                            front.active.crop.getHeight(),
617                            front.requested.w, front.requested.h,
618                            front.requested.crop.left,
619                            front.requested.crop.top,
620                            front.requested.crop.right,
621                            front.requested.crop.bottom,
622                            front.requested.crop.getWidth(),
623                            front.requested.crop.getHeight());
624                }
625
626                if (!isFixedSize) {
627                    if (front.active.w != bufWidth ||
628                        front.active.h != bufHeight) {
629                        // reject this buffer
630                        return true;
631                    }
632                }
633                return false;
634            }
635        };
636
637
638        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
639
640        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
641            // something happened!
642            recomputeVisibleRegions = true;
643            return;
644        }
645
646        // update the active buffer
647        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
648        if (mActiveBuffer == NULL) {
649            // this can only happen if the very first buffer was rejected.
650            return;
651        }
652
653        mRefreshPending = true;
654        mFrameLatencyNeeded = true;
655        mNeedHwcFence = true;
656        if (oldActiveBuffer == NULL) {
657             // the first time we receive a buffer, we need to trigger a
658             // geometry invalidation.
659             mFlinger->invalidateHwcGeometry();
660         }
661
662        Rect crop(mSurfaceTexture->getCurrentCrop());
663        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
664        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
665        if ((crop != mCurrentCrop) ||
666            (transform != mCurrentTransform) ||
667            (scalingMode != mCurrentScalingMode))
668        {
669            mCurrentCrop = crop;
670            mCurrentTransform = transform;
671            mCurrentScalingMode = scalingMode;
672            mFlinger->invalidateHwcGeometry();
673        }
674
675        if (oldActiveBuffer != NULL) {
676            uint32_t bufWidth  = mActiveBuffer->getWidth();
677            uint32_t bufHeight = mActiveBuffer->getHeight();
678            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
679                bufHeight != uint32_t(oldActiveBuffer->height)) {
680                mFlinger->invalidateHwcGeometry();
681            }
682        }
683
684        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
685        if (oldOpacity != isOpaque()) {
686            recomputeVisibleRegions = true;
687        }
688
689        // FIXME: mPostedDirtyRegion = dirty & bounds
690        const Layer::State& front(drawingState());
691        mPostedDirtyRegion.set(front.active.w, front.active.h);
692
693        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
694        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
695    }
696}
697
698void Layer::unlockPageFlip(
699        const Transform& planeTransform, Region& outDirtyRegion)
700{
701    ATRACE_CALL();
702
703    Region postedRegion(mPostedDirtyRegion);
704    if (!postedRegion.isEmpty()) {
705        mPostedDirtyRegion.clear();
706        if (!visibleRegionScreen.isEmpty()) {
707            // The dirty region is given in the layer's coordinate space
708            // transform the dirty region by the surface's transformation
709            // and the global transformation.
710            const Layer::State& s(drawingState());
711            const Transform tr(planeTransform * s.transform);
712            postedRegion = tr.transform(postedRegion);
713
714            // At this point, the dirty region is in screen space.
715            // Make sure it's constrained by the visible region (which
716            // is in screen space as well).
717            postedRegion.andSelf(visibleRegionScreen);
718            outDirtyRegion.orSelf(postedRegion);
719        }
720    }
721}
722
723void Layer::dump(String8& result, char* buffer, size_t SIZE) const
724{
725    LayerBaseClient::dump(result, buffer, SIZE);
726
727    sp<const GraphicBuffer> buf0(mActiveBuffer);
728    uint32_t w0=0, h0=0, s0=0, f0=0;
729    if (buf0 != 0) {
730        w0 = buf0->getWidth();
731        h0 = buf0->getHeight();
732        s0 = buf0->getStride();
733        f0 = buf0->format;
734    }
735    snprintf(buffer, SIZE,
736            "      "
737            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
738            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
739            mFormat, w0, h0, s0,f0,
740            getTransformHint(), mQueuedFrames, mRefreshPending);
741
742    result.append(buffer);
743
744    if (mSurfaceTexture != 0) {
745        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
746    }
747}
748
749void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
750{
751    LayerBaseClient::dumpStats(result, buffer, SIZE);
752    const size_t o = mFrameLatencyOffset;
753    const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
754    const nsecs_t period = hw.getRefreshPeriod();
755    result.appendFormat("%lld\n", period);
756    for (size_t i=0 ; i<128 ; i++) {
757        const size_t index = (o+i) % 128;
758        const nsecs_t time_app   = mFrameStats[index].timestamp;
759        const nsecs_t time_set   = mFrameStats[index].set;
760        const nsecs_t time_vsync = mFrameStats[index].vsync;
761        result.appendFormat("%lld\t%lld\t%lld\n",
762                time_app,
763                time_vsync,
764                time_set);
765    }
766    result.append("\n");
767}
768
769void Layer::clearStats()
770{
771    LayerBaseClient::clearStats();
772    memset(mFrameStats, 0, sizeof(mFrameStats));
773}
774
775uint32_t Layer::getEffectiveUsage(uint32_t usage) const
776{
777    // TODO: should we do something special if mSecure is set?
778    if (mProtectedByApp) {
779        // need a hardware-protected path to external video sink
780        usage |= GraphicBuffer::USAGE_PROTECTED;
781    }
782    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
783    return usage;
784}
785
786uint32_t Layer::getTransformHint() const {
787    uint32_t orientation = 0;
788    if (!mFlinger->mDebugDisableTransformHint) {
789        orientation = getPlaneOrientation();
790        if (orientation & Transform::ROT_INVALID) {
791            orientation = 0;
792        }
793    }
794    return orientation;
795}
796
797// ---------------------------------------------------------------------------
798
799
800}; // namespace android
801