improve dirty block performance

This commit is contained in:
IntelOrca 2016-02-20 00:23:42 +00:00
parent 1b6299b9d2
commit 4617a52e53
2 changed files with 42 additions and 23 deletions

View File

@ -237,9 +237,13 @@ void gfx_set_dirty_blocks(sint16 left, sint16 top, sint16 right, sint16 bottom)
top >>= RCT2_GLOBAL(0x009ABDF1, sint8);
bottom >>= RCT2_GLOBAL(0x009ABDF1, sint8);
for (y = top; y <= bottom; y++)
for (x = left; x <= right; x++)
screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) + x] = 0xFF;
uint32 dirtyBlockColumns = RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32);
for (y = top; y <= bottom; y++) {
uint32 yOffset = y * dirtyBlockColumns;
for (x = left; x <= right; x++) {
screenDirtyBlocks[yOffset + x] = 0xFF;
}
}
}
/**
@ -248,25 +252,35 @@ void gfx_set_dirty_blocks(sint16 left, sint16 top, sint16 right, sint16 bottom)
*/
void gfx_draw_all_dirty_blocks()
{
unsigned int x, y, xx, yy, columns, rows;
uint32 x, y, xx, yy, columns, rows;
uint32 dirtyBlockColumns = RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32);
uint32 dirtyBlockRows = RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, uint32);
uint8 *screenDirtyBlocks = gfx_get_dirty_blocks();
for (x = 0; x < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32); x++) {
for (y = 0; y < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, uint32); y++) {
if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) + x] == 0)
for (x = 0; x < dirtyBlockColumns; x++) {
for (y = 0; y < dirtyBlockRows; y++) {
uint32 yOffset = y * dirtyBlockColumns;
if (screenDirtyBlocks[yOffset + x] == 0) {
continue;
}
// Determine columns
for (xx = x; xx < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32); xx++)
if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) + xx] == 0)
for (xx = x; xx < dirtyBlockColumns; xx++) {
if (screenDirtyBlocks[yOffset + xx] == 0) {
break;
}
}
columns = xx - x;
// Check rows
for (yy = y; yy < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, uint32); yy++)
for (xx = x; xx < x + columns; xx++)
if (screenDirtyBlocks[yy * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) + xx] == 0)
for (yy = y; yy < dirtyBlockRows; yy++) {
uint32 yyOffset = yy * dirtyBlockColumns;
for (xx = x; xx < x + columns; xx++) {
if (screenDirtyBlocks[yyOffset + xx] == 0) {
goto endRowCheck;
}
}
}
endRowCheck:
rows = yy - y;
@ -277,21 +291,26 @@ void gfx_draw_all_dirty_blocks()
static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows)
{
int left, top, right, bottom;
uint32 left, top, right, bottom;
uint32 dirtyBlockColumns = RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32);
uint8 *screenDirtyBlocks = gfx_get_dirty_blocks();
// Unset dirty blocks
for (top = y; top < y + rows; top++)
for (left = x; left < x + columns; left++)
screenDirtyBlocks[top * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) + left] = 0;
for (top = y; top < y + (uint32)rows; top++) {
uint32 topOffset = top * dirtyBlockColumns;
for (left = x; left < x + (uint32)columns; left++) {
screenDirtyBlocks[topOffset + left] = 0;
}
}
// Determine region in pixels
left = max(0, x * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, uint16));
top = max(0, y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, uint16));
right = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16), left + (columns * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, uint16)));
bottom = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16), top + (rows * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, uint16)));
if (right <= left || bottom <= top)
if (right <= left || bottom <= top) {
return;
}
// Draw region
gfx_redraw_screen_rect(left, top, right, bottom);

View File

@ -1067,13 +1067,13 @@ static void platform_refresh_screenbuffer(int width, int height, int pitch)
screenDPI->height = height;
screenDPI->pitch = _screenBufferPitch - width;
RCT2_GLOBAL(0x009ABDF0, uint8) = 6;
RCT2_GLOBAL(0x009ABDF1, uint8) = 3;
RCT2_GLOBAL(0x009ABDF0, uint8) = 7;
RCT2_GLOBAL(0x009ABDF1, uint8) = 6;
RCT2_GLOBAL(0x009ABDF2, uint8) = 1;
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, uint16) = 64;
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, uint16) = 8;
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) = (width >> 6) + 1;
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, uint32) = (height >> 3) + 1;
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, uint16) = 1 << RCT2_GLOBAL(0x009ABDF0, uint8);
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, uint16) = 1 << RCT2_GLOBAL(0x009ABDF1, uint8);
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, uint32) = (width >> RCT2_GLOBAL(0x009ABDF0, uint8)) + 1;
RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, uint32) = (height >> RCT2_GLOBAL(0x009ABDF1, uint8)) + 1;
}
void platform_hide_cursor()