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