mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
common paint: alpha masking optimization
applying fast track approach to the alpha mask when its condition is matched. (simple rectangle alpha masking which isn't half-translucent) From time to time, designers brutally use the alpha masking to clip simple region, thorvg can help the situation by avoiding masking usage internally. This can reduce the 1-step render pass composition. @Issue: https://github.com/Samsung/thorvg/issues/344
This commit is contained in:
parent
91668143e1
commit
44ccfc46d8
2 changed files with 23 additions and 8 deletions
|
@ -34,7 +34,7 @@ static inline bool FLT_SAME(float a, float b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _clipPathFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport)
|
static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport)
|
||||||
{
|
{
|
||||||
/* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */
|
/* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */
|
||||||
auto shape = static_cast<Shape*>(cmpTarget);
|
auto shape = static_cast<Shape*>(cmpTarget);
|
||||||
|
@ -164,9 +164,11 @@ bool Paint::Impl::render(RenderMethod& renderer)
|
||||||
{
|
{
|
||||||
Compositor* cmp = nullptr;
|
Compositor* cmp = nullptr;
|
||||||
|
|
||||||
|
//OPTIMIZE_ME: Can we replace the simple AlphaMasking with ClipPath?
|
||||||
|
|
||||||
/* Note: only ClipPath is processed in update() step.
|
/* Note: only ClipPath is processed in update() step.
|
||||||
Create a composition image. */
|
Create a composition image. */
|
||||||
if (cmpTarget && cmpMethod != CompositeMethod::ClipPath) {
|
if (cmpTarget && cmpMethod != CompositeMethod::ClipPath && !(cmpTarget->pImpl->ctxFlag & ContextFlag::FastTrack)) {
|
||||||
auto region = smethod->bounds(renderer);
|
auto region = smethod->bounds(renderer);
|
||||||
if (region.w == 0 || region.h == 0) return false;
|
if (region.w == 0 || region.h == 0) return false;
|
||||||
cmp = renderer.target(region);
|
cmp = renderer.target(region);
|
||||||
|
@ -200,17 +202,27 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
|
||||||
bool cmpFastTrack = false;
|
bool cmpFastTrack = false;
|
||||||
|
|
||||||
if (cmpTarget) {
|
if (cmpTarget) {
|
||||||
/* If transform has no rotation factors && ClipPath is a simple rectangle,
|
/* If transform has no rotation factors && ClipPath / AlphaMasking is a simple rectangle,
|
||||||
we can avoid regular ClipPath sequence but use viewport for performance */
|
we can avoid regular ClipPath / AlphaMasking sequence but use viewport for performance */
|
||||||
if (cmpMethod == CompositeMethod::ClipPath) {
|
auto tryFastTrack = false;
|
||||||
|
if (cmpMethod == CompositeMethod::ClipPath) tryFastTrack = true;
|
||||||
|
else if (cmpMethod == CompositeMethod::AlphaMask) {
|
||||||
|
auto shape = static_cast<Shape*>(cmpTarget);
|
||||||
|
uint8_t a;
|
||||||
|
shape->fillColor(nullptr, nullptr, nullptr, &a);
|
||||||
|
if (a == 255 && shape->opacity() == 255 && !shape->fill()) tryFastTrack = true;
|
||||||
|
}
|
||||||
|
if (tryFastTrack) {
|
||||||
RenderRegion viewport2;
|
RenderRegion viewport2;
|
||||||
if ((cmpFastTrack = _clipPathFastTrack(cmpTarget, pTransform, cmpTarget->pImpl->rTransform, viewport2))) {
|
if ((cmpFastTrack = _compFastTrack(cmpTarget, pTransform, cmpTarget->pImpl->rTransform, viewport2))) {
|
||||||
viewport = renderer.viewport();
|
viewport = renderer.viewport();
|
||||||
viewport2.intersect(viewport);
|
viewport2.intersect(viewport);
|
||||||
renderer.viewport(viewport2);
|
renderer.viewport(viewport2);
|
||||||
|
cmpTarget->pImpl->ctxFlag |= ContextFlag::FastTrack;
|
||||||
|
} else {
|
||||||
|
cmpTarget->pImpl->ctxFlag &= ~ContextFlag::FastTrack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmpFastTrack) {
|
if (!cmpFastTrack) {
|
||||||
cmpData = cmpTarget->pImpl->update(renderer, pTransform, 255, clips, pFlag);
|
cmpData = cmpTarget->pImpl->update(renderer, pTransform, 255, clips, pFlag);
|
||||||
if (cmpMethod == CompositeMethod::ClipPath) clips.push(cmpData);
|
if (cmpMethod == CompositeMethod::ClipPath) clips.push(cmpData);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
enum ContextFlag {Invalid = 0, FastTrack = 1};
|
||||||
|
|
||||||
struct Iterator
|
struct Iterator
|
||||||
{
|
{
|
||||||
virtual ~Iterator() {}
|
virtual ~Iterator() {}
|
||||||
|
@ -51,10 +53,11 @@ namespace tvg
|
||||||
struct Paint::Impl
|
struct Paint::Impl
|
||||||
{
|
{
|
||||||
StrategyMethod* smethod = nullptr;
|
StrategyMethod* smethod = nullptr;
|
||||||
RenderTransform *rTransform = nullptr;
|
RenderTransform* rTransform = nullptr;
|
||||||
uint32_t renderFlag = RenderUpdateFlag::None;
|
uint32_t renderFlag = RenderUpdateFlag::None;
|
||||||
Paint* cmpTarget = nullptr;
|
Paint* cmpTarget = nullptr;
|
||||||
CompositeMethod cmpMethod = CompositeMethod::None;
|
CompositeMethod cmpMethod = CompositeMethod::None;
|
||||||
|
uint32_t ctxFlag = ContextFlag::Invalid;
|
||||||
uint8_t opacity = 255;
|
uint8_t opacity = 255;
|
||||||
|
|
||||||
~Impl() {
|
~Impl() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue