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

Commit 9f2db77e authored by Chia-I Wu's avatar Chia-I Wu
Browse files

surfaceflinger: pass RenderEngine into BufferLayerConsumer

Add RenderEngine::isCurrent to replace
BufferLayerConsumer::checkAndUpdateEglStateLocked.  Remove a
duplicated check in updateAndReleaseLocked.  Use
RenderEngine::checkErrors.

Test: SurfaceFlinger_test
Change-Id: I6b97534a41a855d101965b498cb1afa72404227e
parent 401ef83b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -660,7 +660,8 @@ void BufferLayer::onFirstRef() {
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer, true);
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer, mTextureName, this);
    mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer,
            mFlinger->getRenderEngine(), mTextureName, this);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setContentsChangedListener(this);
    mSurfaceFlingerConsumer->setName(mName);
+16 −64
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

#include "DispSync.h"
#include "Layer.h"
#include "RenderEngine/RenderEngine.h"

#include <inttypes.h>

@@ -108,8 +109,8 @@ static bool isEglImageCroppable(const Rect& crop) {
    return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0);
}

BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
                                         Layer* layer)
BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RenderEngine& engine,
                                         uint32_t tex, Layer* layer)
      : ConsumerBase(bq, false),
        mCurrentCrop(Rect::EMPTY_RECT),
        mCurrentTransform(0),
@@ -123,10 +124,10 @@ BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, u
        mDefaultWidth(1),
        mDefaultHeight(1),
        mFilteringEnabled(true),
        mRE(engine),
        mEglDisplay(mRE.getEGLDisplay()),
        mTexName(tex),
        mLayer(layer),
        mEglDisplay(EGL_NO_DISPLAY),
        mEglContext(EGL_NO_CONTEXT),
        mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) {
    BLC_LOGV("BufferLayerConsumer");

@@ -211,10 +212,10 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const Dis
        return NO_INIT;
    }

    // Make sure the EGL state is the same as in previous calls.
    status_t err = checkAndUpdateEglStateLocked();
    if (err != NO_ERROR) {
        return err;
    // Make sure RenderEngine is current
    if (!mRE.isCurrent()) {
        BLC_LOGE("updateTexImage: RenderEngine is not current");
        return INVALID_OPERATION;
    }

    BufferItem item;
@@ -222,7 +223,7 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const Dis
    // Acquire the next buffer.
    // In asynchronous mode the list is guaranteed to be one buffer
    // deep, while in synchronous mode we use the oldest buffer.
    err = acquireBufferLocked(&item, computeExpectedPresent(dispSync), maxFrameNumber);
    status_t err = acquireBufferLocked(&item, computeExpectedPresent(dispSync), maxFrameNumber);
    if (err != NO_ERROR) {
        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
            err = NO_ERROR;
@@ -338,13 +339,6 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,

    int slot = item.mSlot;

    // Confirm state.
    err = checkAndUpdateEglStateLocked();
    if (err != NO_ERROR) {
        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer);
        return err;
    }

    // Ensure we have a valid EglImageKHR for the slot, creating an EglImage
    // if nessessary, for the gralloc buffer currently in the slot in
    // ConsumerBase.
@@ -418,15 +412,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,
}

status_t BufferLayerConsumer::bindTextureImageLocked() {
    if (mEglDisplay == EGL_NO_DISPLAY) {
        ALOGE("bindTextureImage: invalid display");
        return INVALID_OPERATION;
    }

    GLenum error;
    while ((error = glGetError()) != GL_NO_ERROR) {
        BLC_LOGW("bindTextureImage: clearing GL error: %#04x", error);
    }
    mRE.checkErrors();

    glBindTexture(sTexTarget, mTexName);
    if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == NULL) {
@@ -446,32 +432,6 @@ status_t BufferLayerConsumer::bindTextureImageLocked() {
    return doGLFenceWaitLocked();
}

status_t BufferLayerConsumer::checkAndUpdateEglStateLocked() {
    EGLDisplay dpy = eglGetCurrentDisplay();
    EGLContext ctx = eglGetCurrentContext();

    // if this is the first time we're called, mEglDisplay/mEglContext have
    // never been set, so don't error out (below).
    if (mEglDisplay == EGL_NO_DISPLAY) {
        mEglDisplay = dpy;
    }
    if (mEglContext == EGL_NO_CONTEXT) {
        mEglContext = ctx;
    }

    if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
        BLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
        return INVALID_OPERATION;
    }

    if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) {
        BLC_LOGE("checkAndUpdateEglState: invalid current EGLContext");
        return INVALID_OPERATION;
    }

    return NO_ERROR;
}

status_t BufferLayerConsumer::syncForReleaseLocked(EGLDisplay dpy) {
    BLC_LOGV("syncForReleaseLocked");

@@ -608,16 +568,8 @@ std::shared_ptr<FenceTime> BufferLayerConsumer::getCurrentFenceTime() const {
}

status_t BufferLayerConsumer::doGLFenceWaitLocked() const {
    EGLDisplay dpy = eglGetCurrentDisplay();
    EGLContext ctx = eglGetCurrentContext();

    if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) {
        BLC_LOGE("doGLFenceWait: invalid current EGLDisplay");
        return INVALID_OPERATION;
    }

    if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) {
        BLC_LOGE("doGLFenceWait: invalid current EGLContext");
    if (!mRE.isCurrent()) {
        BLC_LOGE("doGLFenceWait: RenderEngine is not current");
        return INVALID_OPERATION;
    }

@@ -630,7 +582,7 @@ status_t BufferLayerConsumer::doGLFenceWaitLocked() const {
                return -errno;
            }
            EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE};
            EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
            EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
            if (sync == EGL_NO_SYNC_KHR) {
                close(fenceFd);
                BLC_LOGE("doGLFenceWait: error creating EGL fence: %#x", eglGetError());
@@ -640,9 +592,9 @@ status_t BufferLayerConsumer::doGLFenceWaitLocked() const {
            // XXX: The spec draft is inconsistent as to whether this should
            // return an EGLint or void.  Ignore the return value for now, as
            // it's not strictly needed.
            eglWaitSyncKHR(dpy, sync, 0);
            eglWaitSyncKHR(mEglDisplay, sync, 0);
            EGLint eglErr = eglGetError();
            eglDestroySyncKHR(dpy, sync);
            eglDestroySyncKHR(mEglDisplay, sync);
            if (eglErr != EGL_SUCCESS) {
                BLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", eglErr);
                return UNKNOWN_ERROR;
+8 −18
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ namespace android {

class DispSync;
class Layer;
class RenderEngine;
class String8;

/*
@@ -73,7 +74,8 @@ public:
    // BufferLayerConsumer constructs a new BufferLayerConsumer object.
    // The tex parameter indicates the name of the OpenGL ES
    // texture to which images are to be streamed.
    BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, Layer* layer);
    BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RenderEngine& engine, uint32_t tex,
                        Layer* layer);

    // Sets the contents changed listener. This should be used instead of
    // ConsumerBase::setFrameAvailableListener().
@@ -230,12 +232,6 @@ protected:
    // bind succeeds, this calls doGLFenceWait.
    status_t bindTextureImageLocked();

    // Gets the current EGLDisplay and EGLContext values, and compares them
    // to mEglDisplay and mEglContext.  If the fields have been previously
    // set, the values must match; if not, the fields are set to the current
    // values.
    status_t checkAndUpdateEglStateLocked();

private:
    // EglImage is a utility class for tracking and creating EGLImageKHRs. There
    // is primarily just one image per slot, but there is also special cases:
@@ -381,6 +377,11 @@ private:
    // setFilteringEnabled().
    bool mFilteringEnabled;

    RenderEngine& mRE;

    // mEglDisplay is initialized to RenderEngine's EGLDisplay.
    const EGLDisplay mEglDisplay;

    // mTexName is the name of the OpenGL texture to which streamed images will
    // be bound when updateTexImage is called. It is set at construction time.
    const uint32_t mTexName;
@@ -397,17 +398,6 @@ private:
        sp<EglImage> mEglImage;
    };

    // mEglDisplay is the EGLDisplay with which this BufferLayerConsumer is currently
    // associated.  It is intialized to EGL_NO_DISPLAY and gets set to the
    // current display when updateTexImage is called for the first time.
    EGLDisplay mEglDisplay;

    // mEglContext is the OpenGL ES context with which this BufferLayerConsumer is
    // currently associated.  It is initialized to EGL_NO_CONTEXT and gets set
    // to the current GL context when updateTexImage is called for the first
    // time.
    EGLContext mEglContext;

    // mEGLSlots stores the buffers that have been allocated by the BufferQueue
    // for each buffer slot.  It is initialized to null pointers, and gets
    // filled in with the result of BufferQueue::acquire when the
+4 −0
Original line number Diff line number Diff line
@@ -157,6 +157,10 @@ bool RenderEngine::supportsImageCrop() const {
    return GLExtensions::getInstance().hasImageCrop();
}

bool RenderEngine::isCurrent() const {
    return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
}

bool RenderEngine::setCurrentSurface(const RE::Surface& surface) {
    bool success = true;
    EGLSurface eglSurface = surface.getEGLSurface();
+4 −3
Original line number Diff line number Diff line
@@ -86,6 +86,10 @@ public:

    bool supportsImageCrop() const;

    bool isCurrent() const;
    bool setCurrentSurface(const RE::Surface& surface);
    void resetCurrentSurface();

    // synchronization

    // flush submits RenderEngine command stream for execution and returns a
@@ -124,9 +128,6 @@ public:
        int getStatus() const;
    };

    bool setCurrentSurface(const RE::Surface& surface);
    void resetCurrentSurface();

    // set-up
    virtual void checkErrors() const;
    virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh,