From d1e211e1537ad4489bc58363e14593c28d3359c6 Mon Sep 17 00:00:00 2001 From: Martin Renold Date: Mon, 11 Apr 2011 16:52:05 +0200 Subject: [PATCH] draw_dab: code refactoring Get rid of multiple mask calculations. Get rid of C++ templates. --- lib/tiledsurface.hpp | 178 +++++++++++++++++++++++++++++---------------------- 1 file changed, 102 insertions(+), 76 deletions(-) diff --git a/lib/tiledsurface.hpp b/lib/tiledsurface.hpp index daa3695..4056cb7 100644 --- a/lib/tiledsurface.hpp +++ b/lib/tiledsurface.hpp @@ -27,57 +27,84 @@ private: int tileMemoryValid; int tileMemoryWrite; - // Containers for inline functions; with compiler optimization - // they will allow for diffrent versions of draw_dab() - // without code duplication or performance loss. - - struct BlendMode_Normal { - inline static void pixel (uint16_t * rgba, - const uint32_t & color_r_, - const uint32_t & color_g_, - const uint32_t & color_b_, - const float & opa) { - uint32_t opa_a = (1<<15)*opa; // topAlpha - uint32_t opa_b = (1<<15)-opa_a; // bottomAlpha - - rgba[3] = opa_a + (opa_b*rgba[3])/(1<<15); - rgba[0] = (opa_a*color_r_ + opa_b*rgba[0])/(1<<15); - rgba[1] = (opa_a*color_g_ + opa_b*rgba[1])/(1<<15); - rgba[2] = (opa_a*color_b_ + opa_b*rgba[2])/(1<<15); + void draw_dab_pixels_BlendMode_Normal (uint16_t * mask, + uint16_t * rgba, + int w, int h, + //int rowstride, + uint32_t color_r_, + uint32_t color_g_, + uint32_t color_b_, + float opacity2) { + for (int y=0; y 0.00001) - surface_modified |= draw_dab_pixels - (x, y, radius, color_r, color_g, color_b, opaque*normal, hardness, - aspect_ratio, angle); - - if (eraser > 0.00001) - surface_modified |= draw_dab_pixels - (x, y, radius, color_r, color_g, color_b, opaque*eraser, hardness, - aspect_ratio, angle); - - if (lock_alpha > 0.00001) - surface_modified |= draw_dab_pixels - (x, y, radius, color_r, color_g, color_b, opaque*lock_alpha, hardness, - aspect_ratio, angle); - - return surface_modified; - } - - template - inline bool draw_dab_pixels (float x, float y, - float radius, - float color_r, float color_g, float color_b, - float opaque, float hardness = 0.5, - float aspect_ratio = 1.0, float angle = 0.0) { + if (!(normal || eraser || lock_alpha)) { + // nothing to do + return false; + } if (aspect_ratio<1.0) aspect_ratio=1.0; @@ -218,7 +223,7 @@ public: uint32_t color_r_ = color_r * (1<<15); uint32_t color_g_ = color_g * (1<<15); uint32_t color_b_ = color_b * (1<<15); - color_r = CLAMP(color_r, 0, (1<<15)); + color_r = CLAMP(color_r, 0, (1<<15)); // <--- FIXME!?! color_g = CLAMP(color_g, 0, (1<<15)); color_b = CLAMP(color_b, 0, (1<<15)); @@ -255,6 +260,9 @@ public: float cs=cos(angle_rad); float sn=sin(angle_rad); + // first, we calculate the mask (opacity for each pixel) + static uint16_t mask_p[TILE_SIZE*TILE_SIZE]; + for (yp = y0; yp <= y1; yp++) { yy = (yp + 0.5 - yc); for (xp = x0; xp <= x1; xp++) { @@ -265,8 +273,9 @@ public: rr = (yyr*yyr + xxr*xxr) * one_over_radius2; // rr is in range 0.0..1.0*sqrt(2) + float opa = 0; if (rr <= 1.0) { - float opa = opaque; + opa = opaque; if (hardness < 1.0) { if (rr < hardness) { opa *= rr + 1-(rr/hardness); @@ -290,15 +299,32 @@ public: assert(opa >= 0.0 && opa <= 1.0); assert(eraser_target_alpha >= 0.0 && eraser_target_alpha <= 1.0); #endif - int idx = (yp*TILE_SIZE + xp)*4; - - BlendMode::pixel(rgba_p+idx, color_r_, color_g_, color_b_, opa); } + int idx = yp*TILE_SIZE + xp; + mask_p[idx] = (1<<15)*opa; } } + + // second, we use the mask to stamp a dab for each activated blend mode + + uint16_t * mask_start = mask_p + 1*(y0*TILE_SIZE + x0); + uint16_t * rgba_start = rgba_p + 4*(y0*TILE_SIZE + x0); + int w = x1-x0+1; + int h = y1-y0+1; + + if (normal > 0.00001) + draw_dab_pixels_BlendMode_Normal(mask_start, rgba_start, w, h, + color_r_, color_g_, color_b_, normal); + if (eraser > 0.00001) + draw_dab_pixels_BlendMode_Eraser(mask_start, rgba_start, w, h, + color_r_, color_g_, color_b_, eraser); + if (lock_alpha > 0.00001) + draw_dab_pixels_BlendMode_LockAlpha(mask_start, rgba_start, w, h, + color_r_, color_g_, color_b_, lock_alpha); } } + { // expand the bounding box to include the region we just drawed int bb_x, bb_y, bb_w, bb_h; -- 2.11.0