From 7ca4a2646dd735003670dd65362690beada6e504 Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Sun, 12 Jul 2015 13:59:44 -0700 Subject: [PATCH] Optimize video drawing and API cleanup - Enforces synchronized access to video dirty bit --- Android/jni/jnihooks.c | 4 --- src/common.h | 16 ++++++------ src/display.c | 36 ++++++++++++++++---------- src/timing.c | 4 +-- src/video/glvideo.c | 12 ++++----- src/video/video.h | 57 +++++++++++++++++++----------------------- src/video/xvideo.c | 2 +- 7 files changed, 66 insertions(+), 65 deletions(-) diff --git a/Android/jni/jnihooks.c b/Android/jni/jnihooks.c index 72055d42..d4249b8e 100644 --- a/Android/jni/jnihooks.c +++ b/Android/jni/jnihooks.c @@ -211,10 +211,6 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeRender(JNIEnv *env, jobject } #endif - extern volatile bool _vid_dirty; - if (!nativePaused) { - _vid_dirty = true;// HACK HACK HACK FIXME TODO : efficiency and battery life gains if we can fix this ... - } video_backend->render(); } diff --git a/src/common.h b/src/common.h index 2902913d..0e5f6227 100644 --- a/src/common.h +++ b/src/common.h @@ -16,6 +16,14 @@ # define _GNU_SOURCE #endif +// custom annotations +#define INPARM +#define OUTPARM +#define INOUT +#define PRIVATE +#define PUBLIC +#define READONLY + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -59,14 +67,6 @@ #import #endif -// custom annotations -#define INPARM -#define OUTPARM -#define INOUT -#define PRIVATE -#define PUBLIC -#define READONLY - #define CTOR_PRIORITY_FIRST 101 #define CTOR_PRIORITY_EARLY 111 #define CTOR_PRIORITY_LATE 201 diff --git a/src/display.c b/src/display.c index 929aa283..0069d7c8 100644 --- a/src/display.c +++ b/src/display.c @@ -43,8 +43,6 @@ uint8_t video__hires_odd[0x800] = { 0 }; int video__current_page = 0; // current visual page -extern volatile bool _vid_dirty; - // Video constants -- sourced from AppleWin static const bool bVideoScannerNTSC = true; static const int kHBurstClock = 53; // clock when Color Burst starts @@ -95,6 +93,22 @@ uint8_t video__dhires2[256] = { 0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0xf,0xf,0xb,0xb,0xf,0xf,0xf,0xf, }; + +// forward decls of VM entry points + +void video__write_2e_text0(void); +void video__write_2e_text0_mixed(void); +void video__write_2e_text1(void); +void video__write_2e_text1_mixed(void); +void video__write_2e_odd0(void); +void video__write_2e_even0(void); +void video__write_2e_odd0_mixed(void); +void video__write_2e_even0_mixed(void); +void video__write_2e_odd1(void); +void video__write_2e_even1(void); +void video__write_2e_odd1_mixed(void); +void video__write_2e_even1_mixed(void); + // ---------------------------------------------------------------------------- // Initialization routines @@ -579,7 +593,7 @@ static inline void _plot_lores(uint8_t **d, const uint32_t val) { } static inline void _plot_character(const unsigned int font_off, uint8_t *fb_ptr) { - _vid_dirty = true; + video_setDirty(); uint8_t *font_ptr = video__wider_font+font_off; _plot_char40(/*dst*/&fb_ptr, /*src*/&font_ptr); _plot_char40(/*dst*/&fb_ptr, /*src*/&font_ptr); @@ -602,7 +616,7 @@ static inline void _plot_character1(uint16_t ea, uint8_t b) } static inline void _plot_80character(const unsigned int font_off, uint8_t *fb_ptr) { - _vid_dirty = true; + video_setDirty(); uint8_t *font_ptr = video__font+font_off; _plot_char80(/*dst*/&fb_ptr, /*src*/&font_ptr, SCANWIDTH); _plot_char80(/*dst*/&fb_ptr, /*src*/&font_ptr, SCANWIDTH); @@ -632,7 +646,7 @@ static inline void _plot_80character1(uint16_t ea, uint8_t b) } static inline void _plot_block(const uint32_t val, uint8_t *fb_ptr) { - _vid_dirty = true; + video_setDirty(); uint8_t color = (val & 0x0F) << 4; uint32_t val32 = (color << 24) | (color << 16) | (color << 8) | color; @@ -735,7 +749,7 @@ GLUE_C_WRITE(video__write_2e_text1_mixed) // Classic interface and printing HUD messages void interface_plotChar(uint8_t *fboff, int fb_pix_width, interface_colorscheme_t cs, uint8_t c) { - _vid_dirty = true; + video_setDirty(); uint8_t *src = video__int_font[cs] + c * (FONT_GLYPH_X*FONT_GLYPH_Y); _plot_char80(&fboff, &src, fb_pix_width); _plot_char80(&fboff, &src, fb_pix_width); @@ -761,7 +775,7 @@ static inline void _plot_dhires_pixels(uint8_t idx, uint8_t *fb_ptr) { // PlotDHires static inline void _plot_dhires(uint16_t base, uint16_t ea, uint8_t *fb_base) { - _vid_dirty = true; + video_setDirty(); ea &= ~0x1; uint16_t memoff = ea - base; @@ -983,7 +997,7 @@ static inline void _draw_hires_graphics(uint16_t ea, uint8_t b, bool is_even, ui return; } - _vid_dirty = true; + video_setDirty(); uint16_t off = ea - 0x2000; uint8_t *fb_base = NULL; if (page) { @@ -1079,7 +1093,7 @@ void video_main_loop(void) { } void video_setpage(int p) { - _vid_dirty = true; + video_setDirty(); video__current_page = p; } @@ -1087,10 +1101,6 @@ const uint8_t * const video_current_framebuffer() { return !video__current_page ? video__fb1 : video__fb2; } -bool video_dirty(void) { - return _vid_dirty; -} - void video_redraw(void) { // temporarily reset softswitches diff --git a/src/timing.c b/src/timing.c index a45d9908..09553ade 100644 --- a/src/timing.c +++ b/src/timing.c @@ -328,7 +328,7 @@ void *cpu_thread(void *dummyptr) { #ifdef AUDIO_ENABLED !speaker_isActive() && #endif - !video_dirty() && (!disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS)) ) + !video_isDirty() && (!disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS)) ) { TIMING_LOG("auto switching to full speed"); _timing_initialize(CPU_SCALE_FASTEST); @@ -389,7 +389,7 @@ void *cpu_thread(void *dummyptr) { #ifdef AUDIO_ENABLED speaker_isActive() || #endif - video_dirty() || (disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS))) ) + video_isDirty() || (disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS))) ) { double speed = alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor; if (speed < CPU_SCALE_FASTEST) { diff --git a/src/video/glvideo.c b/src/video/glvideo.c index 6f090024..d44007f9 100644 --- a/src/video/glvideo.c +++ b/src/video/glvideo.c @@ -19,7 +19,7 @@ bool safe_to_do_opengl_logging = false; bool renderer_shutting_down = false; -volatile bool _vid_dirty = true; +volatile unsigned long _backend_vid_dirty = 0; static int windowWidth = SCANWIDTH*1.5; static int windowHeight = SCANHEIGHT*1.5; @@ -713,8 +713,10 @@ static void gldriver_render(void) { // that we calculated above glUniformMatrix4fv(uniformMVPIdx, 1, GL_FALSE, mvp); - char pixels[SCANWIDTH * SCANHEIGHT * sizeof(PIXEL_TYPE)]; - if (_vid_dirty) { + unsigned long wasDirty = video_clearDirty(); + + char pixels[SCANWIDTH * SCANHEIGHT * sizeof(PIXEL_TYPE)]; // HACK FIXME TODO ... are we sure this does not overflow max stack buffer size? + if (wasDirty) { // Update texture from indexed-color Apple //e internal framebuffer unsigned int count = SCANWIDTH * SCANHEIGHT; for (unsigned int i=0, j=0; i