From 574783be168bf9a338d6e80ab3b90dea8f7868e5 Mon Sep 17 00:00:00 2001 From: RuiwenTang Date: Wed, 10 Apr 2024 13:45:32 +0800 Subject: [PATCH] gl_engine: using normal texture rendering in final color blit Since blit msaa framebuffer to another msaa framebuffer may generate GLError in some platforms. Use normal texture rendering to blit the final color buffer onto target framebuffer. --- src/renderer/gl_engine/tvgGlRenderTask.cpp | 19 +++++++++--------- src/renderer/gl_engine/tvgGlRenderTask.h | 11 +++-------- src/renderer/gl_engine/tvgGlRenderer.cpp | 23 ++++++++++++++++------ src/renderer/gl_engine/tvgGlRenderer.h | 2 ++ src/renderer/gl_engine/tvgGlShaderSrc.cpp | 19 ++++++++++++++++++ src/renderer/gl_engine/tvgGlShaderSrc.h | 2 ++ 6 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/renderer/gl_engine/tvgGlRenderTask.cpp b/src/renderer/gl_engine/tvgGlRenderTask.cpp index 753b5c10..3431406a 100644 --- a/src/renderer/gl_engine/tvgGlRenderTask.cpp +++ b/src/renderer/gl_engine/tvgGlRenderTask.cpp @@ -199,25 +199,24 @@ void GlComposeTask::onResolve() { } GlBlitTask::GlBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array&& tasks) - : GlComposeTask(program, target, fbo, std::move(tasks)) + : GlComposeTask(program, target, fbo, std::move(tasks)), mColorTex(fbo->getColorTexture()) { } -void GlBlitTask::setSize(uint32_t width, uint32_t height) -{ - mWidth = width; - mHeight = height; -} - void GlBlitTask::run() { GlComposeTask::run(); - GL_CHECK(glScissor(0, 0, mWidth, mHeight)); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo())); - GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, getSelfFbo())); - GL_CHECK(glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST)); + GL_CHECK(glClearColor(0, 0, 0, 0)); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT)); + + // make sure the blending is correct + GL_CHECK(glEnable(GL_BLEND)); + GL_CHECK(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + + GlRenderTask::run(); } GlDrawBlitTask::GlDrawBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array&& tasks) diff --git a/src/renderer/gl_engine/tvgGlRenderTask.h b/src/renderer/gl_engine/tvgGlRenderTask.h index 78fd16cc..8463dda6 100644 --- a/src/renderer/gl_engine/tvgGlRenderTask.h +++ b/src/renderer/gl_engine/tvgGlRenderTask.h @@ -128,7 +128,7 @@ protected: GLuint getResolveFboId(); - virtual void onResolve(); + void onResolve(); private: GLuint mTargetFbo; GlRenderTarget* mFbo; @@ -141,16 +141,11 @@ public: GlBlitTask(GlProgram*, GLuint target, GlRenderTarget* fbo, Array&& tasks); ~GlBlitTask() override = default; - void setSize(uint32_t width, uint32_t height); - void run() override; -protected: - void onResolve() override {} - + GLuint getColorTextore() const { return mColorTex; } private: - uint32_t mWidth = 0; - uint32_t mHeight = 0; + GLuint mColorTex = 0; }; class GlDrawBlitTask : public GlComposeTask diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index f83ec846..25f273a6 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -87,8 +87,6 @@ bool GlRenderer::sync() //nothing to be done. if (mRenderPassStack.size() == 0) return true; - mGpuBuffer->flushToGPU(); - // Blend function for straight alpha GL_CHECK(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); GL_CHECK(glEnable(GL_BLEND)); @@ -96,12 +94,13 @@ bool GlRenderer::sync() GL_CHECK(glCullFace(GL_FRONT_AND_BACK)); GL_CHECK(glFrontFace(GL_CCW)); + auto task = mRenderPassStack.front().endRenderPass(mPrograms[RT_Blit].get(), mTargetFboId); + + prepareBlitTask(task); + + mGpuBuffer->flushToGPU(); mGpuBuffer->bind(); - auto task = mRenderPassStack.front().endRenderPass(nullptr, mTargetFboId); - - task->setSize(surface.w, surface.h); - task->run(); mGpuBuffer->unbind(); @@ -490,6 +489,8 @@ void GlRenderer::initShaders() mPrograms.push_back(make_unique(GlShader::gen(MASK_VERT_SHADER, MASK_DIFF_FRAG_SHADER))); // stencil Renderer mPrograms.push_back(make_unique(GlShader::gen(STENCIL_VERT_SHADER, STENCIL_FRAG_SHADER))); + // blit Renderer + mPrograms.push_back(make_unique(GlShader::gen(BLIT_VERT_SHADER, BLIT_FRAG_SHADER))); } @@ -692,6 +693,16 @@ GlRenderPass* GlRenderer::currentPass() return &mRenderPassStack.back(); } +void GlRenderer::prepareBlitTask(GlBlitTask* task) +{ + prepareCmpTask(task); + + { + uint32_t loc = task->getProgram()->getUniformLocation("uSrcTexture"); + task->addBindResource(GlBindingResource{0, task->getColorTextore(), loc}); + } +} + void GlRenderer::prepareCmpTask(GlRenderTask* task) { // we use 1:1 blit mapping since compositor fbo is same size as root fbo diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index 67a472b3..4c34ae04 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -47,6 +47,7 @@ public: RT_MaskIntersect, RT_MaskDifference, RT_Stencil, + RT_Blit, RT_None, }; @@ -90,6 +91,7 @@ private: GlRenderPass* currentPass(); + void prepareBlitTask(GlBlitTask* task); void prepareCmpTask(GlRenderTask* task); void endRenderPass(Compositor* cmp); diff --git a/src/renderer/gl_engine/tvgGlShaderSrc.cpp b/src/renderer/gl_engine/tvgGlShaderSrc.cpp index dccc3160..0b67552f 100644 --- a/src/renderer/gl_engine/tvgGlShaderSrc.cpp +++ b/src/renderer/gl_engine/tvgGlShaderSrc.cpp @@ -453,3 +453,22 @@ const char* STENCIL_FRAG_SHADER = TVG_COMPOSE_SHADER( out vec4 FragColor; \n void main() { FragColor = vec4(0.0); } \n ); + +const char* BLIT_VERT_SHADER = TVG_COMPOSE_SHADER( + layout(location = 0) in vec2 aLocation; \n + layout(location = 1) in vec2 aUV; \n + out vec2 vUV; \n + void main() { \n + vUV = aUV; \n + gl_Position = vec4(aLocation, 0.0, 1.0); \n + } +); + +const char* BLIT_FRAG_SHADER = TVG_COMPOSE_SHADER( + uniform sampler2D uSrcTexture; \n + in vec2 vUV; \n + out vec4 FragColor; \n + void main() { \n + FragColor = texture(uSrcTexture, vUV); \n + } +); diff --git a/src/renderer/gl_engine/tvgGlShaderSrc.h b/src/renderer/gl_engine/tvgGlShaderSrc.h index 680e0ab6..94859027 100644 --- a/src/renderer/gl_engine/tvgGlShaderSrc.h +++ b/src/renderer/gl_engine/tvgGlShaderSrc.h @@ -41,5 +41,7 @@ extern const char* MASK_INTERSECT_FRAG_SHADER; extern const char* MASK_DIFF_FRAG_SHADER; extern const char* STENCIL_VERT_SHADER; extern const char* STENCIL_FRAG_SHADER; +extern const char* BLIT_VERT_SHADER; +extern const char* BLIT_FRAG_SHADER; #endif /* _TVG_GL_SHADERSRC_H_ */