Panda3D

shaderPool.cxx

00001 // Filename: shaderPool.cxx
00002 // Created by:  aignacio (Mar06)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "shaderPool.h"
00016 #include "config_util.h"
00017 #include "config_express.h"
00018 #include "virtualFileSystem.h"
00019 #include "loader.h"
00020 #include "shader.h"
00021 
00022 ShaderPool *ShaderPool::_global_ptr = (ShaderPool *)NULL;
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: ShaderPool::write
00026 //       Access: Published, Static
00027 //  Description: Lists the contents of the shader pool to the
00028 //               indicated output stream.
00029 ////////////////////////////////////////////////////////////////////
00030 void ShaderPool::
00031 write(ostream &out) {
00032   get_ptr()->ns_list_contents(out);
00033 }
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: ShaderPool::ns_has_shader
00037 //       Access: Private
00038 //  Description: The nonstatic implementation of has_shader().
00039 ////////////////////////////////////////////////////////////////////
00040 bool ShaderPool::
00041 ns_has_shader(const Filename &orig_filename) {
00042   Filename filename;
00043   resolve_filename(filename, orig_filename);
00044 
00045   LightMutexHolder holder(_lock);
00046   Shaders::const_iterator ti;
00047   ti = _shaders.find(filename);
00048   if (ti != _shaders.end()) {
00049     // This shader was previously loaded.
00050     return true;
00051   }
00052 
00053   return false;
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: ShaderPool::ns_load_shader
00058 //       Access: Private
00059 //  Description: The nonstatic implementation of load_shader().
00060 ////////////////////////////////////////////////////////////////////
00061 CPT(Shader) ShaderPool::
00062 ns_load_shader(const Filename &orig_filename) {
00063   Filename filename;
00064   resolve_filename(filename, orig_filename);
00065 
00066   {
00067     LightMutexHolder holder(_lock);
00068 
00069     Shaders::const_iterator ti;
00070     ti = _shaders.find(filename);
00071     if (ti != _shaders.end()) {
00072       // This shader was previously loaded.
00073       return (*ti).second;
00074     }
00075   }
00076 
00077 /*
00078   shader_cat.info()
00079     << "Loading shader " << filename << "\n";
00080 */
00081 
00082   CPT(Shader) shader;
00083 
00084   shader = (CPT(Shader)) NULL;
00085   string extension = filename.get_extension();
00086 
00087   if (extension.empty() || extension == "cg" || extension == "hlsl") {
00088     // this does nothing for now
00089   }
00090 
00091   if (shader == (CPT(Shader)) NULL) {
00092     shader = Shader::load (filename);
00093   }
00094 
00095   if (shader == (CPT(Shader)) NULL) {
00096     // This shader was not found or could not be read.
00097     return NULL;
00098   }
00099 
00100   {
00101     LightMutexHolder holder(_lock);
00102 
00103     // Now try again.  Someone may have loaded the shader in another
00104     // thread.
00105     Shaders::const_iterator ti;
00106     ti = _shaders.find(filename);
00107     if (ti != _shaders.end()) {
00108       // This shader was previously loaded.
00109       return (*ti).second;
00110     }
00111 
00112     _shaders[filename] = shader;
00113   }
00114 
00115   return shader;
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: ShaderPool::ns_add_shader
00120 //       Access: Private
00121 //  Description: The nonstatic implementation of add_shader().
00122 ////////////////////////////////////////////////////////////////////
00123 void ShaderPool::
00124 ns_add_shader(const Filename &orig_filename, Shader *shader) {
00125   Filename filename;
00126   resolve_filename(filename, orig_filename);
00127 
00128   LightMutexHolder holder(_lock);
00129   // We blow away whatever shader was there previously, if any.
00130   _shaders[filename] = shader;
00131 }
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //     Function: ShaderPool::ns_release_shader
00135 //       Access: Private
00136 //  Description: The nonstatic implementation of release_shader().
00137 ////////////////////////////////////////////////////////////////////
00138 void ShaderPool::
00139 ns_release_shader(const Filename &filename) {
00140   LightMutexHolder holder(_lock);
00141 
00142   Shaders::iterator ti;
00143   ti = _shaders.find(filename);
00144   if (ti != _shaders.end()) {
00145     _shaders.erase(ti);
00146   }
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: ShaderPool::ns_release_all_shaders
00151 //       Access: Private
00152 //  Description: The nonstatic implementation of release_all_shaders().
00153 ////////////////////////////////////////////////////////////////////
00154 void ShaderPool::
00155 ns_release_all_shaders() {
00156   LightMutexHolder holder(_lock);
00157 
00158   _shaders.clear();
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////
00162 //     Function: ShaderPool::ns_garbage_collect
00163 //       Access: Private
00164 //  Description: The nonstatic implementation of garbage_collect().
00165 ////////////////////////////////////////////////////////////////////
00166 int ShaderPool::
00167 ns_garbage_collect() {
00168   LightMutexHolder holder(_lock);
00169 
00170   int num_released = 0;
00171   Shaders new_set;
00172 
00173   Shaders::iterator ti;
00174   for (ti = _shaders.begin(); ti != _shaders.end(); ++ti) {
00175     CPT(Shader) shader = (*ti).second;
00176     if (shader->get_ref_count() == 1) {
00177 /*
00178       if (shader_cat.is_debug()) {
00179         shader_cat.debug()
00180           << "Releasing " << (*ti).first << "\n";
00181       }
00182 */
00183       num_released++;
00184     } else {
00185       new_set.insert(new_set.end(), *ti);
00186     }
00187   }
00188 
00189   _shaders.swap(new_set);
00190   return num_released;
00191 }
00192 
00193 ////////////////////////////////////////////////////////////////////
00194 //     Function: ShaderPool::ns_list_contents
00195 //       Access: Private
00196 //  Description: The nonstatic implementation of list_contents().
00197 ////////////////////////////////////////////////////////////////////
00198 void ShaderPool::
00199 ns_list_contents(ostream &out) const {
00200   LightMutexHolder holder(_lock);
00201 
00202   out << _shaders.size() << " shaders:\n";
00203   Shaders::const_iterator ti;
00204   for (ti = _shaders.begin(); ti != _shaders.end(); ++ti) {
00205     CPT(Shader) shader = (*ti).second;
00206     out << "  " << (*ti).first
00207         << " (count = " << shader->get_ref_count() << ")\n";
00208   }
00209 }
00210 
00211 
00212 ////////////////////////////////////////////////////////////////////
00213 //     Function: ShaderPool::resolve_filename
00214 //       Access: Private
00215 //  Description: Searches for the indicated filename along the
00216 //               model path.
00217 ////////////////////////////////////////////////////////////////////
00218 void ShaderPool::
00219 resolve_filename(Filename &new_filename, const Filename &orig_filename) {
00220   new_filename = orig_filename;
00221   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00222   vfs->resolve_filename(new_filename, get_model_path());
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: ShaderPool::get_ptr
00227 //       Access: Private, Static
00228 //  Description: Initializes and/or returns the global pointer to the
00229 //               one ShaderPool object in the system.
00230 ////////////////////////////////////////////////////////////////////
00231 ShaderPool *ShaderPool::
00232 get_ptr() {
00233   if (_global_ptr == (ShaderPool *)NULL) {
00234     _global_ptr = new ShaderPool;
00235   }
00236   return _global_ptr;
00237 }
 All Classes Functions Variables Enumerations