gl_engine: fix rendering error caused by viewport and stencil state

Fix some error:
* glViewport not controlled by framebuffer, and need to set manually when
target framebuffer is changed.
* change even-odd stencil operation, so no need to do third draw call to
  clear stencil buffer
* fix the missing `GlCanvas::update` calls in Lottoe and LottieExtension
This commit is contained in:
RuiwenTang 2024-04-27 17:07:53 +08:00 committed by Jinny You
parent a532ac3eb2
commit bb7f23da78
6 changed files with 25 additions and 12 deletions

View file

@ -217,6 +217,8 @@ void drawGLview(Evas_Object *obj)
gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl->glClear(GL_COLOR_BUFFER_BIT); gl->glClear(GL_COLOR_BUFFER_BIT);
glCanvas->update();
if (glCanvas->draw() == tvg::Result::Success) { if (glCanvas->draw() == tvg::Result::Success) {
glCanvas->sync(); glCanvas->sync();
} }

View file

@ -194,6 +194,8 @@ void drawGLview(Evas_Object *obj)
gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl->glClear(GL_COLOR_BUFFER_BIT); gl->glClear(GL_COLOR_BUFFER_BIT);
glCanvas->update();
if (glCanvas->draw() == tvg::Result::Success) { if (glCanvas->draw() == tvg::Result::Success) {
glCanvas->sync(); glCanvas->sync();
} }

View file

@ -128,7 +128,7 @@ void GlStencilCoverTask::run()
if (mStencilMode == GlStencilMode::FillEvenOdd) { if (mStencilMode == GlStencilMode::FillEvenOdd) {
GL_CHECK(glStencilFunc(GL_EQUAL, 0x01, 0x01)); GL_CHECK(glStencilFunc(GL_EQUAL, 0x01, 0x01));
GL_CHECK(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)); GL_CHECK(glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE));
} else { } else {
GL_CHECK(glStencilFunc(GL_NOTEQUAL, 0x0, 0xFF)); GL_CHECK(glStencilFunc(GL_NOTEQUAL, 0x0, 0xFF));
GL_CHECK(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)); GL_CHECK(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE));
@ -138,17 +138,6 @@ void GlStencilCoverTask::run()
mCoverTask->run(); mCoverTask->run();
if (mStencilMode == GlStencilMode::FillEvenOdd) {
GL_CHECK(glStencilFunc(GL_NOTEQUAL, 0x0, 0xFF));
GL_CHECK(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE));
GL_CHECK(glColorMask(0, 0, 0, 0));
mStencilTask->run();
GL_CHECK(glColorMask(1, 1, 1, 1));
}
GL_CHECK(glDisable(GL_STENCIL_TEST)); GL_CHECK(glDisable(GL_STENCIL_TEST));
} }
@ -171,6 +160,7 @@ GlComposeTask::~GlComposeTask()
void GlComposeTask::run() void GlComposeTask::run()
{ {
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, getSelfFbo())); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, getSelfFbo()));
GL_CHECK(glViewport(0, 0, mFbo->getWidth(), mFbo->getHeight()));
// clear this fbo // clear this fbo
if (mClearBuffer) { if (mClearBuffer) {
@ -216,6 +206,7 @@ void GlBlitTask::run()
GlComposeTask::run(); GlComposeTask::run();
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo())); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo()));
GL_CHECK(glViewport(mTargetViewport.x, mTargetViewport.y, mTargetViewport.w, mTargetViewport.h));
if (mClearBuffer) { if (mClearBuffer) {
GL_CHECK(glClearColor(0, 0, 0, 0)); GL_CHECK(glClearColor(0, 0, 0, 0));

View file

@ -146,8 +146,11 @@ public:
void run() override; void run() override;
GLuint getColorTextore() const { return mColorTex; } GLuint getColorTextore() const { return mColorTex; }
void setTargetViewport(const RenderRegion& vp) { mTargetViewport = vp; }
private: private:
GLuint mColorTex = 0; GLuint mColorTex = 0;
RenderRegion mTargetViewport = {};
}; };
class GlDrawBlitTask : public GlComposeTask class GlDrawBlitTask : public GlComposeTask

View file

@ -68,11 +68,24 @@ bool GlRenderer::target(int32_t id, uint32_t w, uint32_t h)
mViewport.w = surface.w; mViewport.w = surface.w;
mViewport.h = surface.h; mViewport.h = surface.h;
mTargetViewport.x = 0;
mTargetViewport.y = 0;
mTargetViewport.w = surface.w;
mTargetViewport.h = surface.h;
mTargetFboId = static_cast<GLint>(id); mTargetFboId = static_cast<GLint>(id);
//TODO: It's not allow to draw onto the main surface. Need to confirm the policy. //TODO: It's not allow to draw onto the main surface. Need to confirm the policy.
if (mTargetFboId == 0) { if (mTargetFboId == 0) {
GL_CHECK(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mTargetFboId)); GL_CHECK(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mTargetFboId));
GLint dims[4] = {0};
GL_CHECK(glGetIntegerv(GL_VIEWPORT, dims));
// If targeting on the main framebuffer ,the actual size may by adjusted by the window system.
// In case the size is different from logical size, query and set the actual viewport here
mTargetViewport.w = dims[2];
mTargetViewport.h = dims[3];
} }
mRootTarget = make_unique<GlRenderTarget>(surface.w, surface.h); mRootTarget = make_unique<GlRenderTarget>(surface.w, surface.h);
@ -101,6 +114,7 @@ bool GlRenderer::sync()
prepareBlitTask(task); prepareBlitTask(task);
task->mClearBuffer = mClearBuffer; task->mClearBuffer = mClearBuffer;
task->setTargetViewport(mTargetViewport);
mGpuBuffer->flushToGPU(); mGpuBuffer->flushToGPU();
mGpuBuffer->bind(); mGpuBuffer->bind();

View file

@ -98,6 +98,7 @@ private:
GLint mTargetFboId = 0; GLint mTargetFboId = 0;
RenderRegion mViewport; RenderRegion mViewport;
RenderRegion mTargetViewport;
//TODO: remove all unique_ptr / replace the vector with tvg::Array //TODO: remove all unique_ptr / replace the vector with tvg::Array
unique_ptr<GlStageBuffer> mGpuBuffer; unique_ptr<GlStageBuffer> mGpuBuffer;
vector<std::unique_ptr<GlProgram>> mPrograms; vector<std::unique_ptr<GlProgram>> mPrograms;