open_toontown_panda3d/panda/src/pgraph/shaderPool.cxx

238 lines
6.9 KiB
C++

// Filename: shaderPool.cxx
// Created by: aignacio (Mar06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "shaderPool.h"
#include "config_util.h"
#include "config_express.h"
#include "virtualFileSystem.h"
#include "loader.h"
#include "shader.h"
ShaderPool *ShaderPool::_global_ptr = (ShaderPool *)NULL;
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::write
// Access: Published, Static
// Description: Lists the contents of the shader pool to the
// indicated output stream.
////////////////////////////////////////////////////////////////////
void ShaderPool::
write(ostream &out) {
get_ptr()->ns_list_contents(out);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_has_shader
// Access: Private
// Description: The nonstatic implementation of has_shader().
////////////////////////////////////////////////////////////////////
bool ShaderPool::
ns_has_shader(const Filename &orig_filename) {
Filename filename;
resolve_filename(filename, orig_filename);
LightMutexHolder holder(_lock);
Shaders::const_iterator ti;
ti = _shaders.find(filename);
if (ti != _shaders.end()) {
// This shader was previously loaded.
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_load_shader
// Access: Private
// Description: The nonstatic implementation of load_shader().
////////////////////////////////////////////////////////////////////
CPT(Shader) ShaderPool::
ns_load_shader(const Filename &orig_filename) {
Filename filename;
resolve_filename(filename, orig_filename);
{
LightMutexHolder holder(_lock);
Shaders::const_iterator ti;
ti = _shaders.find(filename);
if (ti != _shaders.end()) {
// This shader was previously loaded.
return (*ti).second;
}
}
/*
shader_cat.info()
<< "Loading shader " << filename << "\n";
*/
CPT(Shader) shader;
shader = (CPT(Shader)) NULL;
string extension = filename.get_extension();
if (extension.empty() || extension == "cg" || extension == "hlsl") {
// this does nothing for now
}
if (shader == (CPT(Shader)) NULL) {
shader = Shader::load (filename);
}
if (shader == (CPT(Shader)) NULL) {
// This shader was not found or could not be read.
return NULL;
}
{
LightMutexHolder holder(_lock);
// Now try again. Someone may have loaded the shader in another
// thread.
Shaders::const_iterator ti;
ti = _shaders.find(filename);
if (ti != _shaders.end()) {
// This shader was previously loaded.
return (*ti).second;
}
_shaders[filename] = shader;
}
return shader;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_add_shader
// Access: Private
// Description: The nonstatic implementation of add_shader().
////////////////////////////////////////////////////////////////////
void ShaderPool::
ns_add_shader(const Filename &orig_filename, Shader *shader) {
Filename filename;
resolve_filename(filename, orig_filename);
LightMutexHolder holder(_lock);
// We blow away whatever shader was there previously, if any.
_shaders[filename] = shader;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_release_shader
// Access: Private
// Description: The nonstatic implementation of release_shader().
////////////////////////////////////////////////////////////////////
void ShaderPool::
ns_release_shader(const Filename &filename) {
LightMutexHolder holder(_lock);
Shaders::iterator ti;
ti = _shaders.find(filename);
if (ti != _shaders.end()) {
_shaders.erase(ti);
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_release_all_shaders
// Access: Private
// Description: The nonstatic implementation of release_all_shaders().
////////////////////////////////////////////////////////////////////
void ShaderPool::
ns_release_all_shaders() {
LightMutexHolder holder(_lock);
_shaders.clear();
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_garbage_collect
// Access: Private
// Description: The nonstatic implementation of garbage_collect().
////////////////////////////////////////////////////////////////////
int ShaderPool::
ns_garbage_collect() {
LightMutexHolder holder(_lock);
int num_released = 0;
Shaders new_set;
Shaders::iterator ti;
for (ti = _shaders.begin(); ti != _shaders.end(); ++ti) {
CPT(Shader) shader = (*ti).second;
if (shader->get_ref_count() == 1) {
/*
if (shader_cat.is_debug()) {
shader_cat.debug()
<< "Releasing " << (*ti).first << "\n";
}
*/
num_released++;
} else {
new_set.insert(new_set.end(), *ti);
}
}
_shaders.swap(new_set);
return num_released;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::ns_list_contents
// Access: Private
// Description: The nonstatic implementation of list_contents().
////////////////////////////////////////////////////////////////////
void ShaderPool::
ns_list_contents(ostream &out) const {
LightMutexHolder holder(_lock);
out << _shaders.size() << " shaders:\n";
Shaders::const_iterator ti;
for (ti = _shaders.begin(); ti != _shaders.end(); ++ti) {
CPT(Shader) shader = (*ti).second;
out << " " << (*ti).first
<< " (count = " << shader->get_ref_count() << ")\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::resolve_filename
// Access: Private
// Description: Searches for the indicated filename along the
// model path.
////////////////////////////////////////////////////////////////////
void ShaderPool::
resolve_filename(Filename &new_filename, const Filename &orig_filename) {
new_filename = orig_filename;
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(new_filename, get_model_path());
}
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::get_ptr
// Access: Private, Static
// Description: Initializes and/or returns the global pointer to the
// one ShaderPool object in the system.
////////////////////////////////////////////////////////////////////
ShaderPool *ShaderPool::
get_ptr() {
if (_global_ptr == (ShaderPool *)NULL) {
_global_ptr = new ShaderPool;
}
return _global_ptr;
}