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