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