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

Commit ea8957b5 authored by Lucas Dupin's avatar Lucas Dupin Committed by Automerger Merge Worker
Browse files

Merge "Use a VBO when drawing blurs" into rvc-dev am: 134a699e am: 7a88749c am: 85e8ea1f

Change-Id: I8c67d045198c93ae12aab7fae35dc79551cde4ea
parents 2f7f4b62 85e8ea1f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ filegroup {
        "gl/GLShadowTexture.cpp",
        "gl/GLShadowVertexGenerator.cpp",
        "gl/GLSkiaShadowPort.cpp",
        "gl/GLVertexBuffer.cpp",
        "gl/ImageManager.cpp",
        "gl/Program.cpp",
        "gl/ProgramCache.cpp",
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "GLVertexBuffer.h"

#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <nativebase/nativebase.h>
#include <utils/Trace.h>

namespace android {
namespace renderengine {
namespace gl {

GLVertexBuffer::GLVertexBuffer() {
    glGenBuffers(1, &mBufferName);
}

GLVertexBuffer::~GLVertexBuffer() {
    glDeleteBuffers(1, &mBufferName);
}

void GLVertexBuffer::allocateBuffers(const GLfloat data[], const GLuint size) {
    ATRACE_CALL();
    bind();
    glBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat), data, GL_STATIC_DRAW);
    unbind();
}

void GLVertexBuffer::bind() const {
    glBindBuffer(GL_ARRAY_BUFFER, mBufferName);
}

void GLVertexBuffer::unbind() const {
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

} // namespace gl
} // namespace renderengine
} // namespace android
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

#pragma once

#include <cstdint>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>

struct ANativeWindowBuffer;

namespace android {
namespace renderengine {
namespace gl {

class GLESRenderEngine;

class GLVertexBuffer {
public:
    explicit GLVertexBuffer();
    ~GLVertexBuffer();

    void allocateBuffers(const GLfloat data[], const GLuint size);
    uint32_t getBufferName() const { return mBufferName; }
    void bind() const;
    void unbind() const;

private:
    uint32_t mBufferName;
};

} // namespace gl
} // namespace renderengine
} // namespace android
+40 −39
Original line number Diff line number Diff line
@@ -49,6 +49,20 @@ BlurFilter::BlurFilter(GLESRenderEngine& engine)
    mBUvLoc = mBlurProgram.getAttributeLocation("aUV");
    mBTextureLoc = mBlurProgram.getUniformLocation("uTexture");
    mBOffsetLoc = mBlurProgram.getUniformLocation("uOffset");

    static constexpr auto size = 2.0f;
    static constexpr auto translation = 1.0f;
    const GLfloat vboData[] = {
        // Vertex data
        translation-size, -translation-size,
        translation-size, -translation+size,
        translation+size, -translation+size,
        // UV data
        0.0f, 0.0f-translation,
        0.0f, size-translation,
        size, size-translation
    };
    mMeshBuffer.allocateBuffers(vboData, 12 /* size */);
}

status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display, uint32_t radius) {
@@ -65,16 +79,24 @@ status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display, uint32_t ra
        mPingFbo.allocateBuffers(fboWidth, fboHeight);
        mPongFbo.allocateBuffers(fboWidth, fboHeight);
        mTexturesAllocated = true;
    }

        if (mPingFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
        ALOGE("Invalid blur buffer");
            ALOGE("Invalid ping buffer");
            return mPingFbo.getStatus();
        }
        if (mPongFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
            ALOGE("Invalid pong buffer");
            return mPongFbo.getStatus();
        }
        if (mCompositionFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
            ALOGE("Invalid composition buffer");
            return mCompositionFbo.getStatus();
        }
        if (!mBlurProgram.isValid()) {
            ALOGE("Invalid shader");
            return GL_INVALID_OPERATION;
        }
    }

    mCompositionFbo.bind();
    glViewport(0, 0, mCompositionFbo.getBufferWidth(), mCompositionFbo.getBufferHeight());
@@ -82,43 +104,22 @@ status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display, uint32_t ra
}

void BlurFilter::drawMesh(GLuint uv, GLuint position) {
    static constexpr auto size = 2.0f;
    static constexpr auto translation = 1.0f;
    GLfloat positions[] = {
        translation-size, -translation-size,
        translation-size, -translation+size,
        translation+size, -translation+size
    };
    GLfloat texCoords[] = {
        0.0f, 0.0f-translation,
        0.0f, size-translation,
        size, size-translation
    };

    // set attributes
    glEnableVertexAttribArray(uv);
    glVertexAttribPointer(uv, 2 /* size */, GL_FLOAT, GL_FALSE, 0, texCoords);
    glEnableVertexAttribArray(position);
    glVertexAttribPointer(position, 2 /* size */, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat),
                          positions);
    mMeshBuffer.bind();
    glVertexAttribPointer(position, 2 /* size */, GL_FLOAT, GL_FALSE,
                          2 * sizeof(GLfloat) /* stride */, 0 /* offset */);
    glVertexAttribPointer(uv, 2 /* size */, GL_FLOAT, GL_FALSE, 0 /* stride */,
                          (GLvoid*)(6 * sizeof(GLfloat)) /* offset */);
    mMeshBuffer.unbind();

    // draw mesh
    glDrawArrays(GL_TRIANGLES, 0 /* first */, 3 /* count */);
    mEngine.checkErrors("Drawing blur mesh");
}

status_t BlurFilter::prepare() {
    ATRACE_NAME("BlurFilter::prepare");

    if (mPongFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
        ALOGE("Invalid FBO");
        return mPongFbo.getStatus();
    }
    if (!mBlurProgram.isValid()) {
        ALOGE("Invalid shader");
        return GL_INVALID_OPERATION;
    }

    blit(mCompositionFbo, mPingFbo);

    // Kawase is an approximation of Gaussian, but it behaves differently from it.
@@ -136,16 +137,15 @@ status_t BlurFilter::prepare() {
    GLFramebuffer* draw = &mPongFbo;
    float stepX = radius / (float)mCompositionFbo.getBufferWidth() / (float)passes;
    float stepY = radius / (float)mCompositionFbo.getBufferHeight() / (float)passes;
    glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight());
    glActiveTexture(GL_TEXTURE0);
    glUniform1i(mBTextureLoc, 0);
    for (auto i = 0; i < passes; i++) {
        ATRACE_NAME("BlurFilter::renderPass");
        draw->bind();

        glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight());
        glBindTexture(GL_TEXTURE_2D, read->getTextureName());
        glUniform2f(mBOffsetLoc, stepX * i, stepY * i);
        mEngine.checkErrors("Setting uniforms");

        drawMesh(mBUvLoc, mBPosLoc);

@@ -189,17 +189,18 @@ status_t BlurFilter::render(bool multiPass) {
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName());
    glUniform1i(mMCompositionTextureLoc, 1);
    mEngine.checkErrors("Setting final pass uniforms");

    drawMesh(mMUvLoc, mMPosLoc);

    glUseProgram(0);
    glActiveTexture(GL_TEXTURE0);
    mEngine.checkErrors("Drawing blur mesh");
    return NO_ERROR;
}

string BlurFilter::getVertexShader() const {
    return R"SHADER(#version 310 es
        precision mediump float;

        in vec2 aPosition;
        in highp vec2 aUV;
@@ -219,7 +220,7 @@ string BlurFilter::getFragmentShader() const {
        uniform sampler2D uTexture;
        uniform vec2 uOffset;

        highp in vec2 vUV;
        in highp vec2 vUV;
        out vec4 fragColor;

        void main() {
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <ui/GraphicTypes.h>
#include "../GLESRenderEngine.h"
#include "../GLFramebuffer.h"
#include "../GLVertexBuffer.h"
#include "GenericProgram.h"

using namespace std;
@@ -72,6 +73,9 @@ private:
    GLFramebuffer* mLastDrawTarget;
    bool mTexturesAllocated = false;

    // VBO containing vertex and uv data of a fullscreen triangle.
    GLVertexBuffer mMeshBuffer;

    GenericProgram mMixProgram;
    GLuint mMPosLoc;
    GLuint mMUvLoc;