Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shadermanager.cc
Go to the documentation of this file.
1 
19 
20 #include "ion/base/allocatable.h"
21 #include "ion/base/lockguards.h"
25 #include "ion/gfx/shaderprogram.h"
28 
29 namespace ion {
30 namespace gfxutils {
31 
32 namespace {
33 
34 using base::LockGuard;
36 using gfx::ResourceManager;
37 using gfx::Shader;
38 using gfx::ShaderPtr;
39 using gfx::ShaderProgram;
41 
42 } // anonymous namespace
43 
44 
46 class ShaderManager::ShaderManagerData : public base::Allocatable {
47  public:
51  struct ProgramInfo {
52  ProgramInfo() : program(ShaderProgramPtr()) {}
53  explicit ProgramInfo(const ShaderProgramPtr& program_in)
54  : program(program_in) {}
56  ShaderSourceComposerPtr vertex_source_composer;
57  ShaderSourceComposerPtr fragment_source_composer;
58  };
59  typedef base::AllocMap<std::string, ProgramInfo> ProgramMap;
60 
61  explicit ShaderManagerData(const base::Allocatable& owner)
62  : programs_(owner) {}
63  ~ShaderManagerData() override {}
64 
66  void AddProgramInfo(const std::string& name, const ProgramInfo& info) {
67  LockGuard guard(&mutex_);
68  programs_[name] = info;
69  }
70 
73  const ShaderProgramPtr GetShaderProgram(const std::string& name) {
74  LockGuard guard(&mutex_);
75  ProgramMap::iterator it = FindProgramInfo(name);
76  return GetProgramFromInfo(&it);
77  }
78 
79  const std::vector<std::string> GetShaderProgramNames() {
80  std::vector<std::string> names;
81  names.reserve(programs_.size());
82  for (ProgramMap::iterator it = programs_.begin(); it != programs_.end();) {
83  if (GetProgramFromInfo(&it).Get()) {
84  names.push_back(it->first);
85  ++it;
86  }
87  }
88  return names;
89  }
90 
92  const std::string& name, ShaderSourceComposerPtr* vertex_source_composer,
93  ShaderSourceComposerPtr* fragment_source_composer) {
94  ShaderProgramPtr program;
95  LockGuard guard(&mutex_);
96  ProgramMap::iterator it = FindProgramInfo(name);
97  if (it != programs_.end()) {
98  if (vertex_source_composer)
99  *vertex_source_composer = it->second.vertex_source_composer;
100  if (fragment_source_composer)
101  *fragment_source_composer = it->second.fragment_source_composer;
102  } else {
103  if (vertex_source_composer)
104  *vertex_source_composer = NULL;
105  if (fragment_source_composer)
106  *fragment_source_composer = NULL;
107  }
108  }
109 
111  LockGuard guard(&mutex_);
112  for (ProgramMap::iterator it = programs_.begin(); it != programs_.end();) {
113  const ShaderProgramPtr& program = GetProgramFromInfo(&it);
114  if (program.Get()) {
115  const ProgramInfo& info = it->second;
116  DCHECK(program.Get());
117 
118  if (Shader* shader = program->GetVertexShader().Get())
119  shader->SetSource(info.vertex_source_composer->GetSource());
120  if (Shader* shader = program->GetFragmentShader().Get())
121  shader->SetSource(info.fragment_source_composer->GetSource());
122  ++it;
123  }
124  }
125  }
126 
127  void RecreateShaderProgramsThatDependOn(const std::string& dependency) {
128  LockGuard guard(&mutex_);
129  for (ProgramMap::iterator it = programs_.begin(); it != programs_.end();) {
130  const ShaderProgramPtr& program = GetProgramFromInfo(&it);
131  if (program.Get()) {
132  const ProgramInfo& info = it->second;
133  if (info.vertex_source_composer->DependsOn(dependency))
134  if (Shader* shader = program->GetVertexShader().Get())
135  shader->SetSource(info.vertex_source_composer->GetSource());
136  if (info.fragment_source_composer->DependsOn(dependency))
137  if (Shader* shader = program->GetFragmentShader().Get())
138  shader->SetSource(info.fragment_source_composer->GetSource());
139  ++it;
140  }
141  }
142  }
143 
144  private:
148  ProgramMap::iterator FindProgramInfo(const std::string& name) {
149  ProgramMap::iterator it = programs_.find(name);
150  if (!GetProgramFromInfo(&it).Get())
151  it = programs_.end();
152  return it;
153  }
154 
159  const ShaderProgramPtr GetProgramFromInfo(ProgramMap::iterator* it) {
160  ShaderProgramPtr program;
161  if ((*it) != programs_.end()) {
162  program = (*it)->second.program.Acquire();
163  if (!program.Get()) {
166  *it = programs_.erase(*it);
167  }
168  }
169  return program;
170  }
171 
173  ProgramMap programs_;
174 
176  port::Mutex mutex_;
177 };
178 
180  : data_(new(GetAllocator()) ShaderManagerData(*this)) {}
181 
182 ShaderManager::~ShaderManager() {}
183 
185  const std::string& name, const ion::gfx::ShaderInputRegistryPtr& registry,
186  const ShaderSourceComposerPtr& vertex_source_composer,
187  const ShaderSourceComposerPtr& fragment_source_composer) {
190  ion::gfx::ShaderProgram(registry));
191  ShaderManagerData::ProgramInfo info(program);
192  program->SetLabel(name);
193  program->SetVertexShader(
195  Shader(vertex_source_composer->GetSource())));
196  program->GetVertexShader()->SetLabel(name + " vertex shader");
197  program->SetFragmentShader(
199  Shader(fragment_source_composer->GetSource())));
200  program->GetFragmentShader()->SetLabel(name + " fragment shader");
201  info.vertex_source_composer = vertex_source_composer;
202  info.fragment_source_composer = fragment_source_composer;
203  data_->AddProgramInfo(name, info);
204 
205  return program;
206 }
207 
209  const std::string& name) {
210  return data_->GetShaderProgram(name);
211 }
212 
213 const std::vector<std::string> ShaderManager::GetShaderProgramNames() {
214  return data_->GetShaderProgramNames();
215 }
216 
218  const std::string& name,
219  ShaderSourceComposerPtr* vertex_source_composer,
220  ShaderSourceComposerPtr* fragment_source_composer) {
221  data_->GetShaderProgramComposers(name, vertex_source_composer,
222  fragment_source_composer);
223 }
224 
226  data_->RecreateAllShaderPrograms();
227 }
228 
230  const std::string& dependency) {
231  data_->RecreateShaderProgramsThatDependOn(dependency);
232 }
233 
234 } // namespace gfxutils
235 } // namespace ion
void RecreateShaderProgramsThatDependOn(const std::string &dependency)
Reconstructs all shaders that depend on the named dependency.
A ShaderProgram represents an OpenGL shader program that can be applied to shapes.
Definition: shaderprogram.h:38
#define DCHECK(expr)
Definition: logging.h:331
GenericLockGuard< port::Mutex > LockGuard
Convenient typedefs for ion::port::Mutex.
Definition: lockguards.h:192
const gfx::ShaderProgramPtr CreateShaderProgram(const std::string &name, const ion::gfx::ShaderInputRegistryPtr &registry, const ShaderSourceComposerPtr &vertex_source_composer, const ShaderSourceComposerPtr &fragment_source_composer)
Creates and returns a ShaderProgram with the passed name using the passed composers and registry...
void RecreateAllShaderPrograms()
Reconstructs all shaders from their composers.
base::WeakReferentPtr< ShaderProgram > ShaderProgramWeakPtr
Definition: shaderprogram.h:34
const AllocatorPtr & GetAllocatorForLifetime(AllocationLifetime lifetime) const
Convenience function that returns the Allocator to use to allocate an object with a specific lifetime...
Definition: allocatable.h:78
const std::vector< std::string > GetShaderProgramNames()
Gets a vector of the names of the shader programs created through the manager.
std::string name
Definition: printer.cc:324
void GetShaderProgramComposers(const std::string &name, ShaderSourceComposerPtr *vertex_source_composer, ShaderSourceComposerPtr *fragment_source_composer)
Gets the composers used to construct the named program's shaders.
base::ReferentPtr< ShaderProgram >::Type ShaderProgramPtr
base::ReferentPtr< Shader >::Type ShaderPtr
Convenience typedef for shared pointers to Shaders.
base::ReferentPtr< GraphicsManager >::Type GraphicsManagerPtr
Convenience typedef for shared pointer to a GraphicsManager.
const gfx::ShaderProgramPtr GetShaderProgram(const std::string &name)
Returns a ReferentPtr to a ShaderProgram that has the passed name.
port::Mutex mutex_
Protects shared access to the Allocator and FT_Library.
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
base::ReferentPtr< ShaderSourceComposer >::Type ShaderSourceComposerPtr
kMediumTerm is used for objects that don't fall into the kShortTerm or kLongTerm categories.
Definition: allocator.h:40