Layer.cpp revision 6905205c8d130b6ea3a813c1b9283492ed183367
15b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org/*
25b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * Copyright (C) 2007 The Android Open Source Project
35b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org *
45b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
55b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * you may not use this file except in compliance with the License.
65b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * You may obtain a copy of the License at
75b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org *
85b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org *      http://www.apache.org/licenses/LICENSE-2.0
95b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org *
105b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * Unless required by applicable law or agreed to in writing, software
115b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
125b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * See the License for the specific language governing permissions and
145b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * limitations under the License.
155b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org */
165b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
175b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#define ATRACE_TAG ATRACE_TAG_GRAPHICS
185b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
195b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <stdlib.h>
205b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <stdint.h>
215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <sys/types.h>
225b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <math.h>
235b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
245b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <cutils/compiler.h>
255b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <cutils/native_handle.h>
265b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <cutils/properties.h>
275b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
285b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/Errors.h>
295b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/Log.h>
305b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/StopWatch.h>
315b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/Trace.h>
325b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
335b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <ui/GraphicBuffer.h>
345b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <ui/PixelFormat.h>
355b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
365b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <gui/Surface.h>
375b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
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    /*
257     * Transformations are applied in this order:
258     * 1) buffer orientation/flip/mirror
259     * 2) state transformation (window manager)
260     * 3) layer orientation (screen orientation)
261     * (NOTE: the matrices are multiplied in reverse order)
262     */
263
264    const Transform bufferOrientation(mCurrentTransform);
265    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
266
267    // this gives us only the "orientation" component of the transform
268    const uint32_t finalTransform = tr.getOrientation();
269
270    // we can only handle simple transformation
271    if (finalTransform & Transform::ROT_INVALID) {
272        layer.setSkip(true);
273    } else {
274        layer.setTransform(finalTransform);
275    }
276    layer.setCrop(computeBufferCrop());
277}
278
279void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
280        HWComposer::HWCLayerInterface& layer) {
281    LayerBaseClient::setPerFrameData(hw, layer);
282    // NOTE: buffer can be NULL if the client never drew into this
283    // layer yet, or if we ran out of memory
284    layer.setBuffer(mActiveBuffer);
285}
286
287void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
288        HWComposer::HWCLayerInterface& layer) {
289    int fenceFd = -1;
290
291    // TODO: there is a possible optimization here: we only need to set the
292    // acquire fence the first time a new buffer is acquired on EACH display.
293
294    if (layer.getCompositionType() == HWC_OVERLAY) {
295        sp<Fence> fence = mSurfaceTexture->getCurrentFence();
296        if (fence.get()) {
297            fenceFd = fence->dup();
298            if (fenceFd == -1) {
299                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
300            }
301        }
302    }
303    layer.setAcquireFenceFd(fenceFd);
304}
305
306void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
307{
308    ATRACE_CALL();
309
310    if (CC_UNLIKELY(mActiveBuffer == 0)) {
311        // the texture has not been created yet, this Layer has
312        // in fact never been drawn into. This happens frequently with
313        // SurfaceView because the WindowManager can't know when the client
314        // has drawn the first time.
315
316        // If there is nothing under us, we paint the screen in black, otherwise
317        // we just skip this update.
318
319        // figure out if there is something below us
320        Region under;
321        const SurfaceFlinger::LayerVector& drawingLayers(
322                mFlinger->mDrawingState.layersSortedByZ);
323        const size_t count = drawingLayers.size();
324        for (size_t i=0 ; i<count ; ++i) {
325            const sp<LayerBase>& layer(drawingLayers[i]);
326            if (layer.get() == static_cast<LayerBase const*>(this))
327                break;
328            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
329        }
330        // if not everything below us is covered, we plug the holes!
331        Region holes(clip.subtract(under));
332        if (!holes.isEmpty()) {
333            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
334        }
335        return;
336    }
337
338    status_t err = mSurfaceTexture->doGLFenceWait();
339    if (err != OK) {
340        ALOGE("onDraw: failed waiting for fence: %d", err);
341        // Go ahead and draw the buffer anyway; no matter what we do the screen
342        // is probably going to have something visibly wrong.
343    }
344
345    if (!isProtected()) {
346        // TODO: we could be more subtle with isFixedSize()
347        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
348
349        // Query the texture matrix given our current filtering mode.
350        float textureMatrix[16];
351        mSurfaceTexture->setFilteringEnabled(useFiltering);
352        mSurfaceTexture->getTransformMatrix(textureMatrix);
353
354        // Set things up for texturing.
355        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
356        GLenum filter = GL_NEAREST;
357        if (useFiltering) {
358            filter = GL_LINEAR;
359        }
360        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
361        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
362        glMatrixMode(GL_TEXTURE);
363        glLoadMatrixf(textureMatrix);
364        glMatrixMode(GL_MODELVIEW);
365        glDisable(GL_TEXTURE_2D);
366        glEnable(GL_TEXTURE_EXTERNAL_OES);
367    } else {
368        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
369        glMatrixMode(GL_TEXTURE);
370        glLoadIdentity();
371        glMatrixMode(GL_MODELVIEW);
372        glDisable(GL_TEXTURE_EXTERNAL_OES);
373        glEnable(GL_TEXTURE_2D);
374    }
375
376    drawWithOpenGL(hw, clip);
377
378    glDisable(GL_TEXTURE_EXTERNAL_OES);
379    glDisable(GL_TEXTURE_2D);
380}
381
382// As documented in libhardware header, formats in the range
383// 0x100 - 0x1FF are specific to the HAL implementation, and
384// are known to have no alpha channel
385// TODO: move definition for device-specific range into
386// hardware.h, instead of using hard-coded values here.
387#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
388
389bool Layer::getOpacityForFormat(uint32_t format)
390{
391    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
392        return true;
393    }
394    PixelFormatInfo info;
395    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
396    // in case of error (unknown format), we assume no blending
397    return (err || info.h_alpha <= info.l_alpha);
398}
399
400
401bool Layer::isOpaque() const
402{
403    // if we don't have a buffer yet, we're translucent regardless of the
404    // layer's opaque flag.
405    if (mActiveBuffer == 0) {
406        return false;
407    }
408
409    // if the layer has the opaque flag, then we're always opaque,
410    // otherwise we use the current buffer's format.
411    return mOpaqueLayer || mCurrentOpacity;
412}
413
414bool Layer::isProtected() const
415{
416    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
417    return (activeBuffer != 0) &&
418            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
419}
420
421uint32_t Layer::doTransaction(uint32_t flags)
422{
423    ATRACE_CALL();
424
425    const Layer::State& front(drawingState());
426    const Layer::State& temp(currentState());
427
428    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
429                             (temp.requested.h != front.requested.h);
430
431    if (sizeChanged) {
432        // the size changed, we need to ask our client to request a new buffer
433        ALOGD_IF(DEBUG_RESIZE,
434                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
435                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
436                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
437                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
438                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
439                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
440                temp.active.w, temp.active.h,
441                temp.active.crop.left,
442                temp.active.crop.top,
443                temp.active.crop.right,
444                temp.active.crop.bottom,
445                temp.active.crop.getWidth(),
446                temp.active.crop.getHeight(),
447                temp.requested.w, temp.requested.h,
448                temp.requested.crop.left,
449                temp.requested.crop.top,
450                temp.requested.crop.right,
451                temp.requested.crop.bottom,
452                temp.requested.crop.getWidth(),
453                temp.requested.crop.getHeight(),
454                front.active.w, front.active.h,
455                front.active.crop.left,
456                front.active.crop.top,
457                front.active.crop.right,
458                front.active.crop.bottom,
459                front.active.crop.getWidth(),
460                front.active.crop.getHeight(),
461                front.requested.w, front.requested.h,
462                front.requested.crop.left,
463                front.requested.crop.top,
464                front.requested.crop.right,
465                front.requested.crop.bottom,
466                front.requested.crop.getWidth(),
467                front.requested.crop.getHeight());
468
469        // record the new size, form this point on, when the client request
470        // a buffer, it'll get the new size.
471        mSurfaceTexture->setDefaultBufferSize(
472                temp.requested.w, temp.requested.h);
473    }
474
475    if (!isFixedSize()) {
476
477        const bool resizePending = (temp.requested.w != temp.active.w) ||
478                                   (temp.requested.h != temp.active.h);
479
480        if (resizePending) {
481            // don't let LayerBase::doTransaction update the drawing state
482            // if we have a pending resize, unless we are in fixed-size mode.
483            // the drawing state will be updated only once we receive a buffer
484            // with the correct size.
485            //
486            // in particular, we want to make sure the clip (which is part
487            // of the geometry state) is latched together with the size but is
488            // latched immediately when no resizing is involved.
489
490            flags |= eDontUpdateGeometryState;
491        }
492    }
493
494    return LayerBase::doTransaction(flags);
495}
496
497bool Layer::isFixedSize() const {
498    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
499}
500
501bool Layer::isCropped() const {
502    return !mCurrentCrop.isEmpty();
503}
504
505// ----------------------------------------------------------------------------
506// pageflip handling...
507// ----------------------------------------------------------------------------
508
509bool Layer::onPreComposition() {
510    mRefreshPending = false;
511    return mQueuedFrames > 0;
512}
513
514void Layer::onPostComposition() {
515    if (mFrameLatencyNeeded) {
516        const HWComposer& hwc = mFlinger->getHwComposer();
517        const size_t offset = mFrameLatencyOffset;
518        mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp();
519        mFrameStats[offset].set = systemTime();
520        mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
521        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
522        mFrameLatencyNeeded = false;
523    }
524}
525
526Region Layer::latchBuffer(bool& recomputeVisibleRegions)
527{
528    ATRACE_CALL();
529
530    Region outDirtyRegion;
531    if (mQueuedFrames > 0) {
532
533        // if we've already called updateTexImage() without going through
534        // a composition step, we have to skip this layer at this point
535        // because we cannot call updateTeximage() without a corresponding
536        // compositionComplete() call.
537        // we'll trigger an update in onPreComposition().
538        if (mRefreshPending) {
539            return outDirtyRegion;
540        }
541
542        // Capture the old state of the layer for comparisons later
543        const bool oldOpacity = isOpaque();
544        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
545
546        // signal another event if we have more frames pending
547        if (android_atomic_dec(&mQueuedFrames) > 1) {
548            mFlinger->signalLayerUpdate();
549        }
550
551        struct Reject : public SurfaceTexture::BufferRejecter {
552            Layer::State& front;
553            Layer::State& current;
554            bool& recomputeVisibleRegions;
555            Reject(Layer::State& front, Layer::State& current,
556                    bool& recomputeVisibleRegions)
557                : front(front), current(current),
558                  recomputeVisibleRegions(recomputeVisibleRegions) {
559            }
560
561            virtual bool reject(const sp<GraphicBuffer>& buf,
562                    const BufferQueue::BufferItem& item) {
563                if (buf == NULL) {
564                    return false;
565                }
566
567                uint32_t bufWidth  = buf->getWidth();
568                uint32_t bufHeight = buf->getHeight();
569
570                // check that we received a buffer of the right size
571                // (Take the buffer's orientation into account)
572                if (item.mTransform & Transform::ROT_90) {
573                    swap(bufWidth, bufHeight);
574                }
575
576
577                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
578                if (front.active != front.requested) {
579
580                    if (isFixedSize ||
581                            (bufWidth == front.requested.w &&
582                             bufHeight == front.requested.h))
583                    {
584                        // Here we pretend the transaction happened by updating the
585                        // current and drawing states. Drawing state is only accessed
586                        // in this thread, no need to have it locked
587                        front.active = front.requested;
588
589                        // We also need to update the current state so that
590                        // we don't end-up overwriting the drawing state with
591                        // this stale current state during the next transaction
592                        //
593                        // NOTE: We don't need to hold the transaction lock here
594                        // because State::active is only accessed from this thread.
595                        current.active = front.active;
596
597                        // recompute visible region
598                        recomputeVisibleRegions = true;
599                    }
600
601                    ALOGD_IF(DEBUG_RESIZE,
602                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
603                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
604                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
605                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
606                            front.active.w, front.active.h,
607                            front.active.crop.left,
608                            front.active.crop.top,
609                            front.active.crop.right,
610                            front.active.crop.bottom,
611                            front.active.crop.getWidth(),
612                            front.active.crop.getHeight(),
613                            front.requested.w, front.requested.h,
614                            front.requested.crop.left,
615                            front.requested.crop.top,
616                            front.requested.crop.right,
617                            front.requested.crop.bottom,
618                            front.requested.crop.getWidth(),
619                            front.requested.crop.getHeight());
620                }
621
622                if (!isFixedSize) {
623                    if (front.active.w != bufWidth ||
624                        front.active.h != bufHeight) {
625                        // reject this buffer
626                        return true;
627                    }
628                }
629                return false;
630            }
631        };
632
633
634        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
635
636        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
637            // something happened!
638            recomputeVisibleRegions = true;
639            return outDirtyRegion;
640        }
641
642        // update the active buffer
643        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
644        if (mActiveBuffer == NULL) {
645            // this can only happen if the very first buffer was rejected.
646            return outDirtyRegion;
647        }
648
649        mRefreshPending = true;
650        mFrameLatencyNeeded = true;
651        if (oldActiveBuffer == NULL) {
652             // the first time we receive a buffer, we need to trigger a
653             // geometry invalidation.
654             mFlinger->invalidateHwcGeometry();
655         }
656
657        Rect crop(mSurfaceTexture->getCurrentCrop());
658        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
659        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
660        if ((crop != mCurrentCrop) ||
661            (transform != mCurrentTransform) ||
662            (scalingMode != mCurrentScalingMode))
663        {
664            mCurrentCrop = crop;
665            mCurrentTransform = transform;
666            mCurrentScalingMode = scalingMode;
667            mFlinger->invalidateHwcGeometry();
668        }
669
670        if (oldActiveBuffer != NULL) {
671            uint32_t bufWidth  = mActiveBuffer->getWidth();
672            uint32_t bufHeight = mActiveBuffer->getHeight();
673            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
674                bufHeight != uint32_t(oldActiveBuffer->height)) {
675                mFlinger->invalidateHwcGeometry();
676            }
677        }
678
679        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
680        if (oldOpacity != isOpaque()) {
681            recomputeVisibleRegions = true;
682        }
683
684        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
685        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
686
687        // FIXME: postedRegion should be dirty & bounds
688        const Layer::State& front(drawingState());
689        Region dirtyRegion(Rect(front.active.w, front.active.h));
690
691        // transform the dirty region to window-manager space
692        outDirtyRegion = (front.transform.transform(dirtyRegion));
693    }
694    return outDirtyRegion;
695}
696
697void Layer::dump(String8& result, char* buffer, size_t SIZE) const
698{
699    LayerBaseClient::dump(result, buffer, SIZE);
700
701    sp<const GraphicBuffer> buf0(mActiveBuffer);
702    uint32_t w0=0, h0=0, s0=0, f0=0;
703    if (buf0 != 0) {
704        w0 = buf0->getWidth();
705        h0 = buf0->getHeight();
706        s0 = buf0->getStride();
707        f0 = buf0->format;
708    }
709    snprintf(buffer, SIZE,
710            "      "
711            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
712            " queued-frames=%d, mRefreshPending=%d\n",
713            mFormat, w0, h0, s0,f0,
714            mQueuedFrames, mRefreshPending);
715
716    result.append(buffer);
717
718    if (mSurfaceTexture != 0) {
719        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
720    }
721}
722
723void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
724{
725    LayerBaseClient::dumpStats(result, buffer, SIZE);
726    const size_t o = mFrameLatencyOffset;
727    const nsecs_t period =
728            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
729    result.appendFormat("%lld\n", period);
730    for (size_t i=0 ; i<128 ; i++) {
731        const size_t index = (o+i) % 128;
732        const nsecs_t time_app   = mFrameStats[index].timestamp;
733        const nsecs_t time_set   = mFrameStats[index].set;
734        const nsecs_t time_vsync = mFrameStats[index].vsync;
735        result.appendFormat("%lld\t%lld\t%lld\n",
736                time_app,
737                time_vsync,
738                time_set);
739    }
740    result.append("\n");
741}
742
743void Layer::clearStats()
744{
745    LayerBaseClient::clearStats();
746    memset(mFrameStats, 0, sizeof(mFrameStats));
747}
748
749uint32_t Layer::getEffectiveUsage(uint32_t usage) const
750{
751    // TODO: should we do something special if mSecure is set?
752    if (mProtectedByApp) {
753        // need a hardware-protected path to external video sink
754        usage |= GraphicBuffer::USAGE_PROTECTED;
755    }
756    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
757    return usage;
758}
759
760void Layer::updateTransformHint() const {
761    uint32_t orientation = 0;
762    if (!mFlinger->mDebugDisableTransformHint) {
763        // The transform hint is used to improve performance on the main
764        // display -- we can only have a single transform hint, it cannot
765        // apply to all displays.
766        // This is why we use the default display here. This is not an
767        // oversight.
768        sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
769        const Transform& planeTransform(hw->getTransform());
770        orientation = planeTransform.getOrientation();
771        if (orientation & Transform::ROT_INVALID) {
772            orientation = 0;
773        }
774    }
775    mSurfaceTexture->setTransformHint(orientation);
776}
777
778// ---------------------------------------------------------------------------
779
780
781}; // namespace android
782