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().
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);

View File

@ -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 */

View File

@ -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) {

View File

@ -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:

View File

@ -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.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";
return true;

View File

@ -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) {

View File

@ -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:

View File

@ -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.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";
return true;