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

This commit is contained in:
Asad M. Zaman 2004-03-31 22:02:42 +00:00
parent a75582f40c
commit 0c85764323
8 changed files with 138 additions and 115 deletions

View File

@ -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(). // until an explicit call to flip_frame() or the next render_frame().
const bool auto_flip = config_display.GetBool("auto-flip", true); 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 // 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. // more polite to other applications that are trying to run.
const bool yield_timeslice = config_display.GetBool("yield-timeslice", false); const bool yield_timeslice = config_display.GetBool("yield-timeslice", false);

View File

@ -45,10 +45,6 @@ extern const bool show_buffers;
extern const bool prefer_parasite_buffer; extern const bool prefer_parasite_buffer;
extern const bool prefer_single_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(); extern EXPCL_PANDA void init_libdisplay();
#endif /* CONFIG_DISPLAY_H */ #endif /* CONFIG_DISPLAY_H */

View File

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

View File

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

View File

@ -424,8 +424,7 @@ support_overlay_window(bool flag) {
void wdxGraphicsWindow8:: void wdxGraphicsWindow8::
close_window() { close_window() {
wdxdisplay8_cat.debug() << "wdx closed window\n"; wdxdisplay8_cat.debug() << "wdx closed window\n";
if (multiple_windows) _dxgsg->release_swap_chain(&_wcontext);
_dxgsg->release_swap_chain(&_wcontext);
WinGraphicsWindow::close_window(); WinGraphicsWindow::close_window();
} }
@ -674,6 +673,8 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
RECT view_rect; RECT view_rect;
HRESULT hr; 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!! // 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(); int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode();
bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0); 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; 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, hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _hWnd,
dwBehaviorFlags, pPresParams, &Display.pD3DDevice); dwBehaviorFlags, pPresParams, &Display.pD3DDevice);
@ -1755,15 +1756,11 @@ open_window(void) {
DXGraphicsStateGuardian8 *dxgsg; DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_R(dxgsg,_gsg,false); DCAST_INTO_R(dxgsg,_gsg,false);
WindowProperties props; WindowProperties props;
bool discard_device = false;
if(!choose_device()) { if(!choose_device()) {
return false; 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"; wdxdisplay8_cat.debug() << "_wcontext.hWnd is " << _wcontext.hWnd << "\n";
if (!WinGraphicsWindow::open_window()) { if (!WinGraphicsWindow::open_window()) {
@ -1777,36 +1774,44 @@ open_window(void) {
// call may be an extension to create multiple windows on same device // call may be an extension to create multiple windows on same device
// In that case just create an additional swapchain for this window // In that case just create an additional swapchain for this window
if (dxgsg->get_pipe()->get_device() == NULL || window_and_fullscreen) { while(1) {
wdxdisplay8_cat.debug() << "device is null \n"; if (dxgsg->get_pipe()->get_device() == NULL || discard_device) {
wdxdisplay8_cat.debug() << "device is null or fullscreen\n";
if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) wdxdisplay8_cat.debug()<<"device width "<<_wcontext.DisplayMode.Width<<"\n";
return false; if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
dxgsg->get_pipe()->make_device((void*)(&_wcontext)); // just crash here
dxgsg->copy_pres_reset(&_wcontext); wdxdisplay8_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n";
if (multiple_windows) { exit(1); //return false;
// then we have no choice but to waste a framebuffer }
dxgsg->get_pipe()->make_device((void*)(&_wcontext));
dxgsg->copy_pres_reset(&_wcontext);
dxgsg->create_swap_chain(&_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.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;
} }
} 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();
} }
wdxdisplay8_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; wdxdisplay8_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n";
return true; return true;

View File

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

View File

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

View File

@ -424,8 +424,7 @@ support_overlay_window(bool flag) {
void wdxGraphicsWindow9:: void wdxGraphicsWindow9::
close_window() { close_window() {
wdxdisplay9_cat.debug() << "wdx closed window\n"; wdxdisplay9_cat.debug() << "wdx closed window\n";
if (multiple_windows) _dxgsg->release_swap_chain(&_wcontext);
_dxgsg->release_swap_chain(&_wcontext);
WinGraphicsWindow::close_window(); WinGraphicsWindow::close_window();
} }
@ -1753,15 +1752,11 @@ open_window(void) {
DXGraphicsStateGuardian9 *dxgsg; DXGraphicsStateGuardian9 *dxgsg;
DCAST_INTO_R(dxgsg,_gsg,false); DCAST_INTO_R(dxgsg,_gsg,false);
WindowProperties props; WindowProperties props;
bool discard_device = false;
if(!choose_device()) { if(!choose_device()) {
return false; 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"; wdxdisplay9_cat.debug() << "_wcontext.hWnd is " << _wcontext.hWnd << "\n";
if (!WinGraphicsWindow::open_window()) { if (!WinGraphicsWindow::open_window()) {
@ -1775,36 +1770,44 @@ open_window(void) {
// call may be an extension to create multiple windows on same device // call may be an extension to create multiple windows on same device
// In that case just create an additional swapchain for this window // In that case just create an additional swapchain for this window
if (dxgsg->get_pipe()->get_device() == NULL || window_and_fullscreen) { while(1) {
wdxdisplay9_cat.debug() << "device is null \n"; 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)) wdxdisplay9_cat.debug()<<"device width "<<_wcontext.DisplayMode.Width<<"\n";
return false; if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
dxgsg->get_pipe()->make_device((void*)(&_wcontext)); // just crash here
dxgsg->copy_pres_reset(&_wcontext); wdxdisplay9_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n";
if (multiple_windows) { exit(1);//return false;
// then we have no choice but to waste a framebuffer }
dxgsg->get_pipe()->make_device((void*)(&_wcontext));
dxgsg->copy_pres_reset(&_wcontext);
dxgsg->create_swap_chain(&_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.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;
} }
} 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();
} }
wdxdisplay9_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; wdxdisplay9_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n";
return true; return true;