diff options
-rw-r--r-- | libs/renderengine/Android.bp | 1 | ||||
-rw-r--r-- | libs/renderengine/gl/GLVertexBuffer.cpp | 55 | ||||
-rw-r--r-- | libs/renderengine/gl/GLVertexBuffer.h | 49 | ||||
-rw-r--r-- | libs/renderengine/gl/filters/BlurFilter.cpp | 79 | ||||
-rw-r--r-- | libs/renderengine/gl/filters/BlurFilter.h | 4 |
5 files changed, 149 insertions, 39 deletions
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp index 1075f161e4..eb6080fc21 100644 --- a/libs/renderengine/Android.bp +++ b/libs/renderengine/Android.bp @@ -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", diff --git a/libs/renderengine/gl/GLVertexBuffer.cpp b/libs/renderengine/gl/GLVertexBuffer.cpp new file mode 100644 index 0000000000..e50c471b6d --- /dev/null +++ b/libs/renderengine/gl/GLVertexBuffer.cpp @@ -0,0 +1,55 @@ +/* + * 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 diff --git a/libs/renderengine/gl/GLVertexBuffer.h b/libs/renderengine/gl/GLVertexBuffer.h new file mode 100644 index 0000000000..c0fd0c1b04 --- /dev/null +++ b/libs/renderengine/gl/GLVertexBuffer.h @@ -0,0 +1,49 @@ +/* + * 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 diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp index e704907dac..6ba78dc025 100644 --- a/libs/renderengine/gl/filters/BlurFilter.cpp +++ b/libs/renderengine/gl/filters/BlurFilter.cpp @@ -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,15 +79,23 @@ 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"); - return mPingFbo.getStatus(); - } - if (mCompositionFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) { - ALOGE("Invalid composition buffer"); - return mCompositionFbo.getStatus(); + if (mPingFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) { + 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(); @@ -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() { diff --git a/libs/renderengine/gl/filters/BlurFilter.h b/libs/renderengine/gl/filters/BlurFilter.h index eb6120ba92..3eb5c96664 100644 --- a/libs/renderengine/gl/filters/BlurFilter.h +++ b/libs/renderengine/gl/filters/BlurFilter.h @@ -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; |