Rewritten renderer blitting, fixes flickering when inversion or grayscale is used.

This commit is contained in:
OBattler
2021-10-06 02:26:30 +02:00
parent 7fc111584d
commit 46807540ed
8 changed files with 76 additions and 61 deletions

View File

@@ -2056,28 +2056,29 @@ config_load(void)
cassette_ui_writeprot = 0;
config_log("Config file not present or invalid!\n");
return;
} else {
load_general(); /* General */
load_machine(); /* Machine */
load_video(); /* Video */
load_input_devices(); /* Input devices */
load_sound(); /* Sound */
load_network(); /* Network */
load_ports(); /* Ports (COM & LPT) */
load_storage_controllers(); /* Storage controllers */
load_hard_disks(); /* Hard disks */
load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
load_floppy_drives(); /* Floppy drives */
load_other_removable_devices(); /* Other removable devices */
load_other_peripherals(); /* Other peripherals */
/* Mark the configuration as changed. */
config_changed = 1;
config_log("Config loaded.\n\n");
}
load_general(); /* General */
load_machine(); /* Machine */
load_video(); /* Video */
load_input_devices(); /* Input devices */
load_sound(); /* Sound */
load_network(); /* Network */
load_ports(); /* Ports (COM & LPT) */
load_storage_controllers(); /* Storage controllers */
load_hard_disks(); /* Hard disks */
load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
load_floppy_drives(); /* Floppy drives */
load_other_removable_devices(); /* Other removable devices */
load_other_peripherals(); /* Other peripherals */
/* Mark the configuration as changed. */
config_changed = 1;
config_log("Config loaded.\n\n");
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
}

View File

@@ -133,6 +133,10 @@ extern int readflash;
/* Function handler pointers. */
extern void (*video_recalctimings)(void);
extern void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size);
extern void video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len);
extern void * __cdecl video_transform_copy(void *_Dst, const void *_Src, size_t _Size);
/* Table functions. */

View File

@@ -133,7 +133,10 @@ sdl_blit_shim(int x, int y, int w, int h)
params.y = y;
params.w = w;
params.h = h;
if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL))) memcpy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)))
video_copy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
if (screenshots)
video_screenshot(interpixels, 0, 0, (2048 + 64));
blitreq = 1;
video_blit_complete();
}

View File

@@ -114,6 +114,8 @@ static const video_timings_t *vid_timings;
static uint32_t cga_2_table[16];
static uint8_t thread_run = 0;
void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy;
PALETTE cgapal = {
{0,0,0}, {0,42,0}, {42,0,0}, {42,21,0},
@@ -317,7 +319,7 @@ static png_infop info_ptr;
static void
video_take_screenshot(const char *fn)
video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len)
{
int i, x, y;
png_bytep *b_rgb = NULL;
@@ -363,10 +365,10 @@ video_take_screenshot(const char *fn)
for (y = 0; y < blit_data.h; ++y) {
b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr));
for (x = 0; x < blit_data.w; ++x) {
if (buffer32 == NULL)
if (buf == NULL)
memset(&(b_rgb[y][x * 3]), 0x00, 3);
else {
temp = buffer32->line[blit_data.y + y][blit_data.x + x];
temp = buf[((start_y + y) * row_len) + start_x + x];
b_rgb[y][x * 3] = (temp >> 16) & 0xff;
b_rgb[y][(x * 3) + 1] = (temp >> 8) & 0xff;
b_rgb[y][(x * 3) + 2] = temp & 0xff;
@@ -390,8 +392,8 @@ video_take_screenshot(const char *fn)
}
static void
video_screenshot(void)
void
video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len)
{
char path[1024], fn[128];
@@ -410,50 +412,42 @@ video_screenshot(void)
video_log("taking screenshot to: %s\n", path);
video_take_screenshot((const char *) path);
video_take_screenshot((const char *) path, buf, start_x, start_y, row_len);
png_destroy_write_struct(&png_ptr, &info_ptr);
screenshots--;
}
static void
video_transform_copy(uint32_t *dst, uint32_t *src, int len)
void * __cdecl
video_transform_copy(void *_Dst, const void *_Src, size_t _Size)
{
int i;
uint32_t *dest_ex = (uint32_t *) _Dst;
uint32_t *src_ex = (uint32_t *) _Src;
if ((dst != NULL) && (src != NULL)) {
for (i = 0; i < len; i++) {
*dst = video_color_transform(*src);
dst++;
src++;
_Size /= sizeof(uint32_t);
if ((dest_ex != NULL) && (src_ex != NULL)) {
for (i = 0; i < _Size; i++) {
*dest_ex = video_color_transform(*src_ex);
dest_ex++;
src_ex++;
}
}
return _Dst;
}
static
void blit_thread(void *param)
{
int yy;
while (thread_run) {
thread_wait_event(blit_data.wake_blit_thread, -1);
thread_reset_event(blit_data.wake_blit_thread);
MTR_BEGIN("video", "blit_thread");
if ((video_grayscale || invert_display) && (blit_data.h > 0)) {
for (yy = 0; yy < blit_data.h; yy++) {
if (((blit_data.y + yy) >= 0) && ((blit_data.y + yy) < buffer32->h)) {
video_transform_copy(&(buffer32->line[blit_data.y + yy][blit_data.x]), &(buffer32->line[blit_data.y + yy][blit_data.x]), blit_data.w);
}
}
}
if (screenshots) {
video_screenshot();
screenshots--;
video_log("screenshot taken, %i left\n", screenshots);
}
if (blit_func)
blit_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h);

View File

@@ -179,8 +179,11 @@ vnc_blit(int x, int y, int w, int h)
p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*VNC_MAX_X]);
if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y)
memcpy(p, &(buffer32->line[yy]), w*sizeof(uint32_t));
video_copy(p, &(buffer32->line[yy]), w*sizeof(uint32_t));
}
if (screenshots)
video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, ROW_LENGTH);
video_blit_complete();

View File

@@ -816,7 +816,10 @@ static void opengl_blit(int x, int y, int w, int h)
return;
}
memcpy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t));
video_copy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t));
if (screenshots)
video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH);
video_blit_complete();

View File

@@ -232,7 +232,8 @@ static void
sdl_blit(int x, int y, int w, int h)
{
SDL_Rect r_src;
int ret;
void *pixeldata;
int pitch, ret;
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) {
video_blit_complete();
@@ -241,17 +242,21 @@ sdl_blit(int x, int y, int w, int h)
SDL_LockMutex(sdl_mutex);
r_src.x = x;
r_src.y = y;
r_src.w = w;
r_src.h = h;
SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), (2048 + 64) * sizeof(uint32_t));
SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch);
video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
if (screenshots)
video_screenshot((uint32_t *) pixeldata, 0, 0, (2048 + 64));
SDL_UnlockTexture(sdl_tex);
video_blit_complete();
SDL_RenderClear(sdl_render);
r_src.x = x;
r_src.y = y;
r_src.x = 0;
r_src.y = 0;
r_src.w = w;
r_src.h = h;
@@ -353,7 +358,7 @@ sdl_init_texture(void)
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
SDL_TEXTUREACCESS_STREAMING, (2048 + 64), (2048 + 64));
}

View File

@@ -822,6 +822,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case IDM_VID_INVERT:
video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT);
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
break;
case IDM_VID_OVERSCAN:
@@ -854,6 +855,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case IDM_VID_GRAY_WHITE:
CheckMenuItem(hmenu, IDM_VID_GRAY_RGB+video_grayscale, MF_UNCHECKED);
video_grayscale = LOWORD(wParam) - IDM_VID_GRAY_RGB;
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
CheckMenuItem(hmenu, IDM_VID_GRAY_RGB+video_grayscale, MF_CHECKED);
device_force_redraw();
config_save();