Layer.cpp revision 97eba8904c2f221c42a9473407223a4c3a213f75
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        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
77    }
78}
79
80void Layer::onFirstRef()
81{
82    LayerBaseClient::onFirstRef();
83
84    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
85    sp<BufferQueue> bq = new SurfaceTextureLayer();
86    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
87            GL_TEXTURE_EXTERNAL_OES, false, bq);
88
89    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
90    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
91    mSurfaceFlingerConsumer->setSynchronousMode(true);
92
93#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
94#warning "disabling triple buffering"
95    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
96#else
97    mSurfaceFlingerConsumer->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    mSurfaceFlingerConsumer->abandon();
119}
120
121void Layer::setName(const String8& name) {
122    LayerBase::setName(name);
123    mSurfaceFlingerConsumer->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->mSurfaceFlingerConsumer->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 mSurfaceFlingerConsumer->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    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
181    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
182    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
183
184    return NO_ERROR;
185}
186
187Rect Layer::computeBufferCrop() const {
188    // Start with the SurfaceFlingerConsumer'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        // SurfaceFlingerConsumer.
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 = mSurfaceFlingerConsumer->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    // Bind the current buffer to the GL texture, and wait for it to be
331    // ready for us to draw into.
332    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
333    if (err != NO_ERROR) {
334        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
335        // Go ahead and draw the buffer anyway; no matter what we do the screen
336        // is probably going to have something visibly wrong.
337    }
338
339    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
340
341    if (!blackOutLayer) {
342        // TODO: we could be more subtle with isFixedSize()
343        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
344
345        // Query the texture matrix given our current filtering mode.
346        float textureMatrix[16];
347        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
348        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
349
350        // Set things up for texturing.
351        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
352        GLenum filter = GL_NEAREST;
353        if (useFiltering) {
354            filter = GL_LINEAR;
355        }
356        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
357        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
358        glMatrixMode(GL_TEXTURE);
359        glLoadMatrixf(textureMatrix);
360        glMatrixMode(GL_MODELVIEW);
361        glDisable(GL_TEXTURE_2D);
362        glEnable(GL_TEXTURE_EXTERNAL_OES);
363    } else {
364        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
365        glMatrixMode(GL_TEXTURE);
366        glLoadIdentity();
367        glMatrixMode(GL_MODELVIEW);
368        glDisable(GL_TEXTURE_EXTERNAL_OES);
369        glEnable(GL_TEXTURE_2D);
370    }
371
372    drawWithOpenGL(hw, clip);
373
374    glDisable(GL_TEXTURE_EXTERNAL_OES);
375    glDisable(GL_TEXTURE_2D);
376}
377
378// As documented in libhardware header, formats in the range
379// 0x100 - 0x1FF are specific to the HAL implementation, and
380// are known to have no alpha channel
381// TODO: move definition for device-specific range into
382// hardware.h, instead of using hard-coded values here.
383#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
384
385bool Layer::getOpacityForFormat(uint32_t format)
386{
387    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
388        return true;
389    }
390    PixelFormatInfo info;
391    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
392    // in case of error (unknown format), we assume no blending
393    return (err || info.h_alpha <= info.l_alpha);
394}
395
396
397bool Layer::isOpaque() const
398{
399    // if we don't have a buffer yet, we're translucent regardless of the
400    // layer's opaque flag.
401    if (mActiveBuffer == 0) {
402        return false;
403    }
404
405    // if the layer has the opaque flag, then we're always opaque,
406    // otherwise we use the current buffer's format.
407    return mOpaqueLayer || mCurrentOpacity;
408}
409
410bool Layer::isProtected() const
411{
412    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
413    return (activeBuffer != 0) &&
414            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
415}
416
417uint32_t Layer::doTransaction(uint32_t flags)
418{
419    ATRACE_CALL();
420
421    const Layer::State& front(drawingState());
422    const Layer::State& temp(currentState());
423
424    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
425                             (temp.requested.h != front.requested.h);
426
427    if (sizeChanged) {
428        // the size changed, we need to ask our client to request a new buffer
429        ALOGD_IF(DEBUG_RESIZE,
430                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
431                "  current={ 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                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
434                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
435                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
436                temp.active.w, temp.active.h,
437                temp.active.crop.left,
438                temp.active.crop.top,
439                temp.active.crop.right,
440                temp.active.crop.bottom,
441                temp.active.crop.getWidth(),
442                temp.active.crop.getHeight(),
443                temp.requested.w, temp.requested.h,
444                temp.requested.crop.left,
445                temp.requested.crop.top,
446                temp.requested.crop.right,
447                temp.requested.crop.bottom,
448                temp.requested.crop.getWidth(),
449                temp.requested.crop.getHeight(),
450                front.active.w, front.active.h,
451                front.active.crop.left,
452                front.active.crop.top,
453                front.active.crop.right,
454                front.active.crop.bottom,
455                front.active.crop.getWidth(),
456                front.active.crop.getHeight(),
457                front.requested.w, front.requested.h,
458                front.requested.crop.left,
459                front.requested.crop.top,
460                front.requested.crop.right,
461                front.requested.crop.bottom,
462                front.requested.crop.getWidth(),
463                front.requested.crop.getHeight());
464
465        // record the new size, form this point on, when the client request
466        // a buffer, it'll get the new size.
467        mSurfaceFlingerConsumer->setDefaultBufferSize(
468                temp.requested.w, temp.requested.h);
469    }
470
471    if (!isFixedSize()) {
472
473        const bool resizePending = (temp.requested.w != temp.active.w) ||
474                                   (temp.requested.h != temp.active.h);
475
476        if (resizePending) {
477            // don't let LayerBase::doTransaction update the drawing state
478            // if we have a pending resize, unless we are in fixed-size mode.
479            // the drawing state will be updated only once we receive a buffer
480            // with the correct size.
481            //
482            // in particular, we want to make sure the clip (which is part
483            // of the geometry state) is latched together with the size but is
484            // latched immediately when no resizing is involved.
485
486            flags |= eDontUpdateGeometryState;
487        }
488    }
489
490    return LayerBase::doTransaction(flags);
491}
492
493bool Layer::isFixedSize() const {
494    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
495}
496
497bool Layer::isCropped() const {
498    return !mCurrentCrop.isEmpty();
499}
500
501// ----------------------------------------------------------------------------
502// pageflip handling...
503// ----------------------------------------------------------------------------
504
505bool Layer::onPreComposition() {
506    mRefreshPending = false;
507    return mQueuedFrames > 0;
508}
509
510void Layer::onPostComposition() {
511    if (mFrameLatencyNeeded) {
512        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
513        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
514
515        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
516        if (frameReadyFence != NULL) {
517            mFrameTracker.setFrameReadyFence(frameReadyFence);
518        } else {
519            // There was no fence for this frame, so assume that it was ready
520            // to be presented at the desired present time.
521            mFrameTracker.setFrameReadyTime(desiredPresentTime);
522        }
523
524        const HWComposer& hwc = mFlinger->getHwComposer();
525        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
526        // XXX: Temporarily don't use the present fence from HWC to work
527        // around a driver bug.
528        presentFence.clear();
529        if (presentFence != NULL) {
530            mFrameTracker.setActualPresentFence(presentFence);
531        } else {
532            // The HWC doesn't support present fences, so use the refresh
533            // timestamp instead.
534            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
535            mFrameTracker.setActualPresentTime(presentTime);
536        }
537
538        mFrameTracker.advanceFrame();
539        mFrameLatencyNeeded = false;
540    }
541}
542
543bool Layer::isVisible() const {
544    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
545}
546
547Region Layer::latchBuffer(bool& recomputeVisibleRegions)
548{
549    ATRACE_CALL();
550
551    Region outDirtyRegion;
552    if (mQueuedFrames > 0) {
553
554        // if we've already called updateTexImage() without going through
555        // a composition step, we have to skip this layer at this point
556        // because we cannot call updateTeximage() without a corresponding
557        // compositionComplete() call.
558        // we'll trigger an update in onPreComposition().
559        if (mRefreshPending) {
560            return outDirtyRegion;
561        }
562
563        // Capture the old state of the layer for comparisons later
564        const bool oldOpacity = isOpaque();
565        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
566
567        // signal another event if we have more frames pending
568        if (android_atomic_dec(&mQueuedFrames) > 1) {
569            mFlinger->signalLayerUpdate();
570        }
571
572        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
573            Layer::State& front;
574            Layer::State& current;
575            bool& recomputeVisibleRegions;
576            Reject(Layer::State& front, Layer::State& current,
577                    bool& recomputeVisibleRegions)
578                : front(front), current(current),
579                  recomputeVisibleRegions(recomputeVisibleRegions) {
580            }
581
582            virtual bool reject(const sp<GraphicBuffer>& buf,
583                    const BufferQueue::BufferItem& item) {
584                if (buf == NULL) {
585                    return false;
586                }
587
588                uint32_t bufWidth  = buf->getWidth();
589                uint32_t bufHeight = buf->getHeight();
590
591                // check that we received a buffer of the right size
592                // (Take the buffer's orientation into account)
593                if (item.mTransform & Transform::ROT_90) {
594                    swap(bufWidth, bufHeight);
595                }
596
597
598                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
599                if (front.active != front.requested) {
600
601                    if (isFixedSize ||
602                            (bufWidth == front.requested.w &&
603                             bufHeight == front.requested.h))
604                    {
605                        // Here we pretend the transaction happened by updating the
606                        // current and drawing states. Drawing state is only accessed
607                        // in this thread, no need to have it locked
608                        front.active = front.requested;
609
610                        // We also need to update the current state so that
611                        // we don't end-up overwriting the drawing state with
612                        // this stale current state during the next transaction
613                        //
614                        // NOTE: We don't need to hold the transaction lock here
615                        // because State::active is only accessed from this thread.
616                        current.active = front.active;
617
618                        // recompute visible region
619                        recomputeVisibleRegions = true;
620                    }
621
622                    ALOGD_IF(DEBUG_RESIZE,
623                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
624                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
625                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
626                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
627                            front.active.w, front.active.h,
628                            front.active.crop.left,
629                            front.active.crop.top,
630                            front.active.crop.right,
631                            front.active.crop.bottom,
632                            front.active.crop.getWidth(),
633                            front.active.crop.getHeight(),
634                            front.requested.w, front.requested.h,
635                            front.requested.crop.left,
636                            front.requested.crop.top,
637                            front.requested.crop.right,
638                            front.requested.crop.bottom,
639                            front.requested.crop.getWidth(),
640                            front.requested.crop.getHeight());
641                }
642
643                if (!isFixedSize) {
644                    if (front.active.w != bufWidth ||
645                        front.active.h != bufHeight) {
646                        // reject this buffer
647                        return true;
648                    }
649                }
650                return false;
651            }
652        };
653
654
655        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
656
657        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
658            // something happened!
659            recomputeVisibleRegions = true;
660            return outDirtyRegion;
661        }
662
663        // update the active buffer
664        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
665        if (mActiveBuffer == NULL) {
666            // this can only happen if the very first buffer was rejected.
667            return outDirtyRegion;
668        }
669
670        mRefreshPending = true;
671        mFrameLatencyNeeded = true;
672        if (oldActiveBuffer == NULL) {
673             // the first time we receive a buffer, we need to trigger a
674             // geometry invalidation.
675            recomputeVisibleRegions = true;
676         }
677
678        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
679        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
680        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
681        if ((crop != mCurrentCrop) ||
682            (transform != mCurrentTransform) ||
683            (scalingMode != mCurrentScalingMode))
684        {
685            mCurrentCrop = crop;
686            mCurrentTransform = transform;
687            mCurrentScalingMode = scalingMode;
688            recomputeVisibleRegions = true;
689        }
690
691        if (oldActiveBuffer != NULL) {
692            uint32_t bufWidth  = mActiveBuffer->getWidth();
693            uint32_t bufHeight = mActiveBuffer->getHeight();
694            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
695                bufHeight != uint32_t(oldActiveBuffer->height)) {
696                recomputeVisibleRegions = true;
697            }
698        }
699
700        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
701        if (oldOpacity != isOpaque()) {
702            recomputeVisibleRegions = true;
703        }
704
705        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
706        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
707
708        // FIXME: postedRegion should be dirty & bounds
709        const Layer::State& front(drawingState());
710        Region dirtyRegion(Rect(front.active.w, front.active.h));
711
712        // transform the dirty region to window-manager space
713        outDirtyRegion = (front.transform.transform(dirtyRegion));
714    }
715    return outDirtyRegion;
716}
717
718void Layer::dump(String8& result, char* buffer, size_t SIZE) const
719{
720    LayerBaseClient::dump(result, buffer, SIZE);
721
722    sp<const GraphicBuffer> buf0(mActiveBuffer);
723    uint32_t w0=0, h0=0, s0=0, f0=0;
724    if (buf0 != 0) {
725        w0 = buf0->getWidth();
726        h0 = buf0->getHeight();
727        s0 = buf0->getStride();
728        f0 = buf0->format;
729    }
730    snprintf(buffer, SIZE,
731            "      "
732            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
733            " queued-frames=%d, mRefreshPending=%d\n",
734            mFormat, w0, h0, s0,f0,
735            mQueuedFrames, mRefreshPending);
736
737    result.append(buffer);
738
739    if (mSurfaceFlingerConsumer != 0) {
740        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
741    }
742}
743
744void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
745{
746    LayerBaseClient::dumpStats(result, buffer, SIZE);
747    const nsecs_t period =
748            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
749    result.appendFormat("%lld\n", period);
750    mFrameTracker.dump(result);
751}
752
753void Layer::clearStats()
754{
755    LayerBaseClient::clearStats();
756    mFrameTracker.clear();
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 sp<const DisplayDevice>& hw) const {
771    uint32_t orientation = 0;
772    if (!mFlinger->mDebugDisableTransformHint) {
773        // The transform hint is used to improve performance, but we can
774        // only have a single transform hint, it cannot
775        // apply to all displays.
776        const Transform& planeTransform(hw->getTransform());
777        orientation = planeTransform.getOrientation();
778        if (orientation & Transform::ROT_INVALID) {
779            orientation = 0;
780        }
781    }
782    mSurfaceFlingerConsumer->setTransformHint(orientation);
783}
784
785// ---------------------------------------------------------------------------
786
787
788}; // namespace android
789