@@ -118,13 +118,69 @@ void window_opengl::shutdown()
118118 ::UnregisterClassW (wc.lpszClassName, wc.hInstance);
119119}
120120
121+ #include " one_call_function.hpp"
121122#include " single_async_executor.hpp"
123+ #include " syncer.hpp"
122124#include < atomic>
123125#include < iostream>
126+
127+ #include < mutex>
128+
129+ struct async_ogl
130+ {
131+ HWND hwnd;
132+ HDC hdc;
133+ HGLRC hglrc;
134+ std::mutex mutex;
135+ void init (HWND hwnd, HGLRC main_hglrc)
136+ {
137+ this ->hwnd = hwnd;
138+ hdc = ::GetDC (hwnd);
139+ hglrc = wglCreateContext (hdc);
140+ if (main_hglrc)
141+ wglShareLists (main_hglrc, hglrc);
142+ }
143+ void destory (HWND hwnd)
144+ {
145+ std::unique_lock lock (mutex);
146+ if (hglrc)
147+ {
148+ wglMakeCurrent (hdc, nullptr );
149+ wglDeleteContext (hglrc);
150+ hglrc = nullptr ;
151+ }
152+ if (hdc)
153+ {
154+ ReleaseDC (hwnd, hdc);
155+ hdc = nullptr ;
156+ }
157+ }
158+ };
159+
160+ struct unique_ogl_lock
161+ {
162+ async_ogl& async;
163+ bool ret = {};
164+ unique_ogl_lock (async_ogl& async) : async(async)
165+ {
166+ async.mutex .lock ();
167+ ret = wglMakeCurrent (async.hdc , async.hglrc );
168+ }
169+ ~unique_ogl_lock ()
170+ {
171+ wglMakeCurrent (async.hdc , nullptr );
172+ wglMakeCurrent (nullptr , nullptr );
173+ async.mutex .unlock ();
174+ }
175+ };
176+
124177struct imapp
125178{
126179 window_opengl window;
180+ stdex::one_call_function<void ()> one_call;
127181 stdex::single_async_executor<void > executor;
182+ stdex::syncer<std::function<void ()>, true > render_syncer;
183+ std::function<void ()> render;
128184 std::atomic_flag is_running = ATOMIC_FLAG_INIT;
129185
130186 void async_execute ()
@@ -135,28 +191,48 @@ struct imapp
135191 create ();
136192 while (is_running.test_and_set ())
137193 {
194+ one_call ();
195+
138196 event_process ();
139197 new_frame ();
140- render ();
198+
199+ render_syncer.try_sync (render);
200+ if (render)
201+ render ();
202+
203+ render_and_swap ();
141204 }
142205 destory ();
143206 }
144207 catch (const std::exception& e)
145208 {
146- std::cerr << " Exception: " << e.what () << std::endl;
209+ // std::cerr << "Exception: " << e.what() << std::endl;
147210 }
148211 catch (...)
149212 {
150- std::cerr << " Unknown exception occurred." << std::endl;
213+ // std::cerr << "Unknown exception occurred." << std::endl;
151214 }
152215 });
153216 }
154217
155218 void create ();
156219 void event_process ();
157220 void new_frame ();
158- void render ();
221+ void render_and_swap ();
159222 void destory ();
223+
224+ std::shared_ptr<async_ogl> create_async_ogl ()
225+ {
226+ auto async = std::make_shared<async_ogl>();
227+ std::promise<void > promise;
228+ std::future<void > future = promise.get_future ();
229+ one_call = [&promise = std::move (promise), async, this ]() {
230+ async->init (window.hwnd , window.hglrc );
231+ promise.set_value ();
232+ };
233+ future.wait ();
234+ return async;
235+ }
160236};
161237void imapp::create ()
162238{
@@ -166,6 +242,7 @@ void imapp::create()
166242 IMGUI_CHECKVERSION ();
167243 ImGui::CreateContext ();
168244 ImGuiIO& io = ImGui::GetIO ();
245+ io.IniFilename = nullptr ; // Disable .ini file
169246 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
170247 io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
171248
@@ -187,18 +264,23 @@ void imapp::event_process()
187264 ::TranslateMessage (&msg);
188265 ::DispatchMessage (&msg);
189266 if (msg.message == WM_QUIT)
190- is_running.clear ();
267+ {
268+ std::cout << " Quit message received." << std::endl;
269+ // is_running.clear();
270+ }
191271 }
192272 if (::IsIconic (window.hwnd ))
193273 ::Sleep (10 );
274+ if (::IsWindow (window.hwnd ) == false )
275+ is_running.clear ();
194276}
195277void imapp::new_frame ()
196278{
197279 ImGui_ImplOpenGL3_NewFrame ();
198280 ImGui_ImplWin32_NewFrame ();
199281 ImGui::NewFrame ();
200282}
201- void imapp::render ()
283+ void imapp::render_and_swap ()
202284{
203285 ImGui::Render ();
204286 glViewport (0 , 0 , window.width , window.height );
@@ -216,30 +298,127 @@ void imapp::destory()
216298 window.shutdown ();
217299}
218300
301+ #include < opencv2/core/opengl.hpp>
302+
219303struct debugger ::impl_t
220304{
221305 imapp app;
306+ std::vector<unique_render_image> render_images;
307+ stdex::syncer<std::vector<unique_render_image>, true > render_image_syncer;
222308
223309 void setup () { app.async_execute (); }
224310 void shutdown ()
225311 {
226312 app.is_running .clear ();
227- app. executor . wait ();
313+ wait_exit ();
228314 }
315+ void wait_exit () { app.executor .wait (); }
316+ void update_render (std::function<void ()> render) { app.render_syncer .set (render); }
229317};
230318
231319debugger::debugger () : impl(std::make_unique<impl_t >()) {}
232- debugger::~debugger () { impl->shutdown (); }
320+ debugger::~debugger ()
321+ {
322+ impl->shutdown ();
323+ }
324+ #include " pool.hpp"
233325
234326void debugger::initlize ()
235327{
236328 impl->setup ();
329+
330+ set_render ([this ]() {
331+ ImGui::Begin (" Debugger" );
332+ ImGui::Text (" Render Images" );
333+ ImGui::Text (" Press 'R' to refresh" );
334+ if (ImGui::Button (" Refresh" ))
335+ {
336+ static stdex::single_async_executor<void > async_executor;
337+ async_executor.submit_exclusive ([this ]() {
338+ auto ogl = impl->app .create_async_ogl ();
339+ unique_ogl_lock lock (*ogl);
340+
341+ std::vector<unique_render_image> images;
342+ for (int i = 0 ; i < 1 ; ++i)
343+ {
344+ cv::Mat image = cv::Mat::zeros (200 , 200 , CV_8UC3);
345+ cv::rectangle (image, cv::Point (rand () % 50 + 2 , 50 ), cv::Point (150 , 150 ), cv::Scalar (0 , 255 , 0 ), -1 );
346+ unique_render_image render_image;
347+ render_image.tex_ref = std::make_shared<cv::ogl::Texture2D>(image, true );
348+ render_image.texture_id = render_image.tex_ref ->texId ();
349+ render_image.width = image.cols ;
350+ render_image.height = image.rows ;
351+ images.push_back (render_image);
352+ }
353+ impl->render_image_syncer .set (images);
354+ });
355+ }
356+ impl->render_image_syncer .try_sync (impl->render_images );
357+ for (auto & image : impl->render_images )
358+ {
359+ ImGui::Image ((intptr_t )image.texture_id , ImVec2 (image.width , image.height ));
360+ }
361+ ImGui::End ();
362+ });
237363}
238364void debugger::destory ()
239365{
240366 impl->shutdown ();
241367}
368+ void debugger::wait_exit ()
369+ {
370+ impl->wait_exit ();
371+ }
372+ void debugger::set_render (std::function<void ()> render)
373+ {
374+ impl->update_render (render);
375+ }
376+ // #include "self_releasing_async.hpp"
377+
378+ #include < frame/frame.include.h>
379+ #include < global/record/record.stdlog.h>
242380std::string debugger::call (std::string command, std::string args)
243381{
382+ if (command == " capture" )
383+ {
384+ if (args == " current" )
385+ {
386+
387+ auto logger = std::make_shared<tianli::global::record::std_logger>();
388+ auto capture = tianli::frame::frame_source::create (tianli::frame::frame_source::source_type::bitblt, logger);
389+ cv::Mat frame;
390+
391+ capture->set_capture_handle (GetDesktopWindow ());
392+ while (frame.empty ())
393+ {
394+ std::this_thread::sleep_for (std::chrono::milliseconds (18 ));
395+ capture->get_frame (frame);
396+ std::cout << " Capture current frame" << std::endl;
397+ if (frame.empty ())
398+ {
399+ std::cout << " Capture failed" << std::endl;
400+ }
401+ }
402+ static stdex::single_async_executor<void > async_executor;
403+ async_executor.submit_exclusive ([frame, this ]() {
404+ auto ogl = impl->app .create_async_ogl ();
405+ unique_ogl_lock lock (*ogl);
406+ std::vector<unique_render_image> images;
407+ {
408+ unique_render_image render_image;
409+ render_image.tex_ref = std::make_shared<cv::ogl::Texture2D>(frame.clone (), true );
410+ render_image.texture_id = render_image.tex_ref ->texId ();
411+ render_image.width = render_image.tex_ref ->cols ();
412+ render_image.height = render_image.tex_ref ->rows ();
413+ images.push_back (render_image);
414+ }
415+ impl->render_image_syncer .set (images);
416+ });
417+ }
418+ }
419+ else
420+ {
421+ return " Unknown command" ;
422+ }
244423 return {};
245424}
0 commit comments