Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 584fcb32 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android Git Automerger
Browse files

am 2c8207e9: add the ability to reject buffers in SurfaceTexture::updateTexImage

* commit '2c8207e9':
  add the ability to reject buffers in SurfaceTexture::updateTexImage
parents c7c8334f 2c8207e9
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -236,6 +236,19 @@ protected:
    static bool isExternalFormat(uint32_t format);

private:
    // this version of updateTexImage() takes a functor used to reject or not
    // the newly acquired buffer.
    // this API is TEMPORARY and intended to be used by SurfaceFlinger only,
    // which is why class Layer is made a friend of SurfaceTexture below.
    class BufferRejecter {
        friend class SurfaceTexture;
        virtual bool reject(const sp<GraphicBuffer>& buf,
                const BufferQueue::BufferItem& item) = 0;
    protected:
        virtual ~BufferRejecter() { }
    };
    friend class Layer;
    status_t updateTexImage(BufferRejecter* rejecter);

    // createImage creates a new EGLImage from a GraphicBuffer.
    EGLImageKHR createImage(EGLDisplay dpy,
+14 −0
Original line number Diff line number Diff line
@@ -176,6 +176,10 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
}

status_t SurfaceTexture::updateTexImage() {
    return SurfaceTexture::updateTexImage(NULL);
}

status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) {
    ATRACE_CALL();
    ST_LOGV("updateTexImage");
    Mutex::Autolock lock(mMutex);
@@ -228,6 +232,16 @@ status_t SurfaceTexture::updateTexImage() {
            mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
        }

        // we call the rejecter here, in case the caller has a reason to
        // not accept this buffer. this is used by SurfaceFlinger to
        // reject buffers which have the wrong size
        if (rejecter && rejecter->reject(mEGLSlots[buf].mGraphicBuffer, item)) {
            mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence);
            mEGLSlots[buf].mFence = EGL_NO_SYNC_KHR;
            glBindTexture(mTexTarget, mTexName);
            return NO_ERROR;
        }

        // Update the GL texture object. We may have to do this even when
        // item.mGraphicBuffer == NULL, if we destroyed the EGLImage when
        // detaching from a context but the buffer has not been re-allocated.
+95 −67
Original line number Diff line number Diff line
@@ -527,31 +527,34 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
            mFlinger->signalLayerUpdate();
        }

        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
            // something happened!
            recomputeVisibleRegions = true;
            return;
        struct Reject : public SurfaceTexture::BufferRejecter {
            Layer::State& front;
            Layer::State& current;
            bool& recomputeVisibleRegions;
            Reject(Layer::State& front, Layer::State& current,
                    bool& recomputeVisibleRegions)
                : front(front), current(current),
                  recomputeVisibleRegions(recomputeVisibleRegions) {
            }

            virtual bool reject(const sp<GraphicBuffer>& buf,
                    const BufferQueue::BufferItem& item) {
                if (buf == NULL) {
                    return false;
                }

        // update the active buffer
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();

        uint32_t bufWidth  = mActiveBuffer->getWidth();
        uint32_t bufHeight = mActiveBuffer->getHeight();
        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
                uint32_t bufWidth  = buf->getWidth();
                uint32_t bufHeight = buf->getHeight();

                // check that we received a buffer of the right size
                // (Take the buffer's orientation into account)
        if (mCurrentTransform & Transform::ROT_90) {
                if (item.mTransform & Transform::ROT_90) {
                    swap(bufWidth, bufHeight);
                }

        // update the layer size if needed
        const Layer::State& front(drawingState());

                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
                if (front.active != front.requested) {
            bool isFixedSize = scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;

                    if (isFixedSize ||
                            (bufWidth == front.requested.w &&
@@ -560,8 +563,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
                        // Here we pretend the transaction happened by updating the
                        // current and drawing states. Drawing state is only accessed
                        // in this thread, no need to have it locked
                Layer::State& editFront(mDrawingState);
                editFront.active = front.requested;
                        front.active = front.requested;

                        // We also need to update the current state so that
                        // we don't end-up overwriting the drawing state with
@@ -569,8 +571,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
                        //
                        // NOTE: We don't need to hold the transaction lock here
                        // because State::active is only accessed from this thread.
                Layer::State& editCurrent(currentState());
                editCurrent.active = front.active;
                        current.active = front.active;

                        // recompute visible region
                        recomputeVisibleRegions = true;
@@ -580,7 +581,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
                    this, bufWidth, bufHeight, transform, scalingMode,
                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
                            front.active.w, front.active.h,
                            front.active.crop.left,
                            front.active.crop.top,
@@ -597,16 +598,42 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
                            front.requested.crop.getHeight());
                }

        mFrameLatencyNeeded = true;
                if (!isFixedSize) {
                    if (front.active.w != bufWidth ||
                        front.active.h != bufHeight) {
                        return true;
                    }
                }
                return false;
            }
        };


        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);

        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
            // something happened!
            recomputeVisibleRegions = true;
            return;
        }


        // update the active buffer
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();

        mFrameLatencyNeeded = true;
        if (oldActiveBuffer == NULL && mActiveBuffer != NULL) {
             // the first time we receive a buffer, we need to trigger a
             // geometry invalidation.
             mFlinger->invalidateHwcGeometry();
         }

        uint32_t bufWidth  = mActiveBuffer->getWidth();
        uint32_t bufHeight = mActiveBuffer->getHeight();

        Rect crop(mSurfaceTexture->getCurrentCrop());
        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
        if ((crop != mCurrentCrop) ||
            (transform != mCurrentTransform) ||
            (scalingMode != mCurrentScalingMode))
@@ -630,6 +657,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
        }

        // FIXME: mPostedDirtyRegion = dirty & bounds
        const Layer::State& front(drawingState());
        mPostedDirtyRegion.set(front.active.w, front.active.h);

        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);