diff options
-rw-r--r-- | graphics/VectorRenderer.cpp | 76 | ||||
-rw-r--r-- | graphics/VectorRenderer.h | 47 |
2 files changed, 79 insertions, 44 deletions
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index 9a10428b64..9dc2fa6ce6 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -211,7 +211,7 @@ drawLine(int x1, int y1, int x2, int y2) { if (dy == 0) { // horizontal lines // these can be filled really fast with a single memset. // TODO: Platform specific ASM in set_to, would make this thing fly - Common::set_to(ptr, ptr + dx + 1, (PixelType)_fgColor); + colorFill(ptr, ptr + dx + 1, (PixelType)_fgColor); } else if (dx == 0) { // vertical lines // these ones use a static pitch increase. @@ -366,21 +366,21 @@ drawSquareAlg(int x, int y, int w, int h, PixelType color, FillMode fill_m) { if (fill_m == kGradientFill) color = calcGradient(max_h - h, max_h); - Common::set_to(ptr, ptr + w, color); + colorFill(ptr, ptr + w, color); ptr += pitch; } } else { int sw = Base::_strokeWidth, sp = 0, hp = pitch * (h - 1); while (sw--) { - Common::set_to(ptr + sp, ptr + w + sp, color); - Common::set_to(ptr + hp - sp, ptr + w + hp - sp, color); + colorFill(ptr + sp, ptr + w + sp, color); + colorFill(ptr + hp - sp, ptr + w + hp - sp, color); sp += pitch; } while (h--) { - Common::set_to(ptr, ptr + Base::_strokeWidth, color); - Common::set_to(ptr + w - Base::_strokeWidth, ptr + w, color); + colorFill(ptr, ptr + Base::_strokeWidth, color); + colorFill(ptr + w - Base::_strokeWidth, ptr + w, color); ptr += pitch; } } @@ -455,8 +455,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillM if (fill_m == kNoFill) { while (sw++ < Base::_strokeWidth) { - Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); - Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); + colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); + colorFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); sp += pitch; __BE_RESET(); @@ -475,8 +475,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillM ptr_fill += pitch * real_radius; while (short_h--) { - Common::set_to(ptr_fill, ptr_fill + Base::_strokeWidth, color); - Common::set_to(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color); + colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color); + colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color); ptr_fill += pitch; } } else { @@ -485,21 +485,21 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillM if (fill_m == kGradientFill) { while (x++ < y) { __BE_ALGORITHM(); - Common::set_to(ptr_tl - x - py, ptr_tr + x - py, calcGradient(real_radius - y, long_h)); - Common::set_to(ptr_tl - y - px, ptr_tr + y - px, calcGradient(real_radius - x, long_h)); + colorFill(ptr_tl - x - py, ptr_tr + x - py, calcGradient(real_radius - y, long_h)); + colorFill(ptr_tl - y - px, ptr_tr + y - px, calcGradient(real_radius - x, long_h)); - Common::set_to(ptr_bl - x + py, ptr_br + x + py, calcGradient(long_h - r + y, long_h)); - Common::set_to(ptr_bl - y + px, ptr_br + y + px, calcGradient(long_h - r + x, long_h)); + colorFill(ptr_bl - x + py, ptr_br + x + py, calcGradient(long_h - r + y, long_h)); + colorFill(ptr_bl - y + px, ptr_br + y + px, calcGradient(long_h - r + x, long_h)); } } else { while (x++ < y) { __BE_ALGORITHM(); - Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color); - Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color); + colorFill(ptr_tl - x - py, ptr_tr + x - py, color); + colorFill(ptr_tl - y - px, ptr_tr + y - px, color); - Common::set_to(ptr_bl - x + py, ptr_br + x + py, color); - Common::set_to(ptr_bl - y + px, ptr_br + y + px, color); + colorFill(ptr_bl - x + py, ptr_br + x + py, color); + colorFill(ptr_bl - y + px, ptr_br + y + px, color); // FIXME: maybe not needed at all? __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); @@ -510,7 +510,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillM while (short_h--) { if (fill_m == kGradientFill) color = calcGradient(real_radius++, long_h); - Common::set_to(ptr_fill, ptr_fill + w + 1, color); + colorFill(ptr_fill, ptr_fill + w + 1, color); ptr_fill += pitch; } } @@ -546,15 +546,15 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, FillMode fill_m) { } } } else { - Common::set_to(ptr - r, ptr + r, color); + colorFill(ptr - r, ptr + r, color); __BE_RESET(); while (x++ < y) { __BE_ALGORITHM(); - Common::set_to(ptr - x + py, ptr + x + py, color); - Common::set_to(ptr - x - py, ptr + x - py, color); - Common::set_to(ptr - y + px, ptr + y + px, color); - Common::set_to(ptr - y - px, ptr + y - px, color); + colorFill(ptr - x + py, ptr + x + py, color); + colorFill(ptr - x - py, ptr + x - py, color); + colorFill(ptr - y + px, ptr + y + px, color); + colorFill(ptr - y - px, ptr + y - px, color); } } } @@ -732,8 +732,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto if (fill_m == VectorRenderer::kNoFill) { while (sw++ < Base::_strokeWidth) { - Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); - Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); + colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); + colorFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); sp += p; x = r - (sw - 1); y = 0; T = 0; @@ -752,8 +752,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto ptr_fill += p * r; while (short_h-- >= 0) { - Common::set_to(ptr_fill, ptr_fill + Base::_strokeWidth, color); - Common::set_to(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color); + colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color); + colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color); ptr_fill += p; } } else { @@ -763,18 +763,18 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto while (x > y++) { __WU_ALGORITHM(); - Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color); - Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color); + colorFill(ptr_tl - x - py, ptr_tr + x - py, color); + colorFill(ptr_tl - y - px, ptr_tr + y - px, color); - Common::set_to(ptr_bl - x + py, ptr_br + x + py, color); - Common::set_to(ptr_bl - y + px, ptr_br + y + px, color); + colorFill(ptr_bl - x + py, ptr_br + x + py, color); + colorFill(ptr_bl - y + px, ptr_br + y + px, color); __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); } ptr_fill += p * r; while (short_h-- >= 0) { - Common::set_to(ptr_fill, ptr_fill + w + 1, color); + colorFill(ptr_fill, ptr_fill + w + 1, color); ptr_fill += p; } } @@ -814,17 +814,17 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f } } } else { - Common::set_to(ptr - r, ptr + r + 1, color); + colorFill(ptr - r, ptr + r + 1, color); x = r; y = 0; T = 0; px = p * x; py = 0; while (x > y++) { __WU_ALGORITHM(); - Common::set_to(ptr - x + py, ptr + x + py, color); - Common::set_to(ptr - x - py, ptr + x - py, color); - Common::set_to(ptr - y + px, ptr + y + px, color); - Common::set_to(ptr - y - px, ptr + y - px, color); + colorFill(ptr - x + py, ptr + x + py, color); + colorFill(ptr - x - py, ptr + x - py, color); + colorFill(ptr - y + px, ptr + y + px, color); + colorFill(ptr - y - px, ptr + y - px, color); __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); } diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 3b5741e83b..4609d51739 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -339,13 +339,13 @@ public: int pitch = surfacePitch(); if (mode == kBackgroundFill) - Common::set_to(ptr, ptr + w * h, _bgColor); + colorFill(ptr, ptr + w * h, _bgColor); else if (mode == kForegroundFill) - Common::set_to(ptr, ptr + w * h, _fgColor); + colorFill(ptr, ptr + w * h, _fgColor); else if (mode == kGradientFill) { int i = h; while (i--) { - Common::set_to(ptr, ptr + w, calcGradient(h - i, h)); + colorFill(ptr, ptr + w, calcGradient(h - i, h)); ptr += pitch; } } @@ -453,7 +453,7 @@ protected: * @param max Maximum amount of the progress. * @return Composite color of the gradient at the given "progress" amount. */ - inline PixelType calcGradient(uint32 pos, uint32 max) { + virtual inline PixelType calcGradient(uint32 pos, uint32 max) { PixelType output = 0; pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max; @@ -475,10 +475,45 @@ protected: * @param color Color of the pixel * @param alpha Alpha intensity of the pixel (0-255) */ - inline void blendFill(PixelType *first, PixelType *last, PixelType color, uint8 alpha) { + virtual inline void blendFill(PixelType *first, PixelType *last, PixelType color, uint8 alpha) { while (first != last) blendPixelPtr(first++, color, alpha); - } + } + + /** + * Fills several pixels in a row with a given color. + * + * This is a replacement function for Common::set_to, using an unrolled + * loop to maximize performance on most architectures. + * This function may (and should) be overloaded in any child renderers + * for portable platforms with platform-specific assembly code. + * + * This fill operation is extensively used throughout the renderer, so this + * counts as one of the main bottlenecks. Please replace it with assembly + * when possible! + * + * @param first Pointer to the first pixel to fill. + * @param last Pointer to the last pixel to fill. + * @param color Color of the pixel + */ + virtual inline void colorFill(PixelType *first, PixelType *last, PixelType color) { + register PixelType *ptr = first; + register int count = (last - first); + { + register int n = (count + 7) / 8; + switch (count % 8) { + case 0: do { *ptr++ = color; + case 7: *ptr++ = color; + case 6: *ptr++ = color; + case 5: *ptr++ = color; + case 4: *ptr++ = color; + case 3: *ptr++ = color; + case 2: *ptr++ = color; + case 1: *ptr++ = color; + } while (--n > 0); + } + } + } PixelType _fgColor; /** Foreground color currently being used to draw on the renderer */ PixelType _bgColor; /** Background color currently being used to draw on the renderer */ |