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:
Augustin Cavalier 2021-10-21 12:09:28 -04:00 committed by Alex von Gluck IV
parent b419a79f8f
commit 778706215d
9 changed files with 38 additions and 118 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;