app_server: Drop gfxcpy and implement some TODOs about checking for graphics memory.
We still do not know if the accelerant buffers are graphics memory or not, but in my testing (on the VESA driver), the only time I could get _CopyRect to be called was where the buffer was in fact not graphics memory. So that should provide a performance improvement there. On the other end of things, this should resolve unaligned video memory access problems on RISCV, and potentially other platforms, as gfxcpy32 did not attempt to align pointers; it should also improve performance as memcpy will usually be faster than our custom gfxcpy here. Most of this code has not been touched since 2006 or so. Change-Id: I40b0345c5d47f2b45acafb14f03fd3a24d2042a8 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4315 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Reviewed-by: Alex von Gluck IV <kallisti5@unixzen.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
b419a79f8f
commit
778706215d
@ -13,6 +13,8 @@ class RenderingBuffer {
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
|
||||
virtual bool IsGraphicsMemory() const = 0;
|
||||
|
||||
virtual color_space ColorSpace() const = 0;
|
||||
virtual void* Bits() const = 0;
|
||||
virtual uint32 BytesPerRow() const = 0;
|
||||
|
@ -15,6 +15,7 @@ class BBitmapBuffer : public RenderingBuffer {
|
||||
virtual ~BBitmapBuffer();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
virtual bool IsGraphicsMemory() const { return false; }
|
||||
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual void* Bits() const;
|
||||
|
@ -13,6 +13,7 @@ class BitmapBuffer : public RenderingBuffer {
|
||||
virtual ~BitmapBuffer();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
virtual bool IsGraphicsMemory() const { return false; }
|
||||
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual void* Bits() const;
|
||||
|
@ -1563,7 +1563,8 @@ DrawingEngine::CopyRect(BRect src, int32 xOffset, int32 yOffset) const
|
||||
uint32 width = src.IntegerWidth() + 1;
|
||||
uint32 height = src.IntegerHeight() + 1;
|
||||
|
||||
_CopyRect(bits, width, height, bytesPerRow, xOffset, yOffset);
|
||||
_CopyRect(buffer->IsGraphicsMemory(), bits, width, height, bytesPerRow,
|
||||
xOffset, yOffset);
|
||||
|
||||
// offset dest again, because it is return value
|
||||
dst.OffsetBy(xOffset, yOffset);
|
||||
@ -1581,21 +1582,12 @@ DrawingEngine::SetRendererOffset(int32 offsetX, int32 offsetY)
|
||||
|
||||
|
||||
void
|
||||
DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height,
|
||||
DrawingEngine::_CopyRect(bool isGraphicsMemory, uint8* src, uint32 width, uint32 height,
|
||||
uint32 bytesPerRow, int32 xOffset, int32 yOffset) const
|
||||
{
|
||||
// TODO: assumes drawing buffer is 32 bits (which it currently always is)
|
||||
int32 xIncrement;
|
||||
int32 yIncrement;
|
||||
|
||||
if (yOffset == 0 && xOffset > 0) {
|
||||
// copy from right to left
|
||||
xIncrement = -1;
|
||||
src += (width - 1) * 4;
|
||||
} else {
|
||||
// copy from left to right
|
||||
xIncrement = 1;
|
||||
}
|
||||
const bool needMemmove = (yOffset == 0 && xOffset > 0 && uint32(xOffset) <= width);
|
||||
|
||||
if (yOffset > 0) {
|
||||
// copy from bottom to top
|
||||
@ -1608,34 +1600,32 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height,
|
||||
|
||||
uint8* dst = src + (ssize_t)yOffset * bytesPerRow + (ssize_t)xOffset * 4;
|
||||
|
||||
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;
|
||||
if (!needMemmove) {
|
||||
if (!isGraphicsMemory) {
|
||||
// NOTE: this (instead of the two pass copy below) might
|
||||
// speed up QEMU -> ?!? (would depend on how it emulates
|
||||
// the PCI bus...)
|
||||
for (uint32 y = 0; y < height; y++) {
|
||||
memcpy(dst, src, width * 4);
|
||||
src += yIncrement;
|
||||
dst += yIncrement;
|
||||
}
|
||||
} else {
|
||||
uint8 tmpBuffer[width * 4];
|
||||
for (uint32 y = 0; y < height; y++) {
|
||||
// NOTE: read into temporary scanline buffer,
|
||||
// NOTE: **don't read and write over the PCI bus
|
||||
// at the same time**
|
||||
memcpy(tmpBuffer, src, width * 4);
|
||||
// write back temporary scanline buffer
|
||||
memcpy(dst, tmpBuffer, 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;
|
||||
}
|
||||
memmove(dst, src, width * 4);
|
||||
src += yIncrement;
|
||||
dst += yIncrement;
|
||||
}
|
||||
|
@ -203,8 +203,8 @@ public:
|
||||
private:
|
||||
friend class DrawTransaction;
|
||||
|
||||
void _CopyRect(uint8* bits, uint32 width,
|
||||
uint32 height, uint32 bytesPerRow,
|
||||
void _CopyRect(bool isGraphicsMemory, uint8* bits,
|
||||
uint32 width, uint32 height, uint32 bytesPerRow,
|
||||
int32 xOffset, int32 yOffset) const;
|
||||
|
||||
ObjectDeleter<Painter>
|
||||
|
@ -676,7 +676,7 @@ HWInterface::_CopyToFront(uint8* src, uint32 srcBPR, int32 x, int32 y,
|
||||
// copy
|
||||
for (; y <= bottom; y++) {
|
||||
// bytes is guaranteed to be multiple of 4
|
||||
gfxcpy32(dst, src, bytes);
|
||||
memcpy(dst, src, bytes);
|
||||
dst += dstBPR;
|
||||
src += srcBPR;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ class MallocBuffer : public RenderingBuffer {
|
||||
virtual ~MallocBuffer();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
virtual bool IsGraphicsMemory() const { return false; }
|
||||
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual void* Bits() const;
|
||||
|
@ -10,87 +10,11 @@
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <string.h>
|
||||
|
||||
class BRect;
|
||||
|
||||
|
||||
// gfxcpy
|
||||
static inline void
|
||||
gfxcpy(uint8* dst, const uint8* src, int32 numBytes)
|
||||
{
|
||||
uint64* d64 = (uint64*)dst;
|
||||
uint64* s64 = (uint64*)src;
|
||||
int32 numBytesBegin = numBytes;
|
||||
while (numBytes >= 32) {
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
numBytes -= 32;
|
||||
}
|
||||
while (numBytes >= 16) {
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
numBytes -= 16;
|
||||
}
|
||||
while (numBytes >= 8) {
|
||||
*d64++ = *s64++;
|
||||
numBytes -= 8;
|
||||
}
|
||||
if (numBytes > 0) {
|
||||
// update original pointers
|
||||
dst += numBytesBegin - numBytes;
|
||||
src += numBytesBegin - numBytes;
|
||||
numBytesBegin = numBytes;
|
||||
|
||||
uint32* d32 = (uint32*)dst;
|
||||
uint32* s32 = (uint32*)src;
|
||||
while (numBytes >= 4) {
|
||||
*d32++ = *s32++;
|
||||
numBytes -= 4;
|
||||
}
|
||||
// update original pointers
|
||||
dst += numBytesBegin - numBytes;
|
||||
src += numBytesBegin - numBytes;
|
||||
|
||||
while (numBytes > 0) {
|
||||
*dst++ = *src++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gfxcpy32
|
||||
// * numBytes is expected to be a multiple of 4
|
||||
static inline void
|
||||
gfxcpy32(uint8* dst, const uint8* src, int32 numBytes)
|
||||
{
|
||||
uint64* d64 = (uint64*)dst;
|
||||
uint64* s64 = (uint64*)src;
|
||||
int32 numBytesStart = numBytes;
|
||||
while (numBytes >= 32) {
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
numBytes -= 32;
|
||||
}
|
||||
if (numBytes >= 16) {
|
||||
*d64++ = *s64++;
|
||||
*d64++ = *s64++;
|
||||
numBytes -= 16;
|
||||
}
|
||||
if (numBytes >= 8) {
|
||||
*d64++ = *s64++;
|
||||
numBytes -= 8;
|
||||
}
|
||||
if (numBytes == 4) {
|
||||
uint32* d32 = (uint32*)(dst + numBytesStart - numBytes);
|
||||
uint32* s32 = (uint32*)(src + numBytesStart - numBytes);
|
||||
*d32 = *s32;
|
||||
}
|
||||
}
|
||||
|
||||
// gfxset32
|
||||
// * numBytes is expected to be a multiple of 4
|
||||
static inline void
|
||||
@ -139,7 +63,7 @@ blend_line32(uint8* buffer, int32 pixels, uint8 r, uint8 g, uint8 b, uint8 a)
|
||||
s += 4;
|
||||
}
|
||||
|
||||
gfxcpy32(buffer, tempBuffer, pixels * 4);
|
||||
memcpy(buffer, tempBuffer, pixels * 4);
|
||||
}
|
||||
|
||||
void align_rect_to_pixels(BRect* rect);
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
virtual ~AccelerantBuffer();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
virtual bool IsGraphicsMemory() const { return true; /* TODO! */ }
|
||||
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual void* Bits() const;
|
||||
|
Loading…
Reference in New Issue
Block a user