mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
renderer: add a new scene effect type - Fill
Fill is used for overriding the scene content color with a given fill information. It's yet an Experimental API. issue: https://github.com/thorvg/thorvg/issues/2718
This commit is contained in:
parent
e34ba91ff1
commit
d6c80f538c
12 changed files with 108 additions and 30 deletions
|
@ -226,7 +226,8 @@ enum class SceneEffect : uint8_t
|
||||||
{
|
{
|
||||||
ClearAll = 0, ///< Reset all previously applied scene effects, restoring the scene to its original state.
|
ClearAll = 0, ///< Reset all previously applied scene effects, restoring the scene to its original state.
|
||||||
GaussianBlur, ///< Apply a blur effect with a Gaussian filter. Param(3) = {sigma(float)[> 0], direction(int)[both: 0 / horizontal: 1 / vertical: 2], border(int)[duplicate: 0 / wrap: 1], quality(int)[0 - 100]}
|
GaussianBlur, ///< Apply a blur effect with a Gaussian filter. Param(3) = {sigma(float)[> 0], direction(int)[both: 0 / horizontal: 1 / vertical: 2], border(int)[duplicate: 0 / wrap: 1], quality(int)[0 - 100]}
|
||||||
DropShadow ///< Apply a drop shadow effect with a Gaussian Blur filter. Param(8) = {color_R(int)[0 - 255], color_G(int)[0 - 255], color_B(int)[0 - 255], opacity(int)[0 - 255], angle(float)[0 - 360], distance(float), blur_sigma(float)[> 0], quality(int)[0 - 100]}
|
DropShadow, ///< Apply a drop shadow effect with a Gaussian Blur filter. Param(8) = {color_R(int)[0 - 255], color_G(int)[0 - 255], color_B(int)[0 - 255], opacity(int)[0 - 255], angle(float)[0 - 360], distance(float), blur_sigma(float)[> 0], quality(int)[0 - 100]}
|
||||||
|
Fill ///< Override the scene content color with a given fill information (Experimental API). Param(5) = {color_R(int)[0 - 255], color_G(int)[0 - 255], color_B(int)[0 - 255], opacity(int)[0 - 255]}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -982,7 +982,7 @@ bool GlRenderer::prepare(TVG_UNUSED RenderEffect* effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GlRenderer::effect(TVG_UNUSED RenderCompositor* cmp, TVG_UNUSED const RenderEffect* effect, TVG_UNUSED uint8_t opacity, TVG_UNUSED bool direct)
|
bool GlRenderer::effect(TVG_UNUSED RenderCompositor* cmp, TVG_UNUSED const RenderEffect* effect, TVG_UNUSED bool direct)
|
||||||
{
|
{
|
||||||
TVGLOG("GL_ENGINE", "SceneEffect(%d) is not supported", (int)effect->type);
|
TVGLOG("GL_ENGINE", "SceneEffect(%d) is not supported", (int)effect->type);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -87,7 +87,7 @@ public:
|
||||||
bool endComposite(RenderCompositor* cmp) override;
|
bool endComposite(RenderCompositor* cmp) override;
|
||||||
|
|
||||||
bool prepare(RenderEffect* effect) override;
|
bool prepare(RenderEffect* effect) override;
|
||||||
bool effect(RenderCompositor* cmp, const RenderEffect* effect, uint8_t opacity, bool direct) override;
|
bool effect(RenderCompositor* cmp, const RenderEffect* effect, bool direct) override;
|
||||||
|
|
||||||
static GlRenderer* gen();
|
static GlRenderer* gen();
|
||||||
static int init(TVG_UNUSED uint32_t threads);
|
static int init(TVG_UNUSED uint32_t threads);
|
||||||
|
|
|
@ -574,7 +574,9 @@ bool rasterConvertCS(RenderSurface* surface, ColorSpace to);
|
||||||
|
|
||||||
bool effectGaussianBlur(SwCompositor* cmp, SwSurface* surface, const RenderEffectGaussianBlur* params);
|
bool effectGaussianBlur(SwCompositor* cmp, SwSurface* surface, const RenderEffectGaussianBlur* params);
|
||||||
bool effectGaussianBlurPrepare(RenderEffectGaussianBlur* effect);
|
bool effectGaussianBlurPrepare(RenderEffectGaussianBlur* effect);
|
||||||
bool effectDropShadow(SwCompositor* cmp, SwSurface* surfaces[2], const RenderEffectDropShadow* params, uint8_t opacity, bool direct);
|
bool effectDropShadow(SwCompositor* cmp, SwSurface* surfaces[2], const RenderEffectDropShadow* params, bool direct);
|
||||||
bool effectDropShadowPrepare(RenderEffectDropShadow* effect);
|
bool effectDropShadowPrepare(RenderEffectDropShadow* effect);
|
||||||
|
bool effectFillPrepare(RenderEffectFill* effect);
|
||||||
|
bool effectFill(SwCompositor* cmp, const RenderEffectFill* params, bool direct);
|
||||||
|
|
||||||
#endif /* _TVG_SW_COMMON_H_ */
|
#endif /* _TVG_SW_COMMON_H_ */
|
||||||
|
|
|
@ -150,7 +150,6 @@ bool effectGaussianBlurPrepare(RenderEffectGaussianBlur* params)
|
||||||
|
|
||||||
//invalid
|
//invalid
|
||||||
if (extends == 0) {
|
if (extends == 0) {
|
||||||
params->invalid = true;
|
|
||||||
free(rd);
|
free(rd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -158,6 +157,7 @@ bool effectGaussianBlurPrepare(RenderEffectGaussianBlur* params)
|
||||||
_gaussianExtendRegion(params->extend, extends, params->direction);
|
_gaussianExtendRegion(params->extend, extends, params->direction);
|
||||||
|
|
||||||
params->rd = rd;
|
params->rd = rd;
|
||||||
|
params->valid = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -165,11 +165,6 @@ bool effectGaussianBlurPrepare(RenderEffectGaussianBlur* params)
|
||||||
|
|
||||||
bool effectGaussianBlur(SwCompositor* cmp, SwSurface* surface, const RenderEffectGaussianBlur* params)
|
bool effectGaussianBlur(SwCompositor* cmp, SwSurface* surface, const RenderEffectGaussianBlur* params)
|
||||||
{
|
{
|
||||||
if (cmp->image.channelSize != sizeof(uint32_t)) {
|
|
||||||
TVGERR("SW_ENGINE", "Not supported grayscale Gaussian Blur!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& buffer = surface->compositor->image;
|
auto& buffer = surface->compositor->image;
|
||||||
auto data = static_cast<SwGaussianBlur*>(params->rd);
|
auto data = static_cast<SwGaussianBlur*>(params->rd);
|
||||||
auto& bbox = cmp->bbox;
|
auto& bbox = cmp->bbox;
|
||||||
|
@ -310,7 +305,6 @@ bool effectDropShadowPrepare(RenderEffectDropShadow* params)
|
||||||
|
|
||||||
//invalid
|
//invalid
|
||||||
if (extends == 0 || params->color[3] == 0) {
|
if (extends == 0 || params->color[3] == 0) {
|
||||||
params->invalid = true;
|
|
||||||
free(rd);
|
free(rd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -327,6 +321,7 @@ bool effectDropShadowPrepare(RenderEffectDropShadow* params)
|
||||||
_dropShadowExtendRegion(params->extend, extends, rd->offset);
|
_dropShadowExtendRegion(params->extend, extends, rd->offset);
|
||||||
|
|
||||||
params->rd = rd;
|
params->rd = rd;
|
||||||
|
params->valid = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -335,13 +330,8 @@ bool effectDropShadowPrepare(RenderEffectDropShadow* params)
|
||||||
//A quite same integration with effectGaussianBlur(). See it for detailed comments.
|
//A quite same integration with effectGaussianBlur(). See it for detailed comments.
|
||||||
//surface[0]: the original image, to overlay it into the filtered image.
|
//surface[0]: the original image, to overlay it into the filtered image.
|
||||||
//surface[1]: temporary buffer for generating the filtered image.
|
//surface[1]: temporary buffer for generating the filtered image.
|
||||||
bool effectDropShadow(SwCompositor* cmp, SwSurface* surface[2], const RenderEffectDropShadow* params, uint8_t opacity, bool direct)
|
bool effectDropShadow(SwCompositor* cmp, SwSurface* surface[2], const RenderEffectDropShadow* params, bool direct)
|
||||||
{
|
{
|
||||||
if (cmp->image.channelSize != sizeof(uint32_t)) {
|
|
||||||
TVGERR("SW_ENGINE", "Not supported grayscale Drop Shadow!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME: if the body is partially visible due to clipping, the shadow also becomes partially visible.
|
//FIXME: if the body is partially visible due to clipping, the shadow also becomes partially visible.
|
||||||
|
|
||||||
auto data = static_cast<SwDropShadow*>(params->rd);
|
auto data = static_cast<SwDropShadow*>(params->rd);
|
||||||
|
@ -357,7 +347,8 @@ bool effectDropShadow(SwCompositor* cmp, SwSurface* surface[2], const RenderEffe
|
||||||
auto stride = cmp->image.stride;
|
auto stride = cmp->image.stride;
|
||||||
auto front = cmp->image.buf32;
|
auto front = cmp->image.buf32;
|
||||||
auto back = buffer[1]->buf32;
|
auto back = buffer[1]->buf32;
|
||||||
opacity = MULTIPLY(params->color[3], opacity);
|
|
||||||
|
auto opacity = direct ? MULTIPLY(params->color[3], cmp->opacity) : params->color[3];
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "DropShadow region(%ld, %ld, %ld, %ld) params(%f %f %f), level(%d)", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y, params->angle, params->distance, params->sigma, data->level);
|
TVGLOG("SW_ENGINE", "DropShadow region(%ld, %ld, %ld, %ld) params(%f %f %f), level(%d)", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y, params->angle, params->distance, params->sigma, data->level);
|
||||||
|
|
||||||
|
@ -408,3 +399,54 @@ bool effectDropShadow(SwCompositor* cmp, SwSurface* surface[2], const RenderEffe
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Fill Implementation */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
bool effectFillPrepare(RenderEffectFill* params)
|
||||||
|
{
|
||||||
|
params->valid = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool effectFill(SwCompositor* cmp, const RenderEffectFill* params, bool direct)
|
||||||
|
{
|
||||||
|
auto opacity = direct ? MULTIPLY(params->color[3], cmp->opacity) : params->color[3];
|
||||||
|
|
||||||
|
auto& bbox = cmp->bbox;
|
||||||
|
auto w = (bbox.max.x - bbox.min.x);
|
||||||
|
auto h = (bbox.max.y - bbox.min.y);
|
||||||
|
auto color = cmp->recoverSfc->join(params->color[0], params->color[1], params->color[2], 255);
|
||||||
|
|
||||||
|
TVGLOG("SW_ENGINE", "Fill region(%ld, %ld, %ld, %ld), param(%d %d %d %d)", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y, params->color[0], params->color[1], params->color[2], params->color[3]);
|
||||||
|
|
||||||
|
if (direct) {
|
||||||
|
auto dbuffer = cmp->recoverSfc->buf32 + (bbox.min.y * cmp->recoverSfc->stride + bbox.min.x);
|
||||||
|
auto sbuffer = cmp->image.buf32 + (bbox.min.y * cmp->image.stride + bbox.min.x);
|
||||||
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
|
auto dst = dbuffer;
|
||||||
|
auto src = sbuffer;
|
||||||
|
for (uint32_t x = 0; x < w; ++x, ++dst, ++src) {
|
||||||
|
auto a = MULTIPLY(opacity, A(*src));
|
||||||
|
auto tmp = ALPHA_BLEND(color, a);
|
||||||
|
*dst = tmp + ALPHA_BLEND(*dst, 255 - a);
|
||||||
|
}
|
||||||
|
dbuffer += cmp->image.stride;
|
||||||
|
sbuffer += cmp->recoverSfc->stride;
|
||||||
|
}
|
||||||
|
cmp->valid = true; //no need the subsequent composition
|
||||||
|
} else {
|
||||||
|
auto dbuffer = cmp->image.buf32 + (bbox.min.y * cmp->image.stride + bbox.min.x);
|
||||||
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
|
auto dst = dbuffer;
|
||||||
|
for (uint32_t x = 0; x < w; ++x, ++dst) {
|
||||||
|
*dst = ALPHA_BLEND(color, MULTIPLY(opacity, A(*dst)));
|
||||||
|
}
|
||||||
|
dbuffer += cmp->image.stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -634,12 +634,15 @@ bool SwRenderer::endComposite(RenderCompositor* cmp)
|
||||||
if (!cmp) return false;
|
if (!cmp) return false;
|
||||||
|
|
||||||
auto p = static_cast<SwCompositor*>(cmp);
|
auto p = static_cast<SwCompositor*>(cmp);
|
||||||
p->valid = true;
|
|
||||||
|
|
||||||
//Recover Context
|
//Recover Context
|
||||||
surface = p->recoverSfc;
|
surface = p->recoverSfc;
|
||||||
surface->compositor = p->recoverCmp;
|
surface->compositor = p->recoverCmp;
|
||||||
|
|
||||||
|
//only invalid (currently used) surface can be composited
|
||||||
|
if (p->valid) return true;
|
||||||
|
p->valid = true;
|
||||||
|
|
||||||
//Default is alpha blending
|
//Default is alpha blending
|
||||||
if (p->method == MaskMethod::None) {
|
if (p->method == MaskMethod::None) {
|
||||||
Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
||||||
|
@ -655,17 +658,23 @@ bool SwRenderer::prepare(RenderEffect* effect)
|
||||||
switch (effect->type) {
|
switch (effect->type) {
|
||||||
case SceneEffect::GaussianBlur: return effectGaussianBlurPrepare(static_cast<RenderEffectGaussianBlur*>(effect));
|
case SceneEffect::GaussianBlur: return effectGaussianBlurPrepare(static_cast<RenderEffectGaussianBlur*>(effect));
|
||||||
case SceneEffect::DropShadow: return effectDropShadowPrepare(static_cast<RenderEffectDropShadow*>(effect));
|
case SceneEffect::DropShadow: return effectDropShadowPrepare(static_cast<RenderEffectDropShadow*>(effect));
|
||||||
|
case SceneEffect::Fill: return effectFillPrepare(static_cast<RenderEffectFill*>(effect));
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SwRenderer::effect(RenderCompositor* cmp, const RenderEffect* effect, uint8_t opacity, bool direct)
|
bool SwRenderer::effect(RenderCompositor* cmp, const RenderEffect* effect, bool direct)
|
||||||
{
|
{
|
||||||
if (effect->invalid) return false;
|
if (!effect->valid) return false;
|
||||||
|
|
||||||
auto p = static_cast<SwCompositor*>(cmp);
|
auto p = static_cast<SwCompositor*>(cmp);
|
||||||
|
|
||||||
|
if (p->image.channelSize != sizeof(uint32_t)) {
|
||||||
|
TVGERR("SW_ENGINE", "Not supported grayscale Gaussian Blur!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (effect->type) {
|
switch (effect->type) {
|
||||||
case SceneEffect::GaussianBlur: {
|
case SceneEffect::GaussianBlur: {
|
||||||
return effectGaussianBlur(p, request(surface->channelSize, true), static_cast<const RenderEffectGaussianBlur*>(effect));
|
return effectGaussianBlur(p, request(surface->channelSize, true), static_cast<const RenderEffectGaussianBlur*>(effect));
|
||||||
|
@ -675,10 +684,13 @@ bool SwRenderer::effect(RenderCompositor* cmp, const RenderEffect* effect, uint8
|
||||||
cmp1->compositor->valid = false;
|
cmp1->compositor->valid = false;
|
||||||
auto cmp2 = request(surface->channelSize, true);
|
auto cmp2 = request(surface->channelSize, true);
|
||||||
SwSurface* surfaces[] = {cmp1, cmp2};
|
SwSurface* surfaces[] = {cmp1, cmp2};
|
||||||
auto ret = effectDropShadow(p, surfaces, static_cast<const RenderEffectDropShadow*>(effect), opacity, direct);
|
auto ret = effectDropShadow(p, surfaces, static_cast<const RenderEffectDropShadow*>(effect), direct);
|
||||||
cmp1->compositor->valid = true;
|
cmp1->compositor->valid = true;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
case SceneEffect::Fill: {
|
||||||
|
return effectFill(p, static_cast<const RenderEffectFill*>(effect), direct);
|
||||||
|
}
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
void clearCompositors();
|
void clearCompositors();
|
||||||
|
|
||||||
bool prepare(RenderEffect* effect) override;
|
bool prepare(RenderEffect* effect) override;
|
||||||
bool effect(RenderCompositor* cmp, const RenderEffect* effect, uint8_t opacity, bool direct) override;
|
bool effect(RenderCompositor* cmp, const RenderEffect* effect, bool direct) override;
|
||||||
|
|
||||||
static SwRenderer* gen();
|
static SwRenderer* gen();
|
||||||
static bool init(uint32_t threads);
|
static bool init(uint32_t threads);
|
||||||
|
|
|
@ -260,7 +260,7 @@ struct RenderEffect
|
||||||
RenderData rd = nullptr;
|
RenderData rd = nullptr;
|
||||||
RenderRegion extend = {0, 0, 0, 0};
|
RenderRegion extend = {0, 0, 0, 0};
|
||||||
SceneEffect type;
|
SceneEffect type;
|
||||||
bool invalid = false;
|
bool valid = false;
|
||||||
|
|
||||||
virtual ~RenderEffect()
|
virtual ~RenderEffect()
|
||||||
{
|
{
|
||||||
|
@ -311,6 +311,22 @@ struct RenderEffectDropShadow : RenderEffect
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RenderEffectFill : RenderEffect
|
||||||
|
{
|
||||||
|
uint8_t color[4]; //rgba
|
||||||
|
|
||||||
|
static RenderEffectFill* gen(va_list& args)
|
||||||
|
{
|
||||||
|
auto inst = new RenderEffectFill;
|
||||||
|
inst->color[0] = va_arg(args, int);
|
||||||
|
inst->color[1] = va_arg(args, int);
|
||||||
|
inst->color[2] = va_arg(args, int);
|
||||||
|
inst->color[3] = std::min(va_arg(args, int), 255);
|
||||||
|
inst->type = SceneEffect::Fill;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class RenderMethod
|
class RenderMethod
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -344,7 +360,7 @@ public:
|
||||||
virtual bool endComposite(RenderCompositor* cmp) = 0;
|
virtual bool endComposite(RenderCompositor* cmp) = 0;
|
||||||
|
|
||||||
virtual bool prepare(RenderEffect* effect) = 0;
|
virtual bool prepare(RenderEffect* effect) = 0;
|
||||||
virtual bool effect(RenderCompositor* cmp, const RenderEffect* effect, uint8_t opacity, bool direct) = 0;
|
virtual bool effect(RenderCompositor* cmp, const RenderEffect* effect, bool direct) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool MASK_REGION_MERGING(MaskMethod method)
|
static inline bool MASK_REGION_MERGING(MaskMethod method)
|
||||||
|
|
|
@ -109,6 +109,10 @@ Result Scene::push(SceneEffect effect, ...) noexcept
|
||||||
re = RenderEffectDropShadow::gen(args);
|
re = RenderEffectDropShadow::gen(args);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SceneEffect::Fill: {
|
||||||
|
re = RenderEffectFill::gen(args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,9 +141,10 @@ struct Scene::Impl
|
||||||
if (cmp) {
|
if (cmp) {
|
||||||
//Apply post effects if any.
|
//Apply post effects if any.
|
||||||
if (effects) {
|
if (effects) {
|
||||||
auto direct = effects->count == 1 ? true : false;
|
//Notify the possiblity of the direct composition of the effect result to the origin surface.
|
||||||
|
auto direct = (effects->count == 1) & (compFlag == CompositionFlag::PostProcessing);
|
||||||
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
||||||
renderer->effect(cmp, *e, opacity, direct);
|
renderer->effect(cmp, *e, direct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderer->endComposite(cmp);
|
renderer->endComposite(cmp);
|
||||||
|
@ -176,7 +177,7 @@ struct Scene::Impl
|
||||||
if (effects) {
|
if (effects) {
|
||||||
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
for (auto e = effects->begin(); e < effects->end(); ++e) {
|
||||||
auto effect = *e;
|
auto effect = *e;
|
||||||
if (effect->rd || renderer->prepare(effect)) {
|
if (effect->valid || renderer->prepare(effect)) {
|
||||||
ex = std::min(ex, effect->extend.x);
|
ex = std::min(ex, effect->extend.x);
|
||||||
ey = std::min(ey, effect->extend.y);
|
ey = std::min(ey, effect->extend.y);
|
||||||
ew = std::max(ew, effect->extend.w);
|
ew = std::max(ew, effect->extend.w);
|
||||||
|
|
|
@ -473,7 +473,7 @@ bool WgRenderer::prepare(TVG_UNUSED RenderEffect* effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool WgRenderer::effect(TVG_UNUSED RenderCompositor* cmp, TVG_UNUSED const RenderEffect* effect, TVG_UNUSED uint8_t opacity, TVG_UNUSED bool direct)
|
bool WgRenderer::effect(TVG_UNUSED RenderCompositor* cmp, TVG_UNUSED const RenderEffect* effect, TVG_UNUSED bool direct)
|
||||||
{
|
{
|
||||||
TVGLOG("WG_ENGINE", "SceneEffect(%d) is not supported", (int)effect->type);
|
TVGLOG("WG_ENGINE", "SceneEffect(%d) is not supported", (int)effect->type);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
bool endComposite(RenderCompositor* cmp) override;
|
bool endComposite(RenderCompositor* cmp) override;
|
||||||
|
|
||||||
bool prepare(RenderEffect* effect) override;
|
bool prepare(RenderEffect* effect) override;
|
||||||
bool effect(RenderCompositor* cmp, const RenderEffect* effect, uint8_t opacity, bool direct) override;
|
bool effect(RenderCompositor* cmp, const RenderEffect* effect, bool direct) override;
|
||||||
|
|
||||||
static WgRenderer* gen();
|
static WgRenderer* gen();
|
||||||
static bool init(uint32_t threads);
|
static bool init(uint32_t threads);
|
||||||
|
|
Loading…
Add table
Reference in a new issue