diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 14ab78c9..9fa7e247 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -913,11 +913,10 @@ const Surface* GlRenderer::mainSurface() } -bool GlRenderer::blend(TVG_UNUSED BlendMethod method) +bool GlRenderer::blend(TVG_UNUSED BlendMethod method, TVG_UNUSED bool direct) { - if (method != BlendMethod::Normal) { - return true; - } + if (method != BlendMethod::Normal) return true; + //TODO: return false; } diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index b6208bb0..2e20c730 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -63,7 +63,7 @@ public: RenderRegion region(RenderData data) override; RenderRegion viewport() override; bool viewport(const RenderRegion& vp) override; - bool blend(BlendMethod method) override; + bool blend(BlendMethod method, bool direct) override; ColorSpace colorSpace() override; const Surface* mainSurface() override; diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index a6db3ec5..893e9bec 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -363,7 +363,7 @@ static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNU } //TODO: BlendMethod could remove the alpha parameter. -static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, uint8_t a) { //if (s > d) => s - d //else => d - s @@ -400,8 +400,7 @@ static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t return JOIN(255, c1, c2, c3); } - -static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a) { // s * d auto c1 = MULTIPLY(C1(s), C1(d)); @@ -410,6 +409,10 @@ static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_ return JOIN(255, c1, c2, c3); } +static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, uint8_t a) +{ + return opBlendDirectMultiply(s, d, a) + ALPHA_BLEND(d, IA(s)); +} static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) { diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index fe20282a..76cf9ac7 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -1383,7 +1383,7 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image, *dst = INTERPOLATE(tmp, *dst, A(*src)); } } else { - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { auto tmp = ALPHA_BLEND(*src, opacity); auto tmp2 = surface->blender(tmp, *dst, 255); *dst = INTERPOLATE(tmp2, *dst, A(tmp)); diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index 4e30490b..2852dc10 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -100,7 +100,6 @@ struct SwShapeTask : SwTask return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12)); } - bool clip(SwRle* target) override { if (shape.fastTrack) rleClipRect(target, &bbox); @@ -442,7 +441,7 @@ bool SwRenderer::renderShape(RenderData data) } -bool SwRenderer::blend(BlendMethod method) +bool SwRenderer::blend(BlendMethod method, bool direct) { if (surface->blendMethod == method) return true; surface->blendMethod = method; @@ -455,7 +454,7 @@ bool SwRenderer::blend(BlendMethod method) surface->blender = opBlendScreen; break; case BlendMethod::Multiply: - surface->blender = opBlendMultiply; + surface->blender = direct ? opBlendDirectMultiply : opBlendMultiply; break; case BlendMethod::Overlay: surface->blender = opBlendOverlay; diff --git a/src/renderer/sw_engine/tvgSwRenderer.h b/src/renderer/sw_engine/tvgSwRenderer.h index fcd8ad46..7aa6d89a 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.h +++ b/src/renderer/sw_engine/tvgSwRenderer.h @@ -46,7 +46,7 @@ public: RenderRegion region(RenderData data) override; RenderRegion viewport() override; bool viewport(const RenderRegion& vp) override; - bool blend(BlendMethod method) override; + bool blend(BlendMethod method, bool direct) override; ColorSpace colorSpace() override; const Surface* mainSurface() override; diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index 6d6361ce..5a4d008b 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -225,8 +225,6 @@ bool Paint::Impl::render(RenderMethod* renderer) if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity); - renderer->blend(blendMethod); - bool ret; PAINT_METHOD(ret, render(renderer)); diff --git a/src/renderer/tvgPicture.cpp b/src/renderer/tvgPicture.cpp index 6ed151e5..bcd95fb9 100644 --- a/src/renderer/tvgPicture.cpp +++ b/src/renderer/tvgPicture.cpp @@ -73,6 +73,8 @@ bool Picture::Impl::needComposition(uint8_t opacity) bool Picture::Impl::render(RenderMethod* renderer) { bool ret = false; + renderer->blend(picture->blend(), true); + if (surface) return renderer->renderImage(rd); else if (paint) { Compositor* cmp = nullptr; diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index 5ac7e804..5dcaafe1 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -294,7 +294,7 @@ public: virtual RenderRegion region(RenderData data) = 0; virtual RenderRegion viewport() = 0; virtual bool viewport(const RenderRegion& vp) = 0; - virtual bool blend(BlendMethod method) = 0; + virtual bool blend(BlendMethod method, bool direct = false) = 0; virtual ColorSpace colorSpace() = 0; virtual const Surface* mainSurface() = 0; diff --git a/src/renderer/tvgScene.h b/src/renderer/tvgScene.h index c9a6c8e1..46decfaa 100644 --- a/src/renderer/tvgScene.h +++ b/src/renderer/tvgScene.h @@ -120,6 +120,8 @@ struct Scene::Impl Compositor* cmp = nullptr; auto ret = true; + renderer->blend(scene->blend()); + if (needComp) { cmp = renderer->target(bounds(renderer), renderer->colorSpace()); renderer->beginComposite(cmp, CompositeMethod::None, opacity); diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h index a1e96a4a..1460861e 100644 --- a/src/renderer/tvgShape.h +++ b/src/renderer/tvgShape.h @@ -54,10 +54,13 @@ struct Shape::Impl Compositor* cmp = nullptr; bool ret; + renderer->blend(shape->blend(), !needComp); + if (needComp) { cmp = renderer->target(bounds(renderer), renderer->colorSpace()); renderer->beginComposite(cmp, CompositeMethod::None, opacity); } + ret = renderer->renderShape(rd); if (cmp) renderer->endComposite(cmp); return ret; diff --git a/src/renderer/tvgText.h b/src/renderer/tvgText.h index 76a1b30e..f0a343c4 100644 --- a/src/renderer/tvgText.h +++ b/src/renderer/tvgText.h @@ -89,6 +89,7 @@ struct Text::Impl bool render(RenderMethod* renderer) { + renderer->blend(paint->blend(), true); return PP(shape)->render(renderer); } diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 35d3a88a..3bb66561 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -218,7 +218,7 @@ bool WgRenderer::viewport(const RenderRegion& vp) } -bool WgRenderer::blend(BlendMethod method) +bool WgRenderer::blend(BlendMethod method, TVG_UNUSED bool direct) { mBlendMethod = method; return false; diff --git a/src/renderer/wg_engine/tvgWgRenderer.h b/src/renderer/wg_engine/tvgWgRenderer.h index d90d2a68..77a83c7e 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.h +++ b/src/renderer/wg_engine/tvgWgRenderer.h @@ -38,7 +38,7 @@ public: RenderRegion region(RenderData data) override; RenderRegion viewport() override; bool viewport(const RenderRegion& vp) override; - bool blend(BlendMethod method) override; + bool blend(BlendMethod method, bool direct) override; ColorSpace colorSpace() override; const Surface* mainSurface() override;