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

Commit 9bb41b0f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[RenderEngine] Make BindNativeBufferAsFramebuffer more generic."

parents 331668ac e5a9a7f3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ filegroup {
    srcs: [
        "gl/GLES20RenderEngine.cpp",
        "gl/GLExtensions.cpp",
        "gl/GLFramebuffer.cpp",
        "gl/GLImage.cpp",
        "gl/GLSurface.cpp",
        "gl/Program.cpp",
+0 −39
Original line number Diff line number Diff line
@@ -354,45 +354,6 @@ void RenderEngine::dump(String8& result) {
    result.appendFormat("%s\n", extensions.getExtensions());
}

void RenderEngine::bindNativeBufferAsFrameBuffer(
        ANativeWindowBuffer* buffer,
        renderengine::BindNativeBufferAsFramebuffer* bindHelper) {
    bindHelper->mImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                                           buffer, nullptr);
    if (bindHelper->mImage == EGL_NO_IMAGE_KHR) {
        bindHelper->mStatus = NO_MEMORY;
        return;
    }

    uint32_t glStatus;
    bindImageAsFramebuffer(bindHelper->mImage, &bindHelper->mTexName, &bindHelper->mFbName,
                           &glStatus);

    ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d",
             glStatus);

    bindHelper->mStatus = glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
}

void RenderEngine::unbindNativeBufferAsFrameBuffer(
        renderengine::BindNativeBufferAsFramebuffer* bindHelper) {
    if (bindHelper->mImage == EGL_NO_IMAGE_KHR) {
        return;
    }

    // back to main framebuffer
    unbindFramebuffer(bindHelper->mTexName, bindHelper->mFbName);
    eglDestroyImageKHR(mEGLDisplay, bindHelper->mImage);

    // Workaround for b/77935566 to force the EGL driver to release the
    // screenshot buffer
    setScissor(0, 0, 0, 0);
    clearWithColor(0.0, 0.0, 0.0, 0.0);
    disableScissor();
}

// ---------------------------------------------------------------------------

static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute,
                                         EGLint wanted, EGLConfig* outConfig) {
    EGLint numConfigs = -1, n = 0;
+45 −29
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <utils/String8.h>
#include <utils/Trace.h>
#include "GLExtensions.h"
#include "GLFramebuffer.h"
#include "GLImage.h"
#include "GLSurface.h"
#include "Program.h"
@@ -154,6 +155,10 @@ GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags)

GLES20RenderEngine::~GLES20RenderEngine() {}

std::unique_ptr<Framebuffer> GLES20RenderEngine::createFramebuffer() {
    return std::make_unique<GLFramebuffer>(*this);
}

std::unique_ptr<Surface> GLES20RenderEngine::createSurface() {
    return std::make_unique<GLSurface>(*this);
}
@@ -197,8 +202,47 @@ void GLES20RenderEngine::bindExternalTextureImage(uint32_t texName,

    glBindTexture(target, texName);
    if (glImage.getEGLImage() != EGL_NO_IMAGE_KHR) {
        glEGLImageTargetTexture2DOES(target, static_cast<GLeglImageOES>(glImage.getEGLImage()));
        glEGLImageTargetTexture2DOES(target,
                                     static_cast<GLeglImageOES>(glImage.getEGLImage()));
    }
}

status_t GLES20RenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
    GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
    EGLImageKHR eglImage = glFramebuffer->getEGLImage();
    uint32_t textureName = glFramebuffer->getTextureName();
    uint32_t framebufferName = glFramebuffer->getFramebufferName();

    // Bind the texture and turn our EGLImage into a texture
    glBindTexture(GL_TEXTURE_2D, textureName);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)eglImage);

    // Bind the Framebuffer to render into
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, textureName, 0);

    mRenderToFbo = true;

    uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES,
             "glCheckFramebufferStatusOES error %d", glStatus);

    return glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
}

void GLES20RenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
    mRenderToFbo = false;

    // back to main framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // Workaround for b/77935566 to force the EGL driver to release the
    // screenshot buffer
    setScissor(0, 0, 0, 0);
    clearWithColor(0.0, 0.0, 0.0, 0.0);
    disableScissor();
}

void GLES20RenderEngine::setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
@@ -304,34 +348,6 @@ void GLES20RenderEngine::disableBlending() {
    glDisable(GL_BLEND);
}

void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName,
                                                uint32_t* fbName, uint32_t* status) {
    GLuint tname, name;
    // turn our EGLImage into a texture
    glGenTextures(1, &tname);
    glBindTexture(GL_TEXTURE_2D, tname);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);

    // create a Framebuffer Object to render into
    glGenFramebuffers(1, &name);
    glBindFramebuffer(GL_FRAMEBUFFER, name);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);

    *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    *texName = tname;
    *fbName = name;

    mRenderToFbo = true;
}

void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
    mRenderToFbo = false;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glDeleteFramebuffers(1, &fbName);
    glDeleteTextures(1, &texName);
}

void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
    mState.setPremultipliedAlpha(true);
    mState.setOpaque(false);
+42 −52
Original line number Diff line number Diff line
@@ -39,32 +39,13 @@ class GLImage;
class GLSurface;

class GLES20RenderEngine : public impl::RenderEngine {
    GLuint mProtectedTexName;
    GLint mMaxViewportDims[2];
    GLint mMaxTextureSize;
    GLuint mVpWidth;
    GLuint mVpHeight;

    struct Group {
        GLuint texture;
        GLuint fbo;
        GLuint width;
        GLuint height;
        mat4 colorTransform;
    };

    Description mState;

    virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName,
                                        uint32_t* status);
    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);

public:
    GLES20RenderEngine(uint32_t featureFlags); // See RenderEngine::FeatureFlag
    virtual ~GLES20RenderEngine();
    ~GLES20RenderEngine() override;

    std::unique_ptr<renderengine::Surface> createSurface() override;
    std::unique_ptr<renderengine::Image> createImage() override;
    std::unique_ptr<Framebuffer> createFramebuffer() override;
    std::unique_ptr<Surface> createSurface() override;
    std::unique_ptr<Image> createImage() override;

    void primeCache() const override;

@@ -72,14 +53,15 @@ public:
    bool setCurrentSurface(const Surface& surface) override;
    void resetCurrentSurface() override;

    void bindExternalTextureImage(uint32_t texName, const renderengine::Image& image) override;

    void bindExternalTextureImage(uint32_t texName, const Image& image) override;
    status_t bindFrameBuffer(Framebuffer* framebuffer) override;
    void unbindFrameBuffer(Framebuffer* framebuffer) override;

protected:
    virtual void dump(String8& result);
    virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
                                          ui::Transform::orientation_flags rotation);
    virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
    void dump(String8& result) override;
    void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
                                  ui::Transform::orientation_flags rotation) override;
    void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
                            const half4& color) override;

    // Color management related functions and state
@@ -88,27 +70,31 @@ protected:
    void setOutputDataSpace(ui::Dataspace dataspace) override;
    void setDisplayMaxLuminance(const float maxLuminance) override;

    virtual void setupLayerTexturing(const Texture& texture);
    virtual void setupLayerBlackedOut();
    virtual void setupFillWithColor(float r, float g, float b, float a);
    virtual void setupColorTransform(const mat4& colorTransform);
    virtual void disableTexturing();
    virtual void disableBlending();
    void setupLayerTexturing(const Texture& texture) override;
    void setupLayerBlackedOut() override;
    void setupFillWithColor(float r, float g, float b, float a) override;
    void setupColorTransform(const mat4& colorTransform) override;
    void disableTexturing() override;
    void disableBlending() override;

    virtual void drawMesh(const Mesh& mesh);
    void drawMesh(const Mesh& mesh) override;

    virtual size_t getMaxTextureSize() const;
    virtual size_t getMaxViewportDims() const;
    size_t getMaxTextureSize() const override;
    size_t getMaxViewportDims() const override;

    // Current dataspace of layer being rendered
    ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;
private:
    // A data space is considered HDR data space if it has BT2020 color space
    // with PQ or HLG transfer function.
    bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
    bool needsXYZTransformMatrix() const;

    // Current output dataspace of the render engine
    ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;
    GLuint mProtectedTexName;
    GLint mMaxViewportDims[2];
    GLint mMaxTextureSize;
    GLuint mVpWidth;
    GLuint mVpHeight;
    Description mState;

    // Whether device supports color management, currently color management
    // supports sRGB, DisplayP3 color spaces.
    const bool mUseColorManagement = false;
    mat4 mSrgbToDisplayP3;
    mat4 mDisplayP3ToSrgb;
    mat3 mSrgbToXyz;
@@ -118,13 +104,17 @@ protected:
    mat4 mXyzToDisplayP3;
    mat4 mXyzToBt2020;

private:
    // A data space is considered HDR data space if it has BT2020 color space
    // with PQ or HLG transfer function.
    bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
    bool needsXYZTransformMatrix() const;

    bool mRenderToFbo = false;

    // Current dataspace of layer being rendered
    ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;

    // Current output dataspace of the render engine
    ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;

    // Whether device supports color management, currently color management
    // supports sRGB, DisplayP3 color spaces.
    const bool mUseColorManagement = false;
};

}  // namespace gl
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "GLFramebuffer.h"

#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "GLES20RenderEngine.h"

namespace android {
namespace renderengine {
namespace gl {

GLFramebuffer::GLFramebuffer(const GLES20RenderEngine& engine)
        : mEGLDisplay(engine.getEGLDisplay()),
          mEGLImage(EGL_NO_IMAGE_KHR) {
    glGenTextures(1, &mTextureName);
    glGenFramebuffers(1, &mFramebufferName);
}

GLFramebuffer::~GLFramebuffer() {
    glDeleteFramebuffers(1, &mFramebufferName);
    glDeleteTextures(1, &mTextureName);
    eglDestroyImageKHR(mEGLDisplay, mEGLImage);
}

bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) {
    if (mEGLImage != EGL_NO_IMAGE_KHR) {
        eglDestroyImageKHR(mEGLDisplay, mEGLImage);
        mEGLImage = EGL_NO_IMAGE_KHR;
    }

    if (nativeBuffer) {
        mEGLImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
                                      EGL_NATIVE_BUFFER_ANDROID,
                                      nativeBuffer, nullptr);
        if (mEGLImage == EGL_NO_IMAGE_KHR) {
            return false;
        }
    }
    return true;
}

}  // namespace gl
}  // namespace renderengine
}  // namespace android
Loading