- Loop unrolling for color fills.
svn-id: r32206
This commit is contained in:
parent
40734a8d6c
commit
0ea6707dc4
2 changed files with 79 additions and 44 deletions
|
@ -211,7 +211,7 @@ drawLine(int x1, int y1, int x2, int y2) {
|
||||||
if (dy == 0) { // horizontal lines
|
if (dy == 0) { // horizontal lines
|
||||||
// these can be filled really fast with a single memset.
|
// these can be filled really fast with a single memset.
|
||||||
// TODO: Platform specific ASM in set_to, would make this thing fly
|
// 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
|
} else if (dx == 0) { // vertical lines
|
||||||
// these ones use a static pitch increase.
|
// 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)
|
if (fill_m == kGradientFill)
|
||||||
color = calcGradient(max_h - h, max_h);
|
color = calcGradient(max_h - h, max_h);
|
||||||
|
|
||||||
Common::set_to(ptr, ptr + w, color);
|
colorFill(ptr, ptr + w, color);
|
||||||
ptr += pitch;
|
ptr += pitch;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int sw = Base::_strokeWidth, sp = 0, hp = pitch * (h - 1);
|
int sw = Base::_strokeWidth, sp = 0, hp = pitch * (h - 1);
|
||||||
|
|
||||||
while (sw--) {
|
while (sw--) {
|
||||||
Common::set_to(ptr + sp, ptr + w + sp, color);
|
colorFill(ptr + sp, ptr + w + sp, color);
|
||||||
Common::set_to(ptr + hp - sp, ptr + w + hp - sp, color);
|
colorFill(ptr + hp - sp, ptr + w + hp - sp, color);
|
||||||
sp += pitch;
|
sp += pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (h--) {
|
while (h--) {
|
||||||
Common::set_to(ptr, ptr + Base::_strokeWidth, color);
|
colorFill(ptr, ptr + Base::_strokeWidth, color);
|
||||||
Common::set_to(ptr + w - Base::_strokeWidth, ptr + w, color);
|
colorFill(ptr + w - Base::_strokeWidth, ptr + w, color);
|
||||||
ptr += pitch;
|
ptr += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,8 +455,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillM
|
||||||
|
|
||||||
if (fill_m == kNoFill) {
|
if (fill_m == kNoFill) {
|
||||||
while (sw++ < Base::_strokeWidth) {
|
while (sw++ < Base::_strokeWidth) {
|
||||||
Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
|
colorFill(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 + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
|
||||||
sp += pitch;
|
sp += pitch;
|
||||||
|
|
||||||
__BE_RESET();
|
__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;
|
ptr_fill += pitch * real_radius;
|
||||||
while (short_h--) {
|
while (short_h--) {
|
||||||
Common::set_to(ptr_fill, ptr_fill + Base::_strokeWidth, color);
|
colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color);
|
||||||
Common::set_to(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
|
colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
|
||||||
ptr_fill += pitch;
|
ptr_fill += pitch;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -485,21 +485,21 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillM
|
||||||
if (fill_m == kGradientFill) {
|
if (fill_m == kGradientFill) {
|
||||||
while (x++ < y) {
|
while (x++ < y) {
|
||||||
__BE_ALGORITHM();
|
__BE_ALGORITHM();
|
||||||
Common::set_to(ptr_tl - x - py, ptr_tr + x - py, calcGradient(real_radius - y, long_h));
|
colorFill(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 - 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));
|
colorFill(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 - y + px, ptr_br + y + px, calcGradient(long_h - r + x, long_h));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (x++ < y) {
|
while (x++ < y) {
|
||||||
__BE_ALGORITHM();
|
__BE_ALGORITHM();
|
||||||
|
|
||||||
Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color);
|
colorFill(ptr_tl - x - py, ptr_tr + x - py, color);
|
||||||
Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color);
|
colorFill(ptr_tl - y - px, ptr_tr + y - px, color);
|
||||||
|
|
||||||
Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
|
colorFill(ptr_bl - x + py, ptr_br + x + py, color);
|
||||||
Common::set_to(ptr_bl - y + px, ptr_br + y + px, color);
|
colorFill(ptr_bl - y + px, ptr_br + y + px, color);
|
||||||
|
|
||||||
// FIXME: maybe not needed at all?
|
// FIXME: maybe not needed at all?
|
||||||
__BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
|
__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--) {
|
while (short_h--) {
|
||||||
if (fill_m == kGradientFill)
|
if (fill_m == kGradientFill)
|
||||||
color = calcGradient(real_radius++, long_h);
|
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;
|
ptr_fill += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,15 +546,15 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, FillMode fill_m) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Common::set_to(ptr - r, ptr + r, color);
|
colorFill(ptr - r, ptr + r, color);
|
||||||
__BE_RESET();
|
__BE_RESET();
|
||||||
|
|
||||||
while (x++ < y) {
|
while (x++ < y) {
|
||||||
__BE_ALGORITHM();
|
__BE_ALGORITHM();
|
||||||
Common::set_to(ptr - x + py, ptr + x + py, color);
|
colorFill(ptr - x + py, ptr + x + py, color);
|
||||||
Common::set_to(ptr - x - py, ptr + x - py, color);
|
colorFill(ptr - x - py, ptr + x - py, color);
|
||||||
Common::set_to(ptr - y + px, ptr + y + px, color);
|
colorFill(ptr - y + px, ptr + y + px, color);
|
||||||
Common::set_to(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) {
|
if (fill_m == VectorRenderer::kNoFill) {
|
||||||
while (sw++ < Base::_strokeWidth) {
|
while (sw++ < Base::_strokeWidth) {
|
||||||
Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
|
colorFill(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 + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
|
||||||
sp += p;
|
sp += p;
|
||||||
|
|
||||||
x = r - (sw - 1); y = 0; T = 0;
|
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;
|
ptr_fill += p * r;
|
||||||
while (short_h-- >= 0) {
|
while (short_h-- >= 0) {
|
||||||
Common::set_to(ptr_fill, ptr_fill + Base::_strokeWidth, color);
|
colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color);
|
||||||
Common::set_to(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
|
colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
|
||||||
ptr_fill += p;
|
ptr_fill += p;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -763,18 +763,18 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
|
||||||
while (x > y++) {
|
while (x > y++) {
|
||||||
__WU_ALGORITHM();
|
__WU_ALGORITHM();
|
||||||
|
|
||||||
Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color);
|
colorFill(ptr_tl - x - py, ptr_tr + x - py, color);
|
||||||
Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color);
|
colorFill(ptr_tl - y - px, ptr_tr + y - px, color);
|
||||||
|
|
||||||
Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
|
colorFill(ptr_bl - x + py, ptr_br + x + py, color);
|
||||||
Common::set_to(ptr_bl - y + px, ptr_br + y + px, 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);
|
__WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_fill += p * r;
|
ptr_fill += p * r;
|
||||||
while (short_h-- >= 0) {
|
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;
|
ptr_fill += p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,17 +814,17 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Common::set_to(ptr - r, ptr + r + 1, color);
|
colorFill(ptr - r, ptr + r + 1, color);
|
||||||
x = r; y = 0; T = 0;
|
x = r; y = 0; T = 0;
|
||||||
px = p * x; py = 0;
|
px = p * x; py = 0;
|
||||||
|
|
||||||
while (x > y++) {
|
while (x > y++) {
|
||||||
__WU_ALGORITHM();
|
__WU_ALGORITHM();
|
||||||
|
|
||||||
Common::set_to(ptr - x + py, ptr + x + py, color);
|
colorFill(ptr - x + py, ptr + x + py, color);
|
||||||
Common::set_to(ptr - x - py, ptr + x - py, color);
|
colorFill(ptr - x - py, ptr + x - py, color);
|
||||||
Common::set_to(ptr - y + px, ptr + y + px, color);
|
colorFill(ptr - y + px, ptr + y + px, color);
|
||||||
Common::set_to(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);
|
__WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,13 +339,13 @@ public:
|
||||||
int pitch = surfacePitch();
|
int pitch = surfacePitch();
|
||||||
|
|
||||||
if (mode == kBackgroundFill)
|
if (mode == kBackgroundFill)
|
||||||
Common::set_to(ptr, ptr + w * h, _bgColor);
|
colorFill(ptr, ptr + w * h, _bgColor);
|
||||||
else if (mode == kForegroundFill)
|
else if (mode == kForegroundFill)
|
||||||
Common::set_to(ptr, ptr + w * h, _fgColor);
|
colorFill(ptr, ptr + w * h, _fgColor);
|
||||||
else if (mode == kGradientFill) {
|
else if (mode == kGradientFill) {
|
||||||
int i = h;
|
int i = h;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
Common::set_to(ptr, ptr + w, calcGradient(h - i, h));
|
colorFill(ptr, ptr + w, calcGradient(h - i, h));
|
||||||
ptr += pitch;
|
ptr += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ protected:
|
||||||
* @param max Maximum amount of the progress.
|
* @param max Maximum amount of the progress.
|
||||||
* @return Composite color of the gradient at the given "progress" amount.
|
* @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;
|
PixelType output = 0;
|
||||||
pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
|
pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
|
||||||
|
|
||||||
|
@ -475,11 +475,46 @@ protected:
|
||||||
* @param color Color of the pixel
|
* @param color Color of the pixel
|
||||||
* @param alpha Alpha intensity of the pixel (0-255)
|
* @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)
|
while (first != last)
|
||||||
blendPixelPtr(first++, color, alpha);
|
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 _fgColor; /** Foreground color currently being used to draw on the renderer */
|
||||||
PixelType _bgColor; /** Background color currently being used to draw on the renderer */
|
PixelType _bgColor; /** Background color currently being used to draw on the renderer */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue