diff --git a/src/renderer/gl_engine/tvgGlRenderTask.cpp b/src/renderer/gl_engine/tvgGlRenderTask.cpp index f30eda06..3c35335d 100644 --- a/src/renderer/gl_engine/tvgGlRenderTask.cpp +++ b/src/renderer/gl_engine/tvgGlRenderTask.cpp @@ -202,25 +202,26 @@ 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)); + if (mClearBuffer) { + 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 1b190ad5..b271f12a 100644 --- a/src/renderer/gl_engine/tvgGlRenderTask.h +++ b/src/renderer/gl_engine/tvgGlRenderTask.h @@ -130,7 +130,7 @@ protected: GLuint getResolveFboId(); - virtual void onResolve(); + void onResolve(); private: GLuint mTargetFbo; GlRenderTarget* mFbo; @@ -143,16 +143,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 510887a4..809f0343 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -86,8 +86,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)); @@ -95,14 +93,15 @@ bool GlRenderer::sync() GL_CHECK(glCullFace(GL_FRONT_AND_BACK)); GL_CHECK(glFrontFace(GL_CCW)); - mGpuBuffer->bind(); + auto task = mRenderPassStack.front().endRenderPass(mPrograms[RT_Blit].get(), mTargetFboId); - auto task = mRenderPassStack.front().endRenderPass(nullptr, mTargetFboId); - - task->setSize(surface.w, surface.h); + prepareBlitTask(task); task->mClearBuffer = mClearBuffer; + mGpuBuffer->flushToGPU(); + mGpuBuffer->bind(); + 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 61c155ee..6ca95fc1 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_ */