From 9a40b6426189c37abece95ed81d832b428d8f5be Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 5 Apr 2021 17:15:37 +0900 Subject: [PATCH] sw_engine raster: ++ precise alpha multiplying previously alpha multiplying operation doesn't have perfect precision, could loss 1 pixel since it divides 255 values by 256. This improved operation comply with both precision & performance. --- src/lib/sw_engine/tvgSwCommon.h | 2 +- src/lib/sw_engine/tvgSwRaster.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index d30bf43c..32adfd61 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -274,7 +274,7 @@ static inline uint32_t COLOR_INTERPOLATE(uint32_t c1, uint32_t a1, uint32_t c2, static inline uint8_t ALPHA_MULTIPLY(uint32_t c, uint32_t a) { - return (c * a) >> 8; + return ((c * a + 0xff) >> 8); } static inline SwCoord HALF_STROKE(float width) diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index 23c68157..b7878ea5 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -851,9 +851,11 @@ bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - r = ALPHA_MULTIPLY(r, a); - g = ALPHA_MULTIPLY(g, a); - b = ALPHA_MULTIPLY(b, a); + if (a < 255) { + r = ALPHA_MULTIPLY(r, a); + g = ALPHA_MULTIPLY(g, a); + b = ALPHA_MULTIPLY(b, a); + } auto color = surface->blender.join(r, g, b, a); auto translucent = _translucent(surface, a); @@ -872,9 +874,11 @@ bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - r = ALPHA_MULTIPLY(r, a); - g = ALPHA_MULTIPLY(g, a); - b = ALPHA_MULTIPLY(b, a); + if (a < 255) { + r = ALPHA_MULTIPLY(r, a); + g = ALPHA_MULTIPLY(g, a); + b = ALPHA_MULTIPLY(b, a); + } auto color = surface->blender.join(r, g, b, a); auto translucent = _translucent(surface, a);