2 Skelton for retropc emulator
3 Author : Takeda.Toshiya
4 Port to Qt : K.Ohta <whatisthis.sowhat _at_ gmail.com>
7 History : 2015.11.10 Split from qt_main.cpp
8 [ win32 main ] -> [ Qt main ] -> [Drawing]
12 #include <QApplication>
14 #include <QGuiApplication>
17 #include <QWaitCondition>
25 #include "csp_logger.h"
26 #include "mainwidget_base.h"
27 #include "draw_thread.h"
28 #include "gl2/qt_glutil_gl2_0.h"
32 DrawThreadClass::DrawThreadClass(OSD *o, CSP_Logger *logger,QObject *parent) : QThread(parent) {
33 MainWindow = (Ui_MainWindowBase *)parent;
34 glv = MainWindow->getGraphicsView();
38 if(p_osd != NULL) using_flags = p_osd->get_config_flags();
39 screen = QGuiApplication::primaryScreen();
41 draw_screen_buffer = NULL;
43 do_change_refresh_rate(screen->refreshRate());
44 connect(screen, SIGNAL(refreshRateChanged(qreal)), this, SLOT(do_change_refresh_rate(qreal)));
45 connect(this, SIGNAL(sig_update_screen(bitmap_t *)), glv, SLOT(update_screen(bitmap_t *)), Qt::QueuedConnection);
47 connect(this, SIGNAL(sig_update_osd()), glv, SLOT(update_osd()), Qt::QueuedConnection);
48 connect(this, SIGNAL(sig_push_frames_to_avio(int, int, int)), glv->extfunc, SLOT(paintGL_OffScreen(int, int, int)));
49 //connect(this, SIGNAL(sig_call_draw_screen()), p_osd, SLOT(draw_screen()));
50 //connect(this, SIGNAL(sig_call_no_draw_screen()), p_osd, SLOT(no_draw_screen()));
51 use_separate_thread_draw = true;
52 if(using_flags->get_config_ptr() != NULL) {
53 use_separate_thread_draw = using_flags->get_config_ptr()->use_separate_thread_draw;
55 rec_frame_width = 640;
56 rec_frame_height = 480;
58 emu_frame_rate = 1000.0 / 30.0;
59 wait_count = emu_frame_rate;
60 wait_refresh = emu_frame_rate;
62 renderSemaphore = new QSemaphore(0);
65 DrawThreadClass::~DrawThreadClass()
67 if(renderSemaphore != NULL) {
68 while(renderSemaphore->available() <= 0) renderSemaphore->release(1);
69 delete renderSemaphore;
74 void DrawThreadClass::SetEmu(EMU *p)
80 void DrawThreadClass::do_set_frames_per_second(double fps)
82 double _n = 1000.0 / (fps * 2.0);
84 wait_count += (_n * 1.0);
87 void DrawThreadClass::doDrawMain(bool flag)
89 p_osd->do_decode_movie(1);
91 draw_frames = p_osd->draw_screen();
93 draw_frames = p_osd->no_draw_screen();
95 emit sig_draw_frames(draw_frames);
97 void DrawThreadClass::doDraw(bool flag)
99 bRecentRenderStatus = flag;
100 if(!use_separate_thread_draw) {
103 if(renderSemaphore != NULL) renderSemaphore->release(1);
107 void DrawThreadClass::doExit(void)
109 //csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL,
110 // "DrawThread : Exit.");
112 if(renderSemaphore != NULL) {
113 while(renderSemaphore->available() <= 0) renderSemaphore->release(1);
117 void DrawThreadClass::do_draw_one_turn(bool _req_draw)
119 if((_req_draw) && (draw_screen_buffer != NULL)) {
120 emit sig_update_screen(draw_screen_buffer);
122 if(ncount == 0) emit sig_update_osd();
125 if(ncount >= 8) ncount = 0;
126 if(rec_frame_count > 0) {
127 emit sig_push_frames_to_avio(rec_frame_count,
128 rec_frame_width, rec_frame_height);
129 rec_frame_count = -1;
133 void DrawThreadClass::doWork(const QString ¶m)
137 double _rate = 1000.0 / 30.0;
139 if(renderSemaphore == NULL) goto __exit;
141 _rate = (wait_refresh < emu_frame_rate) ? emu_frame_rate : wait_refresh;
145 wait_factor = (int)_rate - 1;
147 if(renderSemaphore->tryAcquire(1, wait_factor)) { // Success
148 if(!bRunThread) break;
149 volatile bool _b = bRecentRenderStatus;
150 bRecentRenderStatus = false;
153 if(!bRunThread) break;
154 volatile bool _d = bDrawReq;
155 if(draw_screen_buffer == NULL) _d = false;
156 if((_d) && (draw_screen_buffer != NULL)) bDrawReq = false;
157 do_draw_one_turn(_d);
160 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL,
161 "DrawThread : Exit.");
165 void DrawThreadClass::do_change_refresh_rate(qreal rate)
168 wait_refresh = 1000.0 / (refresh_rate * 2.0);
169 wait_count += (wait_refresh * 1.0);
172 void DrawThreadClass::do_update_screen(bitmap_t *p)
174 draw_screen_buffer = p;
178 void DrawThreadClass::do_req_encueue_video(int count, int width, int height)
180 rec_frame_width = width;
181 rec_frame_height = height;
182 rec_frame_count = count;