OSDN Git Service

[UI][Qt] Remove using_flags->get_config_ptr()->foo. Try to fix issue of http://matsur...
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / draw_thread.cpp
1 /*
2         Skelton for retropc emulator
3         Author : Takeda.Toshiya
4         Port to Qt : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2006.08.18 -
6         License : GPLv2
7         History : 2015.11.10 Split from qt_main.cpp
8         [ win32 main ] -> [ Qt main ] -> [Drawing]
9 */
10
11 #include <Qt>
12 #include <QApplication>
13 #include <QImage>
14 #include <QGuiApplication>
15 #include <QSemaphore>
16 #include <QScreen>
17 #include <QWaitCondition>
18
19 #include <SDL.h>
20 #include "emu.h"
21 #include "osd.h"
22 #include "vm/vm.h"
23
24 #include "qt_main.h"
25 #include "csp_logger.h"
26 #include "mainwidget_base.h"
27 #include "draw_thread.h"
28 #include "gl2/qt_glutil_gl2_0.h"
29 #include "config.h"
30
31
32 DrawThreadClass::DrawThreadClass(OSD *o, CSP_Logger *logger,QObject *parent) : QThread(parent) {
33         MainWindow = (Ui_MainWindowBase *)parent;
34         glv = MainWindow->getGraphicsView();
35         p_osd = o;
36         csp_logger = logger;
37         using_flags = NULL;
38         if(p_osd != NULL) using_flags = p_osd->get_config_flags();
39         screen = QGuiApplication::primaryScreen();
40         
41         draw_screen_buffer = NULL;
42         
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);
46         
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 = config.use_separate_thread_draw;
52         
53         rec_frame_width = 640;
54         rec_frame_height = 480;
55         rec_frame_count = -1;
56         emu_frame_rate = 1000.0 / 30.0;
57         wait_count = emu_frame_rate;
58         wait_refresh = emu_frame_rate;
59         bDrawReq = true;
60         renderSemaphore = new QSemaphore(0);
61 }
62
63 DrawThreadClass::~DrawThreadClass()
64 {
65         if(renderSemaphore != NULL) {
66                 while(renderSemaphore->available() <= 0) renderSemaphore->release(1);
67                 delete renderSemaphore;
68         }
69
70 }
71
72 void DrawThreadClass::SetEmu(EMU *p)
73 {
74         //p_emu = p;
75         p_osd = p->get_osd();
76 }
77
78 void DrawThreadClass::do_set_frames_per_second(double fps)
79 {
80         double _n = 1000.0 / (fps * 2.0);
81         emu_frame_rate = _n;
82         wait_count += (_n * 1.0);
83 }
84
85 void DrawThreadClass::doDrawMain(bool flag)
86 {
87         p_osd->do_decode_movie(1);
88         if(flag) {
89                 draw_frames = p_osd->draw_screen();
90         } else {
91                 draw_frames = p_osd->no_draw_screen();
92         }
93         emit sig_draw_frames(draw_frames);
94 }
95 void DrawThreadClass::doDraw(bool flag)
96 {
97         bRecentRenderStatus = flag;
98         if(!use_separate_thread_draw) {
99                 doDrawMain(flag);
100         } else {
101                 if(renderSemaphore != NULL) renderSemaphore->release(1);
102         }
103 }
104
105 void DrawThreadClass::doExit(void)
106 {
107         //csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL,
108         //                                        "DrawThread : Exit.");
109         bRunThread = false;
110         if(renderSemaphore != NULL) {
111                 while(renderSemaphore->available() <= 0) renderSemaphore->release(1);
112         }
113 }
114
115 void DrawThreadClass::do_draw_one_turn(bool _req_draw)
116 {
117         if((_req_draw) && (draw_screen_buffer != NULL)) {
118                 emit sig_update_screen(draw_screen_buffer);
119         } else {
120                 if(ncount == 0) emit sig_update_osd();
121         }
122         ncount++;
123         if(ncount >= 8) ncount = 0; 
124         if(rec_frame_count > 0) {
125                 emit sig_push_frames_to_avio(rec_frame_count,
126                                                                          rec_frame_width, rec_frame_height);
127                 rec_frame_count = -1;
128         }
129 }
130
131 void DrawThreadClass::doWork(const QString &param)
132 {
133         ncount = 0;
134         bRunThread = true;
135         double _rate = 1000.0 / 30.0;
136         bDrawReq = false;
137         if(renderSemaphore == NULL) goto __exit;
138         do {
139                 _rate = (wait_refresh < emu_frame_rate) ? emu_frame_rate : wait_refresh;
140                 if(_rate < 2.0) {
141                         wait_factor = 2.0;
142                 } else {
143                         wait_factor = (int)_rate - 1;
144                 }
145                 if(renderSemaphore->tryAcquire(1, wait_factor)) { // Success
146                         if(!bRunThread) break;
147                         volatile bool _b = bRecentRenderStatus;
148                         bRecentRenderStatus = false;
149                         doDrawMain(_b);
150                 }
151                 if(!bRunThread) break;
152                 volatile bool _d = bDrawReq;
153                 if(draw_screen_buffer == NULL) _d = false;
154                 if((_d) && (draw_screen_buffer != NULL)) bDrawReq = false;
155                 do_draw_one_turn(_d);
156         } while(bRunThread);
157 __exit:
158         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL,
159                                                   "DrawThread : Exit.");
160         this->exit(0);
161 }
162
163 void DrawThreadClass::do_change_refresh_rate(qreal rate)
164 {
165         refresh_rate = rate;    
166         wait_refresh = 1000.0 / (refresh_rate * 2.0);
167         wait_count += (wait_refresh * 1.0);
168 }
169
170 void DrawThreadClass::do_update_screen(bitmap_t *p)
171 {
172         draw_screen_buffer = p;
173         bDrawReq = true;
174 }
175         
176 void DrawThreadClass::do_req_encueue_video(int count, int width, int height)
177 {
178         rec_frame_width = width;
179         rec_frame_height = height;
180         rec_frame_count = count;
181 }
182