Browse Source

cleaned up window-fullscreen mode and multiple windows mode for dx8 and dx9

Asad M. Zaman 22 years ago
parent
commit
0c85764323

+ 0 - 6
panda/src/display/config_display.cxx

@@ -64,12 +64,6 @@ const string threading_model = config_display.GetString("threading-model", "");
 // until an explicit call to flip_frame() or the next render_frame().
 const bool auto_flip = config_display.GetBool("auto-flip", true);
 
-// This indicates if you want multiple window support for same GSG
-const bool multiple_windows = config_display.GetBool("multiple-windows", false);
-
-// This indicates if you want window_and_fullscreen support for same GSG
-const bool window_and_fullscreen = config_display.GetBool("window-and-fullscreen", false);
-
 // Set this true to yield the timeslice at the end of the frame to be
 // more polite to other applications that are trying to run.
 const bool yield_timeslice = config_display.GetBool("yield-timeslice", false);

+ 0 - 4
panda/src/display/config_display.h

@@ -45,10 +45,6 @@ extern const bool show_buffers;
 extern const bool prefer_parasite_buffer;
 extern const bool prefer_single_buffer;
 
-extern EXPCL_PANDA const bool multiple_windows;
-
-extern EXPCL_PANDA const bool window_and_fullscreen;
-
 extern EXPCL_PANDA void init_libdisplay();
 
 #endif /* CONFIG_DISPLAY_H */

+ 23 - 8
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -965,7 +965,14 @@ do_clear(const RenderBuffer &buffer) {
                                          _depth_clear_value, (DWORD)_stencil_clear_value);
     if(FAILED(hr)) {
         dxgsg8_cat.error() << "clear_buffer failed:  Clear returned " << D3DERRORSTRING(hr);
-        throw_event("panda3d-render-error");
+        // before throwing the event, lets try a 0 flag
+        dxgsg8_cat.error() << "trying with no flag\n";
+        hr = _pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, _d3dcolor_clear_value,
+                                         _depth_clear_value, (DWORD)_stencil_clear_value);
+        if (FAILED(hr)) {
+          dxgsg8_cat.error() << "clear_buffer failed again:  Clear returned " << D3DERRORSTRING(hr);
+          //          throw_event("panda3d-render-error");
+        }
     }
     /* The following line will cause the background to always clear to a medium red
     _color_clear_value[0] = .5;
@@ -1001,7 +1008,7 @@ prepare_display_region() {
       dxgsg8_cat.error()
         << "SetViewport(" << l << ", " << u << ", " << w << ", " << h
         << ") failed" << D3DERRORSTRING(hr);
-#if 0
+#if 1
       D3DVIEWPORT8 vp_old;
       _pD3DDevice->GetViewport( &vp_old );
       dxgsg8_cat.error()
@@ -4541,7 +4548,7 @@ set_context(DXScreenData *pNewContextData) {
     //wdxdisplay8_cat.debug() << "SwapChain = "<< _pSwapChain << "\n";
 }
 
-void DXGraphicsStateGuardian8::  
+bool DXGraphicsStateGuardian8::  
 create_swap_chain(DXScreenData *pNewContextData) {
     // Instead of creating a device and rendering as d3ddevice->present()
     // we should render using SwapChain->present(). This is done to support
@@ -4550,17 +4557,25 @@ create_swap_chain(DXScreenData *pNewContextData) {
 
     HRESULT hr;
     hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain);
-    if (FAILED(hr))
+    if (FAILED(hr)) {
       wdxdisplay8_cat.debug() << "Swapchain creation failed :"<<D3DERRORSTRING(hr)<<"\n";
+      return false;
+    }
+    return true;
 }
 
-void DXGraphicsStateGuardian8::  
+bool DXGraphicsStateGuardian8::  
 release_swap_chain(DXScreenData *pNewContextData) {
     // Release the swap chain on this DXScreenData
   HRESULT hr;
-  hr = pNewContextData->pSwapChain->Release();
-  if (FAILED(hr))
-    wdxdisplay8_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n";
+  if (pNewContextData->pSwapChain) {
+    hr = pNewContextData->pSwapChain->Release();
+    if (FAILED(hr)) {
+      wdxdisplay8_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n";
+      return false;
+    }
+  }
+  return true;
 }
 
 bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) {

+ 2 - 2
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -362,8 +362,8 @@ public:
 
   void support_overlay_window(bool flag);
 
-  void create_swap_chain (DXScreenData *pNewContextData);
-  void release_swap_chain (DXScreenData *pNewContextData);
+  bool create_swap_chain (DXScreenData *pNewContextData);
+  bool release_swap_chain (DXScreenData *pNewContextData);
   void copy_pres_reset(DXScreenData *pNewContextData);
 
 private:

+ 41 - 36
panda/src/dxgsg8/wdxGraphicsWindow8.cxx

@@ -424,8 +424,7 @@ support_overlay_window(bool flag) {
 void wdxGraphicsWindow8::
 close_window() {
   wdxdisplay8_cat.debug() << "wdx closed window\n";
-  if (multiple_windows)
-    _dxgsg->release_swap_chain(&_wcontext);
+  _dxgsg->release_swap_chain(&_wcontext);
   WinGraphicsWindow::close_window();
 }
 
@@ -674,6 +673,8 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
   RECT view_rect;
   HRESULT hr;
 
+  wdxdisplay8_cat.debug()<<"Display Width "<< dwRenderWidth<<" and PresParam Width "<<_wcontext.PresParams.BackBufferWidth<<"\n";
+
   // BUGBUG: need to change panda to put frame buffer properties with GraphicsWindow, not GSG!!
   int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode();
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
@@ -842,7 +843,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
       pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
     }
 
-    //    assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight));
+    //assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight));
 
     hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _hWnd,
                              dwBehaviorFlags, pPresParams, &Display.pD3DDevice);
@@ -1755,15 +1756,11 @@ open_window(void) {
   DXGraphicsStateGuardian8 *dxgsg;
   DCAST_INTO_R(dxgsg,_gsg,false);
   WindowProperties props;
+  bool discard_device = false;
 
   if(!choose_device()) {
     return false;
   }
-  if (dxgsg->get_pipe()->get_device() && !multiple_windows && !window_and_fullscreen) {
-    wdxdisplay8_cat.error() 
-      << "Could not create window; multiple window support not enabled.\n";
-    return false;
-  }
 
   wdxdisplay8_cat.debug() << "_wcontext.hWnd is " << _wcontext.hWnd << "\n";
   if (!WinGraphicsWindow::open_window()) {
@@ -1777,36 +1774,44 @@ open_window(void) {
   // call may be an extension to create multiple windows on same device
   // In that case just create an additional swapchain for this window
 
-  if (dxgsg->get_pipe()->get_device() == NULL || window_and_fullscreen) {
-    wdxdisplay8_cat.debug() << "device is null \n";
-
-    if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer))
-      return false;
-    dxgsg->get_pipe()->make_device((void*)(&_wcontext));
-    dxgsg->copy_pres_reset(&_wcontext);
-    if (multiple_windows) {
-      // then we have no choice but to waste a framebuffer
+  while(1) {
+    if (dxgsg->get_pipe()->get_device() == NULL || discard_device) {
+      wdxdisplay8_cat.debug() << "device is null or fullscreen\n";
+      
+      wdxdisplay8_cat.debug()<<"device width "<<_wcontext.DisplayMode.Width<<"\n";
+      if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
+        // just crash here
+        wdxdisplay8_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n";
+        exit(1); //return false;
+      }
+      dxgsg->get_pipe()->make_device((void*)(&_wcontext));
+      dxgsg->copy_pres_reset(&_wcontext);
       dxgsg->create_swap_chain(&_wcontext);
-    }
+      break;
 
-  } else {
-    // fill in the DXScreenData from dxdevice here and change the
-    // reference to hWnd.
-    wdxdisplay8_cat.debug() << "device is not null\n";
-
-    dxdev = (DXGraphicsDevice8*)dxgsg->get_pipe()->get_device();
-    props = get_properties();
-
-    memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData));
-    _wcontext.hWnd = _hWnd;
-    _wcontext.PresParams.hDeviceWindow = _hWnd;
-    _wcontext.PresParams.BackBufferWidth = props.get_x_size();
-    _wcontext.PresParams.BackBufferHeight = props.get_y_size();
-
-    //wdxdisplay8_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n";
-    //wdxdisplay8_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n";
-    dxgsg->create_swap_chain(&_wcontext);
-    init_resized_window();
+    } else {
+      // fill in the DXScreenData from dxdevice here and change the
+      // reference to hWnd.
+      wdxdisplay8_cat.debug() << "device is not null\n";
+
+      dxdev = (DXGraphicsDevice8*)dxgsg->get_pipe()->get_device();
+      props = get_properties();
+      memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData));
+
+      _wcontext.PresParams.Windowed = !is_fullscreen();
+      _wcontext.PresParams.hDeviceWindow = _wcontext.hWnd = _hWnd;
+      _wcontext.PresParams.BackBufferWidth = _wcontext.DisplayMode.Width = props.get_x_size();
+      _wcontext.PresParams.BackBufferHeight = _wcontext.DisplayMode.Height = props.get_y_size();
+      
+      wdxdisplay8_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n";
+      //wdxdisplay8_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n";
+      if (!dxgsg->create_swap_chain(&_wcontext)) {
+        discard_device = true;
+        continue; // try again
+      }
+      init_resized_window();
+      break;
+    }
   }
   wdxdisplay8_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n";
   return true;

+ 33 - 23
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -4541,35 +4541,45 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) {
 
 void DXGraphicsStateGuardian9::  
 set_context(DXScreenData *pNewContextData) {
-    // dont do copy from window since dx_init sets fields too.
-    // simpler to keep all of it in one place, so use ptr to window struct
-
-    assert(pNewContextData!=NULL);
-    _pScrn = pNewContextData;
-    _pD3DDevice = _pScrn->pD3DDevice;   //copy this one field for speed of deref
-    _pSwapChain = _pScrn->pSwapChain;   //copy this one field for speed of deref
- 
-    //wdxdisplay9_cat.debug() << "SwapChain = "<< _pSwapChain << "\n";
+  // dont do copy from window since dx_init sets fields too.
+  // simpler to keep all of it in one place, so use ptr to window struct
+  
+  assert(pNewContextData!=NULL);
+  _pScrn = pNewContextData;
+  _pD3DDevice = _pScrn->pD3DDevice;   //copy this one field for speed of deref
+  _pSwapChain = _pScrn->pSwapChain;   //copy this one field for speed of deref
+  
+  //wdxdisplay9_cat.debug() << "SwapChain = "<< _pSwapChain << "\n";
 }
 
-void DXGraphicsStateGuardian9::  
+bool DXGraphicsStateGuardian9::  
 create_swap_chain(DXScreenData *pNewContextData) {
-    // Instead of creating a device and rendering as d3ddevice->present()
-    // we should render using SwapChain->present(). This is done to support
-    // multiple windows rendering. For that purpose, we need to set additional
-    // swap chains here.
-
-    HRESULT hr;
-    hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain);
-    if (FAILED(hr))
-      wdxdisplay9_cat.debug() << "Swapchain creation failed :"<<D3DERRORSTRING(hr)<<"\n";
-    //    set_context(pNewContextData);
+  // Instead of creating a device and rendering as d3ddevice->present()
+  // we should render using SwapChain->present(). This is done to support
+  // multiple windows rendering. For that purpose, we need to set additional
+  // swap chains here.
+  
+  HRESULT hr;
+  hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain);
+  if (FAILED(hr)) {
+    wdxdisplay9_cat.debug() << "Swapchain creation failed :"<<D3DERRORSTRING(hr)<<"\n";
+    return false;
+  }
+  return true;
 }
 
-void DXGraphicsStateGuardian9::  
+bool DXGraphicsStateGuardian9::  
 release_swap_chain(DXScreenData *pNewContextData) {
-    // Release the swap chain on this DXScreenData
-    pNewContextData->pSwapChain->Release();
+  // Release the swap chain on this DXScreenData
+  HRESULT hr;
+  if (pNewContextData->pSwapChain) {
+    hr = pNewContextData->pSwapChain->Release();
+    if (FAILED(hr)) {
+      wdxdisplay9_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n";
+      return false;
+    }
+  }
+  return true;
 }
 
 bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) {

+ 2 - 2
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -365,8 +365,8 @@ public:
 
   void support_overlay_window(bool flag);
 
-  void create_swap_chain (DXScreenData *pNewContextData);
-  void release_swap_chain (DXScreenData *pNewContextData);
+  bool create_swap_chain (DXScreenData *pNewContextData);
+  bool release_swap_chain (DXScreenData *pNewContextData);
   void copy_pres_reset(DXScreenData *pNewContextData);
 
 private:

+ 37 - 34
panda/src/dxgsg9/wdxGraphicsWindow9.cxx

@@ -424,8 +424,7 @@ support_overlay_window(bool flag) {
 void wdxGraphicsWindow9::
 close_window() {
   wdxdisplay9_cat.debug() << "wdx closed window\n";
-  if (multiple_windows)
-    _dxgsg->release_swap_chain(&_wcontext);
+  _dxgsg->release_swap_chain(&_wcontext);
   WinGraphicsWindow::close_window();
 }
 
@@ -1753,15 +1752,11 @@ open_window(void) {
   DXGraphicsStateGuardian9 *dxgsg;
   DCAST_INTO_R(dxgsg,_gsg,false);
   WindowProperties props;
+  bool discard_device = false;
 
   if(!choose_device()) {
       return false;
   }
-  if (dxgsg->get_pipe()->get_device() && !multiple_windows && !window_and_fullscreen) {
-    wdxdisplay9_cat.error() 
-      << "Could not create window; multiple window support not enabled.\n";
-    return false;
-  }
 
   wdxdisplay9_cat.debug() << "_wcontext.hWnd is " << _wcontext.hWnd << "\n";
   if (!WinGraphicsWindow::open_window()) {
@@ -1775,36 +1770,44 @@ open_window(void) {
   // call may be an extension to create multiple windows on same device
   // In that case just create an additional swapchain for this window
 
-  if (dxgsg->get_pipe()->get_device() == NULL || window_and_fullscreen) {
-    wdxdisplay9_cat.debug() << "device is null \n";
+  while(1) {
+    if (dxgsg->get_pipe()->get_device() == NULL || discard_device) {
+      wdxdisplay9_cat.debug() << "device is null or fullscreen\n";
 
-    if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer))
-      return false;
-    dxgsg->get_pipe()->make_device((void*)(&_wcontext));
-    dxgsg->copy_pres_reset(&_wcontext);
-    if (multiple_windows) {
-      // then we have no choice but to waste a framebuffer
+      wdxdisplay9_cat.debug()<<"device width "<<_wcontext.DisplayMode.Width<<"\n";
+      if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
+        // just crash here
+        wdxdisplay9_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n";
+        exit(1);//return false;
+      }
+      dxgsg->get_pipe()->make_device((void*)(&_wcontext));
+      dxgsg->copy_pres_reset(&_wcontext);
       dxgsg->create_swap_chain(&_wcontext);
-    }
+      break;
 
-  } else {
-    // fill in the DXScreenData from dxdevice here and change the
-    // reference to hWnd.
-    wdxdisplay9_cat.debug() << "device is not null\n";
-
-    dxdev = (DXGraphicsDevice9*)dxgsg->get_pipe()->get_device();
-    props = get_properties();
-
-    memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData));
-    _wcontext.hWnd = _hWnd;
-    _wcontext.PresParams.hDeviceWindow = _hWnd;
-    _wcontext.PresParams.BackBufferWidth = props.get_x_size();
-    _wcontext.PresParams.BackBufferHeight = props.get_y_size();
-
-    //wdxdisplay9_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n";
-    //wdxdisplay9_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n";
-    dxgsg->create_swap_chain(&_wcontext);
-    init_resized_window();
+    } else {
+      // fill in the DXScreenData from dxdevice here and change the
+      // reference to hWnd.
+      wdxdisplay9_cat.debug() << "device is not null\n";
+
+      dxdev = (DXGraphicsDevice9*)dxgsg->get_pipe()->get_device();
+      props = get_properties();
+      memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData));
+
+      _wcontext.PresParams.Windowed = !is_fullscreen();
+      _wcontext.PresParams.hDeviceWindow = _wcontext.hWnd = _hWnd;
+      _wcontext.PresParams.BackBufferWidth = _wcontext.DisplayMode.Width = props.get_x_size();
+      _wcontext.PresParams.BackBufferHeight = _wcontext.DisplayMode.Height = props.get_y_size();
+
+      wdxdisplay9_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n";
+      //wdxdisplay9_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n";
+      if (!dxgsg->create_swap_chain(&_wcontext)) {
+        discard_device = true;
+        continue; //try again
+      }
+      init_resized_window();
+      break;
+    }
   }
   wdxdisplay9_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n";
   return true;