From f4c53f2579361329f4e93a40dd3c0253ba228c24 Mon Sep 17 00:00:00 2001 From: milek7 Date: Mon, 18 Mar 2019 20:11:59 +0100 Subject: [PATCH] python windows improvements --- Globals.cpp | 7 +++++ Globals.h | 3 +- PyInt.cpp | 70 +++++++++++++++++++----------------------- PyInt.h | 6 ++-- pythonscreenviewer.cpp | 41 +++++++++++++++++++++---- pythonscreenviewer.h | 2 ++ 6 files changed, 80 insertions(+), 49 deletions(-) diff --git a/Globals.cpp b/Globals.cpp index 5c4dc851..2f74eb91 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -801,6 +801,13 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(1); Parser >> python_sharectx; } + else if (token == "python.fpslimit") + { + Parser.getTokens(1); + float fpslimit; + Parser >> fpslimit; + python_minframetime = std::chrono::duration(1.0f / fpslimit); + } else if (token == "python.vsync") { Parser.getTokens(1); diff --git a/Globals.h b/Globals.h index 389a91c4..976db1c3 100644 --- a/Globals.h +++ b/Globals.h @@ -188,7 +188,8 @@ struct global_settings { bool python_displaywindows = false; bool python_threadedupload = true; bool python_vsync = true; - bool python_sharectx = false; + bool python_sharectx = true; + std::chrono::duration python_minframetime {0.01f}; int gfx_framebuffer_width = -1; int gfx_framebuffer_height = -1; diff --git a/PyInt.cpp b/PyInt.cpp index 426ed317..5e5da3d1 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -46,35 +46,47 @@ void render_task::run() { if( ( outputwidth != nullptr ) && ( outputheight != nullptr ) && m_target) { - m_width = PyInt_AsLong( outputwidth ); - m_height = PyInt_AsLong( outputheight ); + int width = PyInt_AsLong( outputwidth ); + int height = PyInt_AsLong( outputheight ); + int components, format; const unsigned char *image = reinterpret_cast( PyString_AsString( output ) ); + + std::lock_guard guard(m_target->mutex); + if (m_target->image) + delete[] m_target->image; + if (!Global.gfx_usegles) { - int size = m_width * m_height * 3; - m_format = GL_SRGB8; - m_components = GL_RGB; - m_image = new unsigned char[size]; - memcpy(m_image, image, size); + int size = width * height * 3; + format = GL_SRGB8; + components = GL_RGB; + m_target->image = new unsigned char[size]; + memcpy(m_target->image, image, size); } else { - m_format = GL_SRGB8_ALPHA8; - m_components = GL_RGBA; - m_image = new unsigned char[m_width * m_height * 4]; + format = GL_SRGB8_ALPHA8; + components = GL_RGBA; + m_target->image = new unsigned char[width * height * 4]; - int w = m_width; - int h = m_height; + int w = width; + int h = height; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { - m_image[(y * w + x) * 4 + 0] = image[(y * w + x) * 3 + 0]; - m_image[(y * w + x) * 4 + 1] = image[(y * w + x) * 3 + 1]; - m_image[(y * w + x) * 4 + 2] = image[(y * w + x) * 3 + 2]; - m_image[(y * w + x) * 4 + 3] = 0xFF; + m_target->image[(y * w + x) * 4 + 0] = image[(y * w + x) * 3 + 0]; + m_target->image[(y * w + x) * 4 + 1] = image[(y * w + x) * 3 + 1]; + m_target->image[(y * w + x) * 4 + 2] = image[(y * w + x) * 3 + 2]; + m_target->image[(y * w + x) * 4 + 3] = 0xFF; } } + + m_target->width = width; + m_target->height = height; + m_target->components = components; + m_target->format = format; + m_target->timestamp = std::chrono::high_resolution_clock::now(); } if( outputheight != nullptr ) { Py_DECREF( outputheight ); } if( outputwidth != nullptr ) { Py_DECREF( outputwidth ); } @@ -84,32 +96,14 @@ void render_task::run() { void render_task::upload() { - if (m_image) + if (m_target->image) { glBindTexture(GL_TEXTURE_2D, m_target->shared_tex); glTexImage2D( GL_TEXTURE_2D, 0, - m_format, - m_width, m_height, 0, - m_components, GL_UNSIGNED_BYTE, m_image); - - { - std::lock_guard guard(m_target->mutex); - if (m_target->image) - delete[] m_target->image; - - size_t size = m_width * m_height * (m_components == GL_RGB ? 3 : 4); - m_target->image = new unsigned char[size]; - - memcpy(m_target->image, m_image, size); - - m_target->width = m_width; - m_target->height = m_height; - m_target->components = m_components; - m_target->format = m_format; - } - - delete[] m_image; + m_target->format, + m_target->width, m_target->height, 0, + m_target->components, GL_UNSIGNED_BYTE, m_target->image); if (Global.python_mipmaps) { diff --git a/PyInt.h b/PyInt.h index 9148e916..c3b2ebb3 100644 --- a/PyInt.h +++ b/PyInt.h @@ -80,6 +80,8 @@ struct python_rt { int height; unsigned char *image = nullptr; + std::chrono::high_resolution_clock::time_point timestamp; + ~python_rt() { if (image) delete[] image; @@ -105,10 +107,6 @@ private: PyObject *m_renderer {nullptr}; dictionary_source *m_input { nullptr }; std::shared_ptr m_target { nullptr }; - - unsigned char *m_image = nullptr; - int m_width, m_height; - GLenum m_components, m_format; }; class python_taskqueue { diff --git a/pythonscreenviewer.cpp b/pythonscreenviewer.cpp index a64f0f93..e0bae35a 100644 --- a/pythonscreenviewer.cpp +++ b/pythonscreenviewer.cpp @@ -76,6 +76,8 @@ void python_screen_viewer::threadfunc() while (!m_exit) { + auto start_time = std::chrono::high_resolution_clock::now(); + for (auto &window : m_windows) { glfwMakeContextCurrent(window->window); gl::program::unbind(); @@ -88,16 +90,38 @@ void python_screen_viewer::threadfunc() window->ubo->update(m_ubs); if (!Global.python_sharectx) { - std::lock_guard guard(m_rt->mutex); + unsigned char *image; + int format, components, width, height; - if (!m_rt->image) - continue; + { + std::lock_guard guard(m_rt->mutex); + + if (window->timestamp == m_rt->timestamp) + continue; + + if (!m_rt->image) + continue; + + format = m_rt->format; + components = m_rt->components; + width = m_rt->width; + height = m_rt->height; + + size_t size = width * height * (components == GL_RGB ? 3 : 4); + + image = new unsigned char[size]; + memcpy(image, m_rt->image, size); + + window->timestamp = m_rt->timestamp; + } glTexImage2D( GL_TEXTURE_2D, 0, - m_rt->format, - m_rt->width, m_rt->height, 0, - m_rt->components, GL_UNSIGNED_BYTE, m_rt->image); + format, + width, height, 0, + components, GL_UNSIGNED_BYTE, image); + + delete[] image; if (Global.python_mipmaps) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); @@ -115,6 +139,11 @@ void python_screen_viewer::threadfunc() glfwSwapBuffers(window->window); } + + auto frametime = std::chrono::high_resolution_clock::now() - start_time; + + if ((Global.python_minframetime - frametime).count() > 0.0f) + std::this_thread::sleep_for(Global.minframetime - frametime); } } diff --git a/pythonscreenviewer.h b/pythonscreenviewer.h index f4e8e4ef..e3d675d4 100644 --- a/pythonscreenviewer.h +++ b/pythonscreenviewer.h @@ -14,6 +14,8 @@ class python_screen_viewer std::unique_ptr ubo; std::unique_ptr shader; + std::chrono::high_resolution_clock::time_point timestamp; + window_state() = default; ~window_state(); };