#include <QSemaphore>
#include <QScreen>
#include <QWaitCondition>
+#include <QElapsedTimer>
-#include <SDL.h>
#include "emu.h"
#include "osd.h"
#include "vm/vm.h"
using_flags = NULL;
if(p_osd != NULL) using_flags = p_osd->get_config_flags();
screen = QGuiApplication::primaryScreen();
-
+
+ is_shared_glcontext = false;
+ glContext = NULL;
draw_screen_buffer = NULL;
-
+ if(p_osd != NULL) {
+ p_osd->set_glview(glv);
+ //printf("OSD/Context sharing succeeded.ADDR=%08x GLES=%s\n", glContext, (glContext->isOpenGLES()) ? "YES" : "NO");
+ }
do_change_refresh_rate(screen->refreshRate());
connect(screen, SIGNAL(refreshRateChanged(qreal)), this, SLOT(do_change_refresh_rate(qreal)));
- connect(this, SIGNAL(sig_update_screen(bitmap_t *)), glv, SLOT(update_screen(bitmap_t *)), Qt::QueuedConnection);
+ connect(this, SIGNAL(sig_update_screen(void *, bool)), glv, SLOT(update_screen(void *, bool)), Qt::QueuedConnection);
connect(this, SIGNAL(sig_update_osd()), glv, SLOT(update_osd()), Qt::QueuedConnection);
connect(this, SIGNAL(sig_push_frames_to_avio(int, int, int)), glv->extfunc, SLOT(paintGL_OffScreen(int, int, int)));
- connect(this, SIGNAL(sig_map_texture()), glv, SLOT(do_map_vram_texture()));
- connect(this, SIGNAL(sig_unmap_texture()), glv, SLOT(do_unmap_vram_texture()));
- connect(glv, SIGNAL(sig_map_texture_reply(bool, void *, int, int)), this, SLOT(do_recv_texture_map_status(bool, void *, int, int)));
- connect(glv, SIGNAL(sig_unmap_texture_reply()), this, SLOT(do_recv_texture_unmap_status()));
//connect(this, SIGNAL(sig_call_draw_screen()), p_osd, SLOT(draw_screen()));
//connect(this, SIGNAL(sig_call_no_draw_screen()), p_osd, SLOT(no_draw_screen()));
void DrawThreadClass::do_draw_one_turn(bool _req_draw)
{
- if((mapped_drawn) && (_req_draw)) {
- emit sig_update_screen(NULL);
- } else if((_req_draw) && (draw_screen_buffer != NULL)) {
- emit sig_update_screen(draw_screen_buffer);
+ if((_req_draw) && (draw_screen_buffer != NULL)) {
+ emit sig_update_screen((void *)draw_screen_buffer, mapped_drawn);
} else {
if(ncount == 0) emit sig_update_osd();
}
bRunThread = true;
double _rate = 1000.0 / 30.0;
bDrawReq = false;
- if(renderSemaphore == NULL) goto __exit;
+ QElapsedTimer tick_timer;
+ tick_timer.start();
+ quint64 elapsed = (quint64)_rate;
+ double drate;
+ if(renderSemaphore == NULL) {
+ QSemaphore *s = new QSemaphore(0);
+ if(s == NULL) goto __exit;
+ renderSemaphore = s;
+ }
+
do {
- _rate = (wait_refresh < emu_frame_rate) ? emu_frame_rate : wait_refresh;
- if(_rate < 2.0) {
- wait_factor = 2.0;
+ //_rate = (wait_refresh < emu_frame_rate) ? emu_frame_rate : wait_refresh;
+ _rate = 1.0e3 / p_osd->vm_frame_rate(); // FPS to msec
+ drate = (double)elapsed / 1.0e6; // nsec to msec
+ if(_rate >= drate) {
+ wait_factor = (int)nearbyint(_rate - drate) + 3;
} else {
- wait_factor = (int)_rate - 1;
+ wait_factor = 3;
}
+ //printf("RATE:%f ELAPSED: %f WAIT_FACTOR:%d\n", _rate, drate, wait_factor);
if(renderSemaphore->tryAcquire(1, wait_factor)) { // Success
- if(!bRunThread) break;
+ if(!bRunThread) goto __exit;
volatile bool _b = bRecentRenderStatus;
bRecentRenderStatus = false;
doDrawMain(_b);
}
- if(!bRunThread) break;
+ if(!bRunThread) goto __exit;
volatile bool _d = bDrawReq;
if(draw_screen_buffer == NULL) _d = false;
if((_d) && (draw_screen_buffer != NULL)) bDrawReq = false;
do_draw_one_turn(_d);
+ elapsed = tick_timer.nsecsElapsed();
+ tick_timer.start();
} while(bRunThread);
__exit:
csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL,
wait_count += (wait_refresh * 1.0);
}
-void DrawThreadClass::do_update_screen(bitmap_t *p)
+void DrawThreadClass::do_update_screen(void *p, bool is_mapped)
{
- draw_screen_buffer = p;
+ draw_screen_buffer = (bitmap_t*)p;
bDrawReq = true;
+ mapped_drawn = is_mapped;
}
void DrawThreadClass::do_req_encueue_video(int count, int width, int height)
mapping_width = 0;
mapping_height = 0;
if(glv->is_ready_to_map_vram_texture()) {
- emit sig_map_texture();
textureMappingSemaphore->acquire();
//mapping_pointer = (scrntype_t *)(glv->do_map_vram_texture(&mapping_width, &mapping_height));
//if(mapping_pointer == NULL) {
}
}
-void DrawThreadClass::do_recv_texture_map_status(bool f, void *p, int width, int height)
-{
- mapping_status = f;
- mapping_pointer = (scrntype_t *)p;
- mapping_width = width;
- mapping_height = height;
- p_osd->do_set_screen_map_texture_address(mapping_pointer, mapping_width, mapping_height);
- //printf("%08x\n", mapping_pointer);
- if(mapping_status) {
- mapped_drawn = true;
- }
- textureMappingSemaphore->release(1);
-}
-
-void DrawThreadClass::do_recv_texture_unmap_status(void)
-{
- mapping_status = false;
- mapping_pointer = NULL;
- mapping_width = 0;
- mapping_height = 0;
- mapped_drawn = false;
- p_osd->do_set_screen_map_texture_address(mapping_pointer, mapping_width, mapping_height);
- textureMappingSemaphore->release(1);
-}