Optimize video drawing and API cleanup

- Enforces synchronized access to video dirty bit
This commit is contained in:
Aaron Culliney 2015-07-12 13:59:44 -07:00
parent da301ded7c
commit 7ca4a2646d
7 changed files with 66 additions and 65 deletions

View File

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

View File

@ -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 <CoreFoundation/CoreFoundation.h>
#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

View File

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

View File

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

View File

@ -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<count; i++, j+=sizeof(PIXEL_TYPE)) {
@ -731,7 +733,7 @@ static void gldriver_render(void) {
glActiveTexture(TEXTURE_ACTIVE_FRAMEBUFFER);
glBindTexture(GL_TEXTURE_2D, a2TextureName);
glUniform1i(uniformTex2Use, TEXTURE_ID_FRAMEBUFFER);
if (_vid_dirty) {
if (wasDirty) {
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, SCANWIDTH, SCANHEIGHT, /*border*/0, TEX_FORMAT, TEX_TYPE, (GLvoid *)&pixels[0]);
}
@ -780,8 +782,6 @@ static void gldriver_render(void) {
// Render HUD nodes
glnode_renderNodes();
_vid_dirty = false;
#if USE_GLUT
glutSwapBuffers();
#endif

View File

@ -130,10 +130,29 @@ void video_setpage(int page);
*/
const uint8_t * const video_current_framebuffer();
// do not access directly, but through inline accessor methods
extern volatile unsigned long _backend_vid_dirty;
/*
* True if anything changed in framebuffer and not yet drawn
*/
bool video_dirty(void);
static inline bool video_isDirty(void) {
return _backend_vid_dirty;
}
/*
* Atomically set dirty bit, return previous value
*/
static inline unsigned long video_setDirty(void) {
return __sync_fetch_and_or(&_backend_vid_dirty, 1UL);
}
/*
* Atomically clear dirty bit, return previous value
*/
static inline unsigned long video_clearDirty(void) {
return __sync_fetch_and_and(&_backend_vid_dirty, 0UL);
}
// ----------------------------------------------------------------------------
@ -247,37 +266,13 @@ uint8_t floating_bus_hibit(const bool hibit);
/*
* Pointers to framebuffer (can be VGA memory or host buffer)
*/
extern uint8_t *video__fb1,*video__fb2;
extern uint8_t *video__fb1;
extern uint8_t *video__fb2;
extern uint8_t video__hires_even[0x800];
extern uint8_t video__hires_odd[0x800];
extern uint8_t video__dhires1[256];
extern uint8_t video__dhires2[256];
extern int video__current_page; /* Current visual page */
/* --- Precalculated hi-res page offsets given addr --- */
extern unsigned int video__screen_addresses[8192];
extern uint8_t video__columns[8192];
extern uint8_t video__odd_colors[2];
extern uint8_t video__even_colors[2];
/* Hooks */
void video__write_2e_text0(),
video__write_2e_text0_mixed(),
video__write_2e_text1(),
video__write_2e_text1_mixed(),
video__write_2e_odd0(),
video__write_2e_even0(),
video__write_2e_odd0_mixed(),
video__write_2e_even0_mixed(),
video__write_2e_odd1(),
video__write_2e_even1(),
video__write_2e_odd1_mixed(),
video__write_2e_even1_mixed();
/*
* Current visual page
*/
extern READONLY int video__current_page;
#endif /* !A2_VIDEO_H */

View File

@ -64,7 +64,7 @@ static video_backend_s xvideo_backend = { 0 };
static bool request_set_mode = false;
static int request_mode = 0;
volatile bool _vid_dirty = true;
volatile unsigned long _backend_vid_dirty = 0;
typedef struct {
unsigned long flags;