fix removing windows, and also gl hack for compressed mipmaps

This commit is contained in:
David Rose 2009-01-16 01:25:53 +00:00
parent dd717afa00
commit a398ac7517
9 changed files with 132 additions and 5 deletions

View File

@ -467,6 +467,36 @@ remove_window(GraphicsOutput *window) {
do_remove_window(window, current_thread);
GraphicsStateGuardian *gsg = window->get_gsg();
if (gsg != (GraphicsStateGuardian *)NULL) {
PreparedGraphicsObjects *pgo = gsg->get_prepared_objects();
if (pgo != (PreparedGraphicsObjects *)NULL) {
// Check to see if any other still-active windows share this
// context.
bool any_common = false;
{
LightReMutexHolder holder(_lock, current_thread);
Windows::iterator wi;
for (wi = _windows.begin(); wi != _windows.end() && !any_common; ++wi) {
GraphicsStateGuardian *gsg2 = (*wi)->get_gsg();
if (gsg2 != (GraphicsStateGuardian *)NULL &&
gsg2->get_prepared_objects() == pgo) {
any_common = true;
}
}
}
if (!any_common) {
// If no windows still use this context, release all textures,
// etc. We do this in case there is a floating pointer
// somewhere keeping the GSG from destructing when its window
// goes away. A leaked GSG pointer is bad enough, but there's
// no reason we also need to keep around all of the objects
// allocated on graphics memory.
pgo->release_all();
}
}
}
nassertr(count == 1, true);
return true;
}
@ -486,6 +516,10 @@ remove_all_windows() {
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
GraphicsOutput *win = (*wi);
do_remove_window(win, current_thread);
GraphicsStateGuardian *gsg = win->get_gsg();
if (gsg != (GraphicsStateGuardian *)NULL) {
gsg->release_all();
}
}
_windows.clear();

View File

@ -139,6 +139,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
_prepared_objects = new PreparedGraphicsObjects;
_stereo_buffer_mask = ~0;
_incomplete_render = allow_incomplete_render;
_loader = Loader::get_global_ptr();
_is_hardware = false;
_prefers_triangle_strips = false;

View File

@ -660,6 +660,11 @@ reset() {
_supports_generate_mipmap =
has_extension("GL_SGIS_generate_mipmap") || is_at_least_version(1, 4);
// Temporary hack. There is an issue with auto-generating mipmaps
// for pre-compressed images, on certain drivers. Until I check in
// a fix, let's turn off this feature in general.
_supports_generate_mipmap = false;
_supports_multitexture = false;
_supports_mesa_6 = false;
@ -7313,6 +7318,13 @@ upload_texture_image(CLP(TextureContext) *gtc,
gtc->_depth != depth) {
// We need to reload a new image.
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "loading new texture object, " << width << " x " << height
<< " x " << depth << ", mipmaps " << mipmap_bias << " - "
<< num_ram_mipmap_levels << "\n";
}
if (num_ram_mipmap_levels == 0) {
if (external_format == GL_DEPTH_STENCIL_EXT) {
GLP(TexImage2D)(page_target, 0, internal_format,
@ -7404,6 +7416,14 @@ upload_texture_image(CLP(TextureContext) *gtc,
} else {
// We can reload the image over the previous image, possibly
// saving on texture memory fragmentation.
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "subloading existing texture object, " << width << " x " << height
<< " x " << depth << ", mipmaps " << mipmap_bias << " - "
<< num_ram_mipmap_levels << "\n";
}
for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
const unsigned char *image_ptr = tex->get_ram_mipmap_image(n);
if (image_ptr == (const unsigned char *)NULL) {
@ -7747,13 +7767,17 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
GLint width = 1, height = 1, depth = 1;
GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_WIDTH, &width);
GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_HEIGHT, &height);
if (_supports_3d_texture) {
if (target != GL_TEXTURE_1D) {
GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_HEIGHT, &height);
}
if (_supports_3d_texture && target == GL_TEXTURE_3D) {
GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_DEPTH, &depth);
} else if (target == GL_TEXTURE_CUBE_MAP) {
depth = 6;
}
report_my_gl_errors();
GLint internal_format;
GLint internal_format = 0;
GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
// Make sure we were able to query those parameters properly.
@ -7875,6 +7899,11 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
format = Texture::F_rgba;
compression = Texture::CM_fxt1;
break;
default:
GLCAT.warning()
<< "Unhandled internal format for " << tex->get_name()
<< " : " << hex << "0x" << internal_format << dec << "\n";
}
// We don't want to call setup_texture() again; that resets too

View File

@ -35,6 +35,19 @@ BufferResidencyTracker(const string &pgo_name, const string &type_name) :
{
}
////////////////////////////////////////////////////////////////////
// Function: BufferResidencyTracker::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
BufferResidencyTracker::
~BufferResidencyTracker() {
_inactive_nonresident_collector.set_level(0);
_active_nonresident_collector.set_level(0);
_inactive_resident_collector.set_level(0);
_active_resident_collector.set_level(0);
}
////////////////////////////////////////////////////////////////////
// Function: BufferResidencyTracker::begin_frame
// Access: Public
@ -72,6 +85,20 @@ end_frame(Thread *current_thread) {
_active_resident_collector.set_level(_chains[S_active_resident].get_total_size());
}
////////////////////////////////////////////////////////////////////
// Function: BufferResidencyTracker::set_levels
// Access: Public
// Description: Resets the pstats levels to their appropriate values,
// possibly in the middle of a frame.
////////////////////////////////////////////////////////////////////
void BufferResidencyTracker::
set_levels() {
_inactive_nonresident_collector.set_level(_chains[S_inactive_nonresident].get_total_size());
_active_nonresident_collector.set_level(_chains[S_active_nonresident].get_total_size());
_inactive_resident_collector.set_level(_chains[S_inactive_resident].get_total_size());
_active_resident_collector.set_level(_chains[S_active_resident].get_total_size());
}
////////////////////////////////////////////////////////////////////
// Function: BufferResidencyTracker::write
// Access: Public

View File

@ -36,9 +36,11 @@ class BufferContext;
class EXPCL_PANDA_GOBJ BufferResidencyTracker {
public:
BufferResidencyTracker(const string &pgo_name, const string &type_name);
~BufferResidencyTracker();
void begin_frame(Thread *current_thread);
void end_frame(Thread *current_thread);
void set_levels();
INLINE BufferContextChain &get_inactive_nonresident();
INLINE BufferContextChain &get_active_nonresident();

View File

@ -69,6 +69,10 @@ release_all() {
release_all_shaders();
release_all_vertex_buffers();
release_all_index_buffers();
_texture_residency.set_levels();
_vbuffer_residency.set_levels();
_ibuffer_residency.set_levels();
}
////////////////////////////////////////////////////////////////////

View File

@ -964,8 +964,9 @@ clear_ram_mipmap_image(int n) {
// Access: Published
// Description: Automatically fills in the n mipmap levels of the
// Texture, based on the texture's source image. This
// requires the texture's ram image to be available in
// system memory.
// requires the texture's uncompressed ram image to be
// available in system memory. If it is not already, it
// will be fetched if possible.
//
// This call is not normally necessary, since the mipmap
// levels will be generated automatically if needed.
@ -975,6 +976,8 @@ clear_ram_mipmap_image(int n) {
void Texture::
generate_ram_mipmap_images() {
MutexHolder holder(_lock);
do_get_uncompressed_ram_image();
nassertv(do_has_ram_image());
nassertv(_ram_image_compression == CM_off);
nassertv(_component_type != T_float);

View File

@ -57,6 +57,29 @@ set_default_gsg(GraphicsStateGuardianBase *default_gsg) {
_default_gsg = default_gsg;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardianBase::get_num_gsgs
// Access: Published, Static
// Description: Returns the total number of GSG's in the universe.
////////////////////////////////////////////////////////////////////
int GraphicsStateGuardianBase::
get_num_gsgs() {
return _gsgs.size();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardianBase::get_gsg
// Access: Published, Static
// Description: Returns the nth GSG in the universe. GSG's
// automatically add themselves and remove themselves
// from this list as they are created and destroyed.
////////////////////////////////////////////////////////////////////
GraphicsStateGuardianBase *GraphicsStateGuardianBase::
get_gsg(int n) {
nassertr(n >= 0 && n < (int)_gsgs.size(), NULL);
return _gsgs[n];
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardianBase::add_gsg
// Access: Public, Static

View File

@ -215,6 +215,10 @@ PUBLISHED:
static GraphicsStateGuardianBase *get_default_gsg();
static void set_default_gsg(GraphicsStateGuardianBase *default_gsg);
static int get_num_gsgs();
static GraphicsStateGuardianBase *get_gsg(int n);
MAKE_SEQ(get_gsgs, get_num_gsgs, get_gsg);
public:
static void add_gsg(GraphicsStateGuardianBase *gsg);
static void remove_gsg(GraphicsStateGuardianBase *gsg);