From 0e6f7148ab0987574c45e78cb8fd6ff72fdf103a Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sat, 25 Feb 2023 14:59:20 +0100 Subject: optimize ppusim with threads --- src/demo.c | 6 +++--- src/ds.mk | 3 ++- src/ppusim/pixel.c | 19 ++++++------------- src/ppusim/pixel.h | 4 ++-- src/ppusim/sim.c | 8 ++------ src/ppusim/work.c | 38 ++++++++++++++++++++++++++++++++++++++ src/ppusim/work.h | 14 ++++++++++++++ 7 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 src/ppusim/work.c create mode 100644 src/ppusim/work.h (limited to 'src') diff --git a/src/demo.c b/src/demo.c index 6248989..019750a 100644 --- a/src/demo.c +++ b/src/demo.c @@ -12,7 +12,7 @@ void hh_demo_setup() { hh_ppu_update_sprite(1, HH_DBG_SPRITE_CHECKERBOARD); // background pattern - hh_ppu_update_color(0, 1, (hh_ppu_rgb_color_t) {0x8, 0x8, 0x8}); + hh_ppu_update_color(0, 1, (hh_ppu_rgb_color_t) {0x4, 0x4, 0x4}); for (unsigned i = 0; i < HH_PPU_BG_CANVAS_TILES_H * HH_PPU_BG_CANVAS_TILES_V; i++) { hh_ppu_update_background(i, (hh_s_ppu_loc_bam_entry) { .horizontal_flip = false, @@ -48,8 +48,8 @@ void hh_demo_loop(unsigned long frame) { }); for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) { - g_hh_demo_balls[i].position_x = HH_PPU_SCREEN_WIDTH/2 - HH_PPU_SPRITE_WIDTH/2 + (int)(60 * (double)sin((1*(double)frame + 6*(double)i) / 30)); - g_hh_demo_balls[i].position_y = HH_PPU_SCREEN_HEIGHT/2 - HH_PPU_SPRITE_HEIGHT/2 + (int)(30 * (double)sin((2*(double)frame + 6*(double)i) / 30)); + g_hh_demo_balls[i].position_x = HH_PPU_SCREEN_WIDTH/2 - HH_PPU_SPRITE_WIDTH/2 + (int)(60 * (double)sin((1*(double)frame / 10) + (double)i * 12)); + g_hh_demo_balls[i].position_y = HH_PPU_SCREEN_HEIGHT/2 - HH_PPU_SPRITE_HEIGHT/2 + (int)(30 * (double)sin((2*(double)frame / 10) + (double)i * 12)); hh_ppu_update_foreground(i, g_hh_demo_balls[i]); } } diff --git a/src/ds.mk b/src/ds.mk index 18107ad..f70c1c9 100644 --- a/src/ds.mk +++ b/src/ds.mk @@ -5,5 +5,6 @@ LFLAGS += -lSDL2 DESKTOP_SRCS += ppusim/sim.c \ ppusim/mem.c \ - ppusim/pixel.c + ppusim/pixel.c \ + ppusim/work.c diff --git a/src/ppusim/pixel.c b/src/ppusim/pixel.c index 2163c10..6e915e6 100644 --- a/src/ppusim/pixel.c +++ b/src/ppusim/pixel.c @@ -1,21 +1,11 @@ #include #include +#include "ppusim/work.h" #include "ppu/internals.h" #include "ppusim/mem.h" -#include "ppusim/sim.h" #include "ppu/consts.h" -static void hh_ppusim_draw(SDL_Renderer* r, unsigned px, unsigned py, unsigned cr, unsigned cg, unsigned cb) { - SDL_SetRenderDrawColor(r, cr, cg, cb, 255); - SDL_RenderFillRect(r, &(SDL_Rect) { - .x = px * HH_PPUSIM_UPSCALE_FACTOR, - .y = py * HH_PPUSIM_UPSCALE_FACTOR, - .w = HH_PPUSIM_UPSCALE_FACTOR, - .h = HH_PPUSIM_UPSCALE_FACTOR - }); -} - /* transform xy if tile is flipped */ static uint16_t hh_ppusim_apply_transform(unsigned x, unsigned y, bool fliph, bool flipv) { unsigned tx = fliph ? HH_PPU_SPRITE_WIDTH - x - 1 : x; @@ -77,7 +67,7 @@ static uint8_t hh_ppusim_fg_pixel(unsigned x, unsigned y) { return cidx; } -void hh_ppusim_pixel(SDL_Renderer* r, unsigned x, unsigned y) { +void hh_ppusim_pixel(uint8_t* s, unsigned x, unsigned y) { uint8_t bg_cidx = hh_ppusim_bg_pixel(x, y); uint8_t fg_cidx = hh_ppusim_fg_pixel(x, y); uint8_t cidx = (fg_cidx & HH_MASK(3)) == 0 ? bg_cidx : fg_cidx; @@ -87,6 +77,9 @@ void hh_ppusim_pixel(SDL_Renderer* r, unsigned x, unsigned y) { HH_RESIZE(pal_rgb, 7, 4), HH_RESIZE(pal_rgb, 3, 0) }; - hh_ppusim_draw(r, x, y, rgb[0] << 4, rgb[1] << 4, rgb[2] << 4); + + s[0] = rgb[0] << 4; + s[1] = rgb[1] << 4; + s[2] = rgb[2] << 4; } diff --git a/src/ppusim/pixel.h b/src/ppusim/pixel.h index 8044560..475fe11 100644 --- a/src/ppusim/pixel.h +++ b/src/ppusim/pixel.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "ppusim/work.h" -void hh_ppusim_pixel(SDL_Renderer*, unsigned x, unsigned y); +void hh_ppusim_pixel(uint8_t* s, unsigned x, unsigned y); diff --git a/src/ppusim/sim.c b/src/ppusim/sim.c index 8f01359..4226a9b 100644 --- a/src/ppusim/sim.c +++ b/src/ppusim/sim.c @@ -7,7 +7,7 @@ #include "ppu/ppu.h" #include "ppusim/mem.h" #include "ppusim/sim.h" -#include "ppusim/pixel.h" +#include "ppusim/work.h" SDL_Window *g_hh_window = NULL; SDL_Renderer *g_hh_renderer = NULL; @@ -38,11 +38,7 @@ void hh_loop() { hh_ppu_vblank_interrupt(); SDL_RenderClear(g_hh_renderer); - - for (unsigned x = 0; x < HH_PPU_SCREEN_WIDTH; x++) - for (unsigned y = 0; y < HH_PPU_SCREEN_HEIGHT; y++) - hh_ppusim_pixel(g_hh_renderer, x, y); - + hh_ppusim_draw_frame(g_hh_renderer); SDL_SetRenderDrawColor(g_hh_renderer, 0, 0, 0, 255); SDL_RenderPresent(g_hh_renderer); diff --git a/src/ppusim/work.c b/src/ppusim/work.c new file mode 100644 index 0000000..2073907 --- /dev/null +++ b/src/ppusim/work.c @@ -0,0 +1,38 @@ +#include +#include +#include + +#include "ppusim/work.h" +#include "ppusim/sim.h" +#include "ppu/consts.h" +#include "ppusim/pixel.h" + +pthread_t g_hh_ppusim_scanline_threads[HH_PPU_SCREEN_HEIGHT]; +hh_s_ppusim_screen g_hh_ppusim_screen; + +void* hh_ppusim_draw_scanline(void* scanline_context) { + unsigned scanline = (unsigned long) scanline_context; + for (unsigned x = 0; x < HH_PPU_SCREEN_WIDTH; x++) + hh_ppusim_pixel(g_hh_ppusim_screen[scanline][x], x, scanline); + return NULL; +} + +void hh_ppusim_draw_frame(SDL_Renderer* renderer) { + for (unsigned y = 0; y < HH_PPU_SCREEN_HEIGHT; y++) + pthread_create(&g_hh_ppusim_scanline_threads[y], NULL, hh_ppusim_draw_scanline, (void*)(unsigned long)y); + for (unsigned y = 0; y < HH_PPU_SCREEN_HEIGHT; y++) + pthread_join(g_hh_ppusim_scanline_threads[y], NULL); + + for (unsigned x = 0; x < HH_PPU_SCREEN_WIDTH; x++) { + for (unsigned y = 0; y < HH_PPU_SCREEN_HEIGHT; y++) { + SDL_SetRenderDrawColor(renderer, g_hh_ppusim_screen[y][x][0], g_hh_ppusim_screen[y][x][1], g_hh_ppusim_screen[y][x][2], 255); + SDL_RenderFillRect(renderer, &(SDL_Rect) { + .x = x * HH_PPUSIM_UPSCALE_FACTOR, + .y = y * HH_PPUSIM_UPSCALE_FACTOR, + .w = HH_PPUSIM_UPSCALE_FACTOR, + .h = HH_PPUSIM_UPSCALE_FACTOR, + }); + } + } +} + diff --git a/src/ppusim/work.h b/src/ppusim/work.h new file mode 100644 index 0000000..1171a22 --- /dev/null +++ b/src/ppusim/work.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +#include "ppu/consts.h" + +typedef uint8_t hh_s_ppusim_color[3]; +typedef hh_s_ppusim_color hh_s_ppusim_scanline[HH_PPU_SCREEN_WIDTH]; +typedef hh_s_ppusim_scanline hh_s_ppusim_screen[HH_PPU_SCREEN_HEIGHT]; + +void* hh_ppusim_draw_scanline(void*); + +void hh_ppusim_draw_frame(SDL_Renderer*); + -- cgit v1.2.3