more fullscreen fixes

This commit is contained in:
David Rose 2007-04-26 23:53:54 +00:00
parent 25ddc12ae9
commit 554430ab21
12 changed files with 150 additions and 50 deletions

View File

@ -39,6 +39,7 @@
#include "displayRegion.h"
#include "graphicsOutput.h"
#include "texturePool.h"
#include "geomMunger.h"
#include <algorithm>
#include <limits.h>
@ -192,6 +193,8 @@ GraphicsStateGuardian::
delete _stencil_render_states;
_stencil_render_states = 0;
}
GeomMunger::unregister_mungers_for_gsg(this);
}
////////////////////////////////////////////////////////////////////
@ -614,31 +617,40 @@ end_occlusion_query() {
////////////////////////////////////////////////////////////////////
PT(GeomMunger) GraphicsStateGuardian::
get_geom_munger(const RenderState *state, Thread *current_thread) {
// We can cast the RenderState to a non-const object because we are
// only updating a cache within the RenderState, not really changing
// any of its properties.
RenderState *nc_state = ((RenderState *)state);
// Before we even look up the map, see if the _last_mi value points
// to this GSG. This is likely because we tend to visit the same
// state multiple times during a frame. Also, this might well be
// the only GSG in the world anyway.
if (!state->_mungers.empty()) {
RenderState::Mungers::const_iterator mi = state->_last_mi;
if (!nc_state->_mungers.empty()) {
RenderState::Mungers::const_iterator mi = nc_state->_last_mi;
if (!(*mi).first.was_deleted() && (*mi).first == this) {
return (*mi).second;
if ((*mi).second->is_registered()) {
return (*mi).second;
}
}
}
// Nope, we have to look it up in the map.
RenderState::Mungers::const_iterator mi = state->_mungers.find(this);
if (mi != state->_mungers.end() && !(*mi).first.was_deleted()) {
((RenderState *)state)->_last_mi = mi;
return (*mi).second;
RenderState::Mungers::iterator mi = nc_state->_mungers.find(this);
if (mi != nc_state->_mungers.end() && !(*mi).first.was_deleted()) {
if ((*mi).second->is_registered()) {
nc_state->_last_mi = mi;
return (*mi).second;
}
// This GeomMunger is no longer registered. Remove it from the
// map.
nc_state->_mungers.erase(mi);
}
// Nothing in the map; create a new entry.
PT(GeomMunger) munger = make_geom_munger(state, current_thread);
PT(GeomMunger) munger = make_geom_munger(nc_state, current_thread);
nassertr(munger->is_registered(), munger);
// Cast the RenderState to a non-const object. We can do this
// because we are only updating a cache within the RenderState, not
// really changing any of its properties.
RenderState *nc_state = (RenderState *)state;
mi = nc_state->_mungers.insert(RenderState::Mungers::value_type(this, munger)).first;
nc_state->_last_mi = mi;

View File

@ -25,5 +25,5 @@
////////////////////////////////////////////////////////////////////
INLINE GraphicsStateGuardian *StandardMunger::
get_gsg() const {
return _gsg;
return (GraphicsStateGuardian *)GeomMunger::get_gsg();
}

View File

@ -38,11 +38,11 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
int num_components,
StandardMunger::NumericType numeric_type,
StandardMunger::Contents contents) :
StateMunger(gsg),
_num_components(num_components),
_numeric_type(numeric_type),
_contents(contents)
{
_gsg = DCAST(GraphicsStateGuardian, gsg);
_render_mode = state->get_render_mode();
_munge_color = false;
@ -54,7 +54,7 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
if (color_attrib != (ColorAttrib *)NULL &&
color_attrib->get_color_type() == ColorAttrib::T_flat) {
if (!_gsg->get_color_scale_via_lighting()) {
if (!get_gsg()->get_color_scale_via_lighting()) {
// We only need to munge the color directly if the GSG says it
// can't cheat the color via lighting (presumably, in this case,
// by applying a material).
@ -78,8 +78,8 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
// If the GSG says it can't cheat this RGB or alpha scale, we have
// to apply the color scale directly.
if ((color_scale_attrib->has_rgb_scale() && !_gsg->get_color_scale_via_lighting()) ||
(color_scale_attrib->has_alpha_scale() && !_gsg->get_alpha_scale_via_texture(tex_attrib))) {
if ((color_scale_attrib->has_rgb_scale() && !get_gsg()->get_color_scale_via_lighting()) ||
(color_scale_attrib->has_alpha_scale() && !get_gsg()->get_alpha_scale_via_texture(tex_attrib))) {
_munge_color_scale = true;
}
@ -127,9 +127,9 @@ munge_data_impl(const GeomVertexData *data) {
if (table != (TransformBlendTable *)NULL &&
table->get_num_transforms() != 0 &&
table->get_max_simultaneous_transforms() <=
_gsg->get_max_vertex_transforms()) {
get_gsg()->get_max_vertex_transforms()) {
if (matrix_palette &&
table->get_num_transforms() <= _gsg->get_max_vertex_transform_indices()) {
table->get_num_transforms() <= get_gsg()->get_max_vertex_transform_indices()) {
if (table->get_num_transforms() == table->get_max_simultaneous_transforms()) {
// We can support an indexed palette, but since that won't
@ -145,7 +145,7 @@ munge_data_impl(const GeomVertexData *data) {
}
} else if (table->get_num_transforms() <=
_gsg->get_max_vertex_transforms()) {
get_gsg()->get_max_vertex_transforms()) {
// We can't support an indexed palette, but we have few enough
// transforms that we can do a nonindexed table.
animation.set_hardware(table->get_num_transforms(), false);
@ -172,7 +172,7 @@ munge_data_impl(const GeomVertexData *data) {
bool StandardMunger::
munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data,
Thread *current_thread) {
int supported_geom_rendering = _gsg->get_supported_geom_rendering();
int supported_geom_rendering = get_gsg()->get_supported_geom_rendering();
int unsupported_bits = geom->get_geom_rendering() & ~supported_geom_rendering;
if (unsupported_bits != 0) {
@ -225,10 +225,6 @@ int StandardMunger::
compare_to_impl(const GeomMunger *other) const {
const StandardMunger *om = DCAST(StandardMunger, other);
if (_gsg != om->_gsg) {
return _gsg < om->_gsg ? -1 : 1;
}
if (_render_mode != om->_render_mode) {
return _render_mode < om->_render_mode ? -1 : 1;
}

View File

@ -56,7 +56,6 @@ private:
int _num_components;
NumericType _numeric_type;
Contents _contents;
WPT(GraphicsStateGuardian) _gsg;
CPT(RenderModeAttrib) _render_mode;
bool _munge_color;

View File

@ -159,6 +159,9 @@ DXGraphicsStateGuardian9(GraphicsPipe *pipe) :
////////////////////////////////////////////////////////////////////
DXGraphicsStateGuardian9::
~DXGraphicsStateGuardian9() {
dxgsg9_cat.debug()
<< "DXGraphicsStateGuardian9 " << this << " destructing\n";
if (IS_VALID_PTR(_d3d_device)) {
_d3d_device->SetTexture(0, NULL); // this frees reference to the old texture
}
@ -895,10 +898,16 @@ prepare_lens() {
bool DXGraphicsStateGuardian9::
begin_frame(Thread *current_thread) {
DBG_S dxgsg9_cat.debug ( ) << "^^^^^^^^^^^ begin_frame \n"; DBG_E
DBG_S dxgsg9_cat.debug ( ) << "^^^^^^^^^^^ begin_frame \n"; DBG_E
GraphicsStateGuardian::begin_frame(current_thread);
if (_d3d_device == NULL) {
dxgsg9_cat.debug()
<< this << "::begin_frame(): no device.\n";
return false;
}
if (_lru)
{
_lru -> begin_frame ( );
@ -2369,8 +2378,11 @@ reset() {
// TransformState::make_identity());
// want gsg to pass all state settings down so any non-matching defaults we set here get overwritten
assert(_screen->_d3d9 != NULL);
assert(_d3d_device != NULL);
nassertv(_screen->_d3d9 != NULL);
if (_d3d_device == NULL) {
return;
}
D3DCAPS9 d3d_caps;
_d3d_device->GetDeviceCaps(&d3d_caps);
@ -2728,7 +2740,7 @@ reset() {
} else {
// every card is going to have vertex fog, since it's implemented
// in d3d runtime.
assert((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
// vertex fog may look crappy if you have large polygons in the
// foreground and they get clipped, so you may want to disable it
@ -4334,6 +4346,10 @@ set_context(DXScreenData *new_context) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
set_render_target() {
if (_d3d_device == NULL) {
return;
}
LPDIRECT3DSURFACE9 back = NULL, stencil = NULL;
UINT swap_chain;
@ -4566,9 +4582,9 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
DXScreenData **screen) {
HRESULT hr;
assert(IS_VALID_PTR(presentation_params));
assert(IS_VALID_PTR(_screen->_d3d9));
assert(IS_VALID_PTR(_d3d_device));
nassertr(IS_VALID_PTR(presentation_params), E_FAIL);
nassertr(IS_VALID_PTR(_screen->_d3d9), E_FAIL);
nassertr(IS_VALID_PTR(_d3d_device), E_FAIL);
// for windowed mode make sure our format matches the desktop fmt,
// in case the desktop mode has been changed
@ -4681,10 +4697,14 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
bool DXGraphicsStateGuardian9::
check_cooperative_level() {
bool bDoReactivateWindow = false;
if (_d3d_device == NULL) {
return false;
}
HRESULT hr = _d3d_device->TestCooperativeLevel();
if (SUCCEEDED(hr)) {
assert(SUCCEEDED(_last_testcooplevel_result));
nassertr(SUCCEEDED(_last_testcooplevel_result), false);
return true;
}

View File

@ -251,7 +251,11 @@ verify_window_sizes(int numsizes, int *dimen) {
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow9::
close_window() {
wdxdisplay9_cat.debug() << "wdx closed window\n";
if (wdxdisplay9_cat.is_debug()) {
wdxdisplay9_cat.debug()
<< "wdxGraphicsWindow9::close_window() " << this << "\n";
}
if (_gsg != (GraphicsStateGuardian *)NULL) {
_gsg.clear();
_active = false;
@ -316,6 +320,7 @@ open_window() {
wdxdisplay9_cat.debug() << "device width " << _wcontext._display_mode.Width << "\n";
if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
wdxdisplay9_cat.error() << "Unable to create window with specified parameters.\n";
close_window();
return false;
}
_dxgsg->get_pipe()->make_device((void*)(&_wcontext));
@ -565,8 +570,8 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
PRINT_REFCNT(wdxdisplay9, _d3d9);
assert(_d3d9 != NULL);
assert(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION);
nassertr(_d3d9 != NULL, false);
nassertr(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION, false);
bool do_sync = sync_video;
@ -993,14 +998,14 @@ choose_device() {
bool wdxGraphicsWindow9::
consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) {
assert(dxpipe != NULL);
nassertr(dxpipe != NULL, false);
WindowProperties properties = get_properties();
DWORD dwRenderWidth = properties.get_x_size();
DWORD dwRenderHeight = properties.get_y_size();
HRESULT hr;
LPDIRECT3D9 _d3d9 = dxpipe->__d3d9;
assert(_dxgsg != NULL);
nassertr(_dxgsg != NULL, false);
_wcontext._d3d9 = _d3d9;
_wcontext._is_dx9_1 = dxpipe->__is_dx9_1;
_wcontext._card_id = device_info->cardID; // could this change by end?
@ -1207,8 +1212,8 @@ init_resized_window() {
DWORD newWidth = _wcontext._presentation_params.BackBufferWidth;
DWORD newHeight = _wcontext._presentation_params.BackBufferHeight;
assert((newWidth != 0) && (newHeight != 0));
assert(_wcontext._window != NULL);
nassertv((newWidth != 0) && (newHeight != 0));
nassertv(_wcontext._window != NULL);
if (_wcontext._presentation_params.Windowed) {
POINT ul, lr;
@ -1231,7 +1236,7 @@ init_resized_window() {
}
// clear window to black ASAP
assert(_wcontext._window != NULL);
nassertv(_wcontext._window != NULL);
ClearToBlack(_wcontext._window, get_properties());
// clear textures and VB's out of video&AGP mem, so cache is reset

View File

@ -17,6 +17,17 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: GeomMunger::get_gsg
// Access: Public
// Description: Returns a pointer to the GSG that created this
// munger.
////////////////////////////////////////////////////////////////////
INLINE GraphicsStateGuardianBase *GeomMunger::
get_gsg() const {
return _gsg;
}
////////////////////////////////////////////////////////////////////
// Function: GeomMunger::is_registered
// Access: Public
@ -50,6 +61,17 @@ register_munger(GeomMunger *munger, Thread *current_thread) {
return get_registry()->register_munger(munger, current_thread);
}
////////////////////////////////////////////////////////////////////
// Function: GeomMunger::unregister_mungers_for_gsg
// Access: Public, Static
// Description: Removes all the mungers from the registry that are
// associated with the indicated GSG.
////////////////////////////////////////////////////////////////////
INLINE void GeomMunger::
unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg) {
get_registry()->unregister_mungers_for_gsg(gsg);
}
////////////////////////////////////////////////////////////////////
// Function: GeomMunger::munge_format
// Access: Public

View File

@ -33,7 +33,8 @@ PStatCollector GeomMunger::_munge_pcollector("*:Munge");
// Description:
////////////////////////////////////////////////////////////////////
GeomMunger::
GeomMunger() :
GeomMunger(GraphicsStateGuardianBase *gsg) :
_gsg(gsg),
_is_registered(false)
{
#ifndef NDEBUG
@ -281,8 +282,8 @@ compare_to_impl(const GeomMunger *other) const {
// they would produce a different answer to
// munge_format(), munge_data(), or munge_geom(). (They
// still might be different in other ways, but if they
// would produce the same answer, this function consider
// them to be the same.)
// would produce the same answer, this function will
// consider them to be the same.)
////////////////////////////////////////////////////////////////////
int GeomMunger::
geom_compare_to_impl(const GeomMunger *other) const {
@ -417,3 +418,30 @@ unregister_munger(GeomMunger *munger) {
munger->_registered_key = _mungers.end();
munger->do_unregister();
}
////////////////////////////////////////////////////////////////////
// Function: GeomMunger::Registry::unregister_mungers_for_gsg
// Access: Public
// Description: Removes all the mungers from the registry that are
// associated with the indicated GSG.
////////////////////////////////////////////////////////////////////
void GeomMunger::Registry::
unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg) {
MutexHolder holder(_registry_lock);
Mungers::iterator mi = _mungers.begin();
while (mi != _mungers.end()) {
GeomMunger *munger = (*mi);
Mungers::iterator mnext = mi;
++mnext;
if (munger->get_gsg() == gsg) {
nassertv(mi == munger->_registered_key);
_mungers.erase(mi);
munger->_registered_key = _mungers.end();
munger->do_unregister();
}
mi = mnext;
}
}

View File

@ -59,13 +59,16 @@ class Geom;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomMunger : public TypedReferenceCount, public GeomEnums {
public:
GeomMunger();
GeomMunger(GraphicsStateGuardianBase *gsg);
GeomMunger(const GeomMunger &copy);
void operator = (const GeomMunger &copy);
virtual ~GeomMunger();
INLINE GraphicsStateGuardianBase *get_gsg() const;
INLINE bool is_registered() const;
INLINE static PT(GeomMunger) register_munger(GeomMunger *munger, Thread *current_thread);
INLINE static void unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg);
INLINE CPT(GeomVertexFormat) munge_format(const GeomVertexFormat *format,
const GeomVertexAnimationSpec &animation) const;
@ -117,6 +120,8 @@ private:
// This mutex protects the above.
Mutex _formats_lock;
GraphicsStateGuardianBase *_gsg;
bool _is_registered;
typedef pset<GeomMunger *, IndirectCompareTo<GeomMunger> > Mungers;
class EXPCL_PANDA Registry {
@ -124,6 +129,7 @@ private:
Registry();
PT(GeomMunger) register_munger(GeomMunger *munger, Thread *current_thread);
void unregister_munger(GeomMunger *munger);
void unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg);
Mungers _mungers;
Mutex _registry_lock;

View File

@ -16,3 +16,14 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: StateMunger::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE StateMunger::
StateMunger(GraphicsStateGuardianBase *gsg) :
GeomMunger(gsg)
{
}

View File

@ -33,6 +33,7 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA StateMunger : public GeomMunger {
public:
INLINE StateMunger(GraphicsStateGuardianBase *gsg);
virtual ~StateMunger();
CPT(RenderState) munge_state(const RenderState *state);

View File

@ -335,15 +335,15 @@ close_window() {
set_cursor_out_of_window();
DestroyWindow(_hWnd);
// Remove the window handle from our global map.
_window_handles.erase(_hWnd);
_hWnd = (HWND)0;
if (is_fullscreen()) {
// revert to default display mode.
ChangeDisplaySettings(NULL, 0x0);
}
// Remove the window handle from our global map.
_window_handles.erase(_hWnd);
_hWnd = (HWND)0;
GraphicsWindow::close_window();
}