Browse Source

wgldisplay: report context binding error, keep track of thread

This isn't really a complete solution, just a stopgap measure to prevent a crash.
rdb 7 years ago
parent
commit
b85fead09d

+ 8 - 3
panda/src/wgldisplay/wglGraphicsPipe.cxx

@@ -22,6 +22,7 @@ TypeHandle wglGraphicsPipe::_type_handle;
 bool    wglGraphicsPipe::_current_valid;
 bool    wglGraphicsPipe::_current_valid;
 HDC     wglGraphicsPipe::_current_hdc;
 HDC     wglGraphicsPipe::_current_hdc;
 HGLRC   wglGraphicsPipe::_current_hglrc;
 HGLRC   wglGraphicsPipe::_current_hglrc;
+Thread *wglGraphicsPipe::_current_thread;
 
 
 /**
 /**
  *
  *
@@ -41,16 +42,19 @@ wglGraphicsPipe::
 /**
 /**
  * a thin wrapper around wglMakeCurrent to avoid unnecessary OS-call overhead.
  * a thin wrapper around wglMakeCurrent to avoid unnecessary OS-call overhead.
  */
  */
-void wglGraphicsPipe::
+bool wglGraphicsPipe::
 wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector) {
 wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector) {
+  Thread *thread = Thread::get_current_thread();
   if ((_current_valid) &&
   if ((_current_valid) &&
       (_current_hdc == hdc) &&
       (_current_hdc == hdc) &&
-      (_current_hglrc == hglrc)) {
-    return;
+      (_current_hglrc == hglrc) &&
+      (_current_thread == thread)) {
+    return true;
   }
   }
   _current_valid = true;
   _current_valid = true;
   _current_hdc = hdc;
   _current_hdc = hdc;
   _current_hglrc = hglrc;
   _current_hglrc = hglrc;
+  _current_thread = thread;
   BOOL res;
   BOOL res;
   if (collector) {
   if (collector) {
     PStatTimer timer(*collector);
     PStatTimer timer(*collector);
@@ -58,6 +62,7 @@ wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector) {
   } else {
   } else {
     res = wglMakeCurrent(hdc, hglrc);
     res = wglMakeCurrent(hdc, hglrc);
   }
   }
+  return (res != 0);
 }
 }
 
 
 /**
 /**

+ 2 - 1
panda/src/wgldisplay/wglGraphicsPipe.h

@@ -46,11 +46,12 @@ protected:
 private:
 private:
 
 
   static std::string format_pfd_flags(DWORD pfd_flags);
   static std::string format_pfd_flags(DWORD pfd_flags);
-  static void wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector);
+  static bool wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector);
 
 
   static bool  _current_valid;
   static bool  _current_valid;
   static HDC   _current_hdc;
   static HDC   _current_hdc;
   static HGLRC _current_hglrc;
   static HGLRC _current_hglrc;
+  static Thread *_current_thread;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 6 - 1
panda/src/wgldisplay/wglGraphicsStateGuardian.cxx

@@ -319,7 +319,12 @@ choose_pixel_format(const FrameBufferProperties &properties,
     return;
     return;
   }
   }
 
 
-  wglGraphicsPipe::wgl_make_current(twindow_dc, twindow_ctx, nullptr);
+  if (!wglGraphicsPipe::wgl_make_current(twindow_dc, twindow_ctx, nullptr)) {
+    wgldisplay_cat.error()
+      << "Failed to make WGL context current.\n";
+    wglDeleteContext(twindow_ctx);
+    return;
+  }
 
 
   _extensions.clear();
   _extensions.clear();
   save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS));
   save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS));

+ 5 - 1
panda/src/wgldisplay/wglGraphicsWindow.cxx

@@ -79,7 +79,11 @@ begin_frame(FrameMode mode, Thread *current_thread) {
   HGLRC context = wglgsg->get_context(_hdc);
   HGLRC context = wglgsg->get_context(_hdc);
   nassertr(context, false);
   nassertr(context, false);
 
 
-  wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
+  if (!wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector)) {
+    wgldisplay_cat.error()
+      << "Failed to make WGL context current.\n";
+    return false;
+  }
   wglgsg->reset_if_new();
   wglgsg->reset_if_new();
 
 
   if (mode == FM_render) {
   if (mode == FM_render) {