mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
renderer: ++engines safety
Added drawing exceptions when target is not properly ready. Now, Canvas::update() Canvas::draw() will return InsufficientCondition if the target has not been set beforehand.
This commit is contained in:
parent
2524cdfee5
commit
3fbb55440a
9 changed files with 32 additions and 5 deletions
|
@ -40,8 +40,9 @@ GlRenderTarget::~GlRenderTarget()
|
||||||
|
|
||||||
void GlRenderTarget::init(GLint resolveId)
|
void GlRenderTarget::init(GLint resolveId)
|
||||||
{
|
{
|
||||||
if (mFbo != 0 || mWidth == 0 || mHeight == 0) return;
|
if (mFbo != GL_INVALID_VALUE || mWidth == 0 || mHeight == 0) return;
|
||||||
|
|
||||||
|
//TODO: fbo is used. maybe we can consider the direct rendering with resolveId as well.
|
||||||
GL_CHECK(glGenFramebuffers(1, &mFbo));
|
GL_CHECK(glGenFramebuffers(1, &mFbo));
|
||||||
|
|
||||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mFbo));
|
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mFbo));
|
||||||
|
|
|
@ -44,12 +44,13 @@ public:
|
||||||
void setViewport(const RenderRegion& vp) { mViewport = vp; }
|
void setViewport(const RenderRegion& vp) { mViewport = vp; }
|
||||||
const RenderRegion& getViewport() const { return mViewport; }
|
const RenderRegion& getViewport() const { return mViewport; }
|
||||||
|
|
||||||
|
bool invalid() const { return mFbo == GL_INVALID_VALUE; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t mWidth = 0;
|
uint32_t mWidth = 0;
|
||||||
uint32_t mHeight = 0;
|
uint32_t mHeight = 0;
|
||||||
RenderRegion mViewport{};
|
RenderRegion mViewport{};
|
||||||
GLuint mFbo = 0;
|
GLuint mFbo = GL_INVALID_VALUE;
|
||||||
GLuint mColorBuffer = 0;
|
GLuint mColorBuffer = 0;
|
||||||
GLuint mDepthStencilBuffer = 0;
|
GLuint mDepthStencilBuffer = 0;
|
||||||
GLuint mResolveFbo = 0;
|
GLuint mResolveFbo = 0;
|
||||||
|
|
|
@ -809,6 +809,8 @@ void GlRenderer::endRenderPass(RenderCompositor* cmp)
|
||||||
|
|
||||||
bool GlRenderer::clear()
|
bool GlRenderer::clear()
|
||||||
{
|
{
|
||||||
|
if (mRootTarget.invalid()) return false;
|
||||||
|
|
||||||
mClearBuffer = true;
|
mClearBuffer = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -896,6 +898,8 @@ RenderRegion GlRenderer::region(RenderData data)
|
||||||
|
|
||||||
bool GlRenderer::preRender()
|
bool GlRenderer::preRender()
|
||||||
{
|
{
|
||||||
|
if (mRootTarget.invalid()) return false;
|
||||||
|
|
||||||
currentContext();
|
currentContext();
|
||||||
if (mPrograms.empty()) initShaders();
|
if (mPrograms.empty()) initShaders();
|
||||||
mRenderPassStack.push(new GlRenderPass(&mRootTarget));
|
mRenderPassStack.push(new GlRenderPass(&mRootTarget));
|
||||||
|
@ -1525,6 +1529,8 @@ bool GlRenderer::viewport(const RenderRegion& vp)
|
||||||
|
|
||||||
bool GlRenderer::preUpdate()
|
bool GlRenderer::preUpdate()
|
||||||
{
|
{
|
||||||
|
if (mRootTarget.invalid()) return false;
|
||||||
|
|
||||||
currentContext();
|
currentContext();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,7 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h,
|
||||||
|
|
||||||
bool SwRenderer::preUpdate()
|
bool SwRenderer::preUpdate()
|
||||||
{
|
{
|
||||||
return true;
|
return surface != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ bool SwRenderer::postUpdate()
|
||||||
|
|
||||||
bool SwRenderer::preRender()
|
bool SwRenderer::preRender()
|
||||||
{
|
{
|
||||||
return true;
|
return surface != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,11 @@ struct WgContext {
|
||||||
|
|
||||||
// release buffer objects
|
// release buffer objects
|
||||||
void releaseBuffer(WGPUBuffer& buffer);
|
void releaseBuffer(WGPUBuffer& buffer);
|
||||||
|
|
||||||
|
bool invalid()
|
||||||
|
{
|
||||||
|
return !instance || !device;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _TVG_WG_COMMON_H_
|
#endif // _TVG_WG_COMMON_H_
|
||||||
|
|
|
@ -195,6 +195,8 @@ RenderData WgRenderer::prepare(RenderSurface* surface, RenderData data, const Ma
|
||||||
|
|
||||||
bool WgRenderer::preRender()
|
bool WgRenderer::preRender()
|
||||||
{
|
{
|
||||||
|
if (mContext.invalid()) return false;
|
||||||
|
|
||||||
// push rot render storage to the render tree stack
|
// push rot render storage to the render tree stack
|
||||||
assert(mRenderStorageStack.count == 0);
|
assert(mRenderStorageStack.count == 0);
|
||||||
mRenderStorageStack.push(&mRenderStorageRoot);
|
mRenderStorageStack.push(&mRenderStorageRoot);
|
||||||
|
@ -301,6 +303,8 @@ const RenderSurface* WgRenderer::mainSurface()
|
||||||
|
|
||||||
bool WgRenderer::clear()
|
bool WgRenderer::clear()
|
||||||
{
|
{
|
||||||
|
if (mContext.invalid()) return false;
|
||||||
|
|
||||||
//TODO: clear the current target buffer only if clear() is called
|
//TODO: clear the current target buffer only if clear() is called
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -632,6 +636,8 @@ void WgRenderer::dispose(RenderEffect* effect)
|
||||||
|
|
||||||
bool WgRenderer::preUpdate()
|
bool WgRenderer::preUpdate()
|
||||||
{
|
{
|
||||||
|
if (mContext.invalid()) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,9 @@ TEST_CASE("Bounding Box", "[tvgPaint]")
|
||||||
Initializer::init(0);
|
Initializer::init(0);
|
||||||
|
|
||||||
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
||||||
|
uint32_t buffer[100*100];
|
||||||
|
canvas->target(buffer, 100, 100, 100, ColorSpace::ABGR8888);
|
||||||
|
|
||||||
auto shape = Shape::gen();
|
auto shape = Shape::gen();
|
||||||
canvas->push(shape);
|
canvas->push(shape);
|
||||||
canvas->sync();
|
canvas->sync();
|
||||||
|
|
|
@ -80,7 +80,8 @@ TEST_CASE("Scene Clear And Reuse Shape", "[tvgScene]")
|
||||||
REQUIRE(Initializer::init(0) == Result::Success);
|
REQUIRE(Initializer::init(0) == Result::Success);
|
||||||
{
|
{
|
||||||
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
||||||
REQUIRE(canvas);
|
uint32_t buffer[100*100];
|
||||||
|
canvas->target(buffer, 100, 100, 100, ColorSpace::ABGR8888);
|
||||||
|
|
||||||
auto scene = Scene::gen();
|
auto scene = Scene::gen();
|
||||||
REQUIRE(scene);
|
REQUIRE(scene);
|
||||||
|
|
|
@ -120,6 +120,8 @@ TEST_CASE("Text Basic", "[tvgText]")
|
||||||
Initializer::init(0);
|
Initializer::init(0);
|
||||||
|
|
||||||
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
||||||
|
uint32_t buffer[100*100];
|
||||||
|
canvas->target(buffer, 100, 100, 100, ColorSpace::ABGR8888);
|
||||||
|
|
||||||
auto text = Text::gen();
|
auto text = Text::gen();
|
||||||
REQUIRE(text);
|
REQUIRE(text);
|
||||||
|
@ -144,6 +146,8 @@ TEST_CASE("Text with composite glyphs", "[tvgText]")
|
||||||
Initializer::init(0);
|
Initializer::init(0);
|
||||||
|
|
||||||
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
||||||
|
uint32_t buffer[100*100];
|
||||||
|
canvas->target(buffer, 100, 100, 100, ColorSpace::ABGR8888);
|
||||||
|
|
||||||
auto text = Text::gen();
|
auto text = Text::gen();
|
||||||
REQUIRE(text);
|
REQUIRE(text);
|
||||||
|
|
Loading…
Add table
Reference in a new issue