mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-26 00:29:27 +00:00
Optimize video drawing and API cleanup
- Enforces synchronized access to video dirty bit
This commit is contained in:
parent
da301ded7c
commit
7ca4a2646d
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
16
src/common.h
16
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 <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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user