X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=source%2Fsrc%2Fqt%2Fgui%2Fdraw_thread.cpp;h=16ea756486ffe1bc715bfff5733cb84291364fb4;hb=89e0ad9c2c740b1ce9688650172b8fb9b9935476;hp=62e35fd2e53ac43f0300193047d2971fe28dc7c2;hpb=8b43d026a08188a84ec80efca0672736d31d0d50;p=csp-qt%2Fcommon_source_project-fm7.git diff --git a/source/src/qt/gui/draw_thread.cpp b/source/src/qt/gui/draw_thread.cpp index 62e35fd2e..16ea75648 100644 --- a/source/src/qt/gui/draw_thread.cpp +++ b/source/src/qt/gui/draw_thread.cpp @@ -15,8 +15,8 @@ #include #include #include +#include -#include #include "emu.h" #include "osd.h" #include "vm/vm.h" @@ -37,20 +37,27 @@ DrawThreadClass::DrawThreadClass(OSD *o, CSP_Logger *logger,QObject *parent) : Q 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_call_draw_screen()), p_osd, SLOT(draw_screen())); //connect(this, SIGNAL(sig_call_no_draw_screen()), p_osd, SLOT(no_draw_screen())); - use_separate_thread_draw = false; - if(using_flags != NULL) use_separate_thread_draw = using_flags->get_config_ptr()->use_separate_thread_draw; - + use_separate_thread_draw = true; + if(using_flags->get_config_ptr() != NULL) { + use_separate_thread_draw = using_flags->get_config_ptr()->use_separate_thread_draw; + } rec_frame_width = 640; rec_frame_height = 480; rec_frame_count = -1; @@ -59,6 +66,12 @@ DrawThreadClass::DrawThreadClass(OSD *o, CSP_Logger *logger,QObject *parent) : Q wait_refresh = emu_frame_rate; bDrawReq = true; renderSemaphore = new QSemaphore(0); + textureMappingSemaphore = new QSemaphore(0); + mapping_status = false; + mapping_pointer = NULL; + mapping_width = 0; + mapping_height = 0; + mapped_drawn = false; } DrawThreadClass::~DrawThreadClass() @@ -67,6 +80,10 @@ DrawThreadClass::~DrawThreadClass() while(renderSemaphore->available() <= 0) renderSemaphore->release(1); delete renderSemaphore; } + if(textureMappingSemaphore != NULL) { + while(textureMappingSemaphore->available() <= 0) textureMappingSemaphore->release(1); + delete textureMappingSemaphore; + } } @@ -83,14 +100,19 @@ void DrawThreadClass::do_set_frames_per_second(double fps) wait_count += (_n * 1.0); } +// Note: Mapping vram from draw_thread does'nt work well. +// This feature might be disable. 20180728 K.Ohta. void DrawThreadClass::doDrawMain(bool flag) { + //req_map_screen_texture(); p_osd->do_decode_movie(1); if(flag) { draw_frames = p_osd->draw_screen(); } else { draw_frames = p_osd->no_draw_screen(); } + //req_unmap_screen_texture(); + emit sig_draw_frames(draw_frames); } void DrawThreadClass::doDraw(bool flag) @@ -116,7 +138,7 @@ void DrawThreadClass::doExit(void) void DrawThreadClass::do_draw_one_turn(bool _req_draw) { if((_req_draw) && (draw_screen_buffer != NULL)) { - emit sig_update_screen(draw_screen_buffer); + emit sig_update_screen((void *)draw_screen_buffer, mapped_drawn); } else { if(ncount == 0) emit sig_update_osd(); } @@ -127,6 +149,7 @@ void DrawThreadClass::do_draw_one_turn(bool _req_draw) rec_frame_width, rec_frame_height); rec_frame_count = -1; } + mapped_drawn = false; } void DrawThreadClass::doWork(const QString ¶m) @@ -135,25 +158,39 @@ void DrawThreadClass::doWork(const QString ¶m) 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, @@ -168,10 +205,11 @@ void DrawThreadClass::do_change_refresh_rate(qreal rate) 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) @@ -180,4 +218,43 @@ void DrawThreadClass::do_req_encueue_video(int count, int width, int height) rec_frame_height = height; rec_frame_count = count; } +// Note: Mapping vram from draw_thread does'nt work well. +// This feature might be disable. 20180728 K.Ohta. +void DrawThreadClass::req_map_screen_texture() +{ + mapping_status = false; + mapping_pointer = NULL; + mapping_width = 0; + mapping_height = 0; + if(glv->is_ready_to_map_vram_texture()) { + textureMappingSemaphore->acquire(); + //mapping_pointer = (scrntype_t *)(glv->do_map_vram_texture(&mapping_width, &mapping_height)); + //if(mapping_pointer == NULL) { + // mapping_status = false; + // mapping_pointer = NULL; + // mapping_width = 0; + // mapping_height = 0; + //} else { + // mapping_status = true; + //} + //p_osd->do_set_screen_map_texture_address(mapping_pointer, mapping_width, mapping_height); + } +} + +void DrawThreadClass::req_unmap_screen_texture() +{ + if(mapping_status) { + if(glv->is_ready_to_map_vram_texture()) { + emit sig_unmap_texture(); + textureMappingSemaphore->acquire(); + + //glv->do_unmap_vram_texture(); + //mapping_status = false; + //mapping_pointer = NULL; + //mapping_width = 0; + //mapping_height = 0; + //p_osd->do_set_screen_map_texture_address(mapping_pointer, mapping_width, mapping_height); + } + } +}