diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 247c8d987b..75110af139 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -6,6 +6,8 @@ * Stephan Aßmus */ +#include "DrawingEngine.h" + #include #include #include @@ -16,8 +18,7 @@ #include "PNGDump.h" #include "RenderingBuffer.h" -#include "DrawingEngine.h" - +#include "frame_buffer_support.h" // make_rect_valid static inline void @@ -1182,7 +1183,7 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height, int32 xIncrement; int32 yIncrement; - if (xOffset > 0) { + if (yOffset == 0 && xOffset > 0) { // copy from right to left xIncrement = -1; src += (width - 1) * 4; @@ -1202,16 +1203,37 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height, uint8* dst = src + yOffset * bytesPerRow + xOffset * 4; - for (uint32 y = 0; y < height; y++) { - uint32* srcHandle = (uint32*)src; - uint32* dstHandle = (uint32*)dst; - for (uint32 x = 0; x < width; x++) { - *dstHandle = *srcHandle; - srcHandle += xIncrement; - dstHandle += xIncrement; + if (xIncrement == 1) { + uint8 tmpBuffer[width * 4]; + for (uint32 y = 0; y < height; y++) { + // NOTE: read into temporary scanline buffer, + // avoid memcpy because it might be graphics card memory + gfxcpy32(tmpBuffer, src, width * 4); + // write back temporary scanline buffer + // NOTE: **don't read and write over the PCI bus + // at the same time** + memcpy(dst, tmpBuffer, width * 4); +// NOTE: this (instead of the two pass copy above) might +// speed up QEMU -> ?!? (would depend on how it emulates +// the PCI bus...) +// TODO: would be nice if we actually knew +// if we're operating in graphics memory or main memory... +//memcpy(dst, src, width * 4); + src += yIncrement; + dst += yIncrement; + } + } else { + for (uint32 y = 0; y < height; y++) { + uint32* srcHandle = (uint32*)src; + uint32* dstHandle = (uint32*)dst; + for (uint32 x = 0; x < width; x++) { + *dstHandle = *srcHandle; + srcHandle += xIncrement; + dstHandle += xIncrement; + } + src += yIncrement; + dst += yIncrement; } - src += yIncrement; - dst += yIncrement; } } diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 9e52408393..7ff78fc256 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -705,10 +705,11 @@ Painter::FillRect(const BRect& r, const rgb_color& c) const int32 y2 = min_c(fBaseRenderer->ymax(), bottom); uint8* offset = dst + x1 * 4; for (; y1 <= y2; y1++) { - uint32* handle = (uint32*)(offset + y1 * bpr); - for (int32 x = x1; x <= x2; x++) { - *handle++ = color.data32; - } +// uint32* handle = (uint32*)(offset + y1 * bpr); +// for (int32 x = x1; x <= x2; x++) { +// *handle++ = color.data32; +// } +gfxset32(offset + y1 * bpr, color.data32, (x2 - x1 + 1) * 4); } } } while (fBaseRenderer->next_clip_box()); @@ -738,10 +739,11 @@ Painter::FillRectNoClipping(const BRect& r, const rgb_color& c) const dst += left * 4; for (; y <= bottom; y++) { - uint32* handle = (uint32*)dst; - for (int32 x = left; x <= right; x++) { - *handle++ = color.data32; - } +// uint32* handle = (uint32*)dst; +// for (int32 x = left; x <= right; x++) { +// *handle++ = color.data32; +// } +gfxset32(dst, color.data32, (right - left + 1) * 4); dst += bpr; } } diff --git a/src/servers/app/drawing/frame_buffer_support.h b/src/servers/app/drawing/frame_buffer_support.h index c74dff149c..37bae1a8a3 100644 --- a/src/servers/app/drawing/frame_buffer_support.h +++ b/src/servers/app/drawing/frame_buffer_support.h @@ -87,6 +87,22 @@ gfxcpy32(uint8* dst, const uint8* src, int32 numBytes) } } +// gfxset32 +// * numBytes is expected to be a multiple of 4 +static inline void +gfxset32(uint8* dst, uint32 color, int32 numBytes) +{ + uint64 s64 = ((uint64)color << 32) | color; + while (numBytes >= 8) { + *(uint64*)dst = s64; + numBytes -= 8; + dst += 8; + } + if (numBytes == 4) { + *(uint32*)dst = color; + } +} + union pixel32 { uint32 data32; uint8 data8[4];