Home | History | Annotate | Download | only in service
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "gpu/command_buffer/service/shader_manager.h"
      6 
      7 #include <utility>
      8 
      9 #include "base/logging.h"
     10 #include "base/strings/string_util.h"
     11 
     12 namespace gpu {
     13 namespace gles2 {
     14 
     15 Shader::Shader(GLuint service_id, GLenum shader_type)
     16       : use_count_(0),
     17         service_id_(service_id),
     18         shader_type_(shader_type),
     19         valid_(false) {
     20 }
     21 
     22 Shader::~Shader() {
     23 }
     24 
     25 void Shader::IncUseCount() {
     26   ++use_count_;
     27 }
     28 
     29 void Shader::DecUseCount() {
     30   --use_count_;
     31   DCHECK_GE(use_count_, 0);
     32 }
     33 
     34 void Shader::MarkAsDeleted() {
     35   DCHECK_NE(service_id_, 0u);
     36   service_id_ = 0;
     37 }
     38 
     39 void Shader::SetStatus(
     40     bool valid, const char* log, ShaderTranslatorInterface* translator) {
     41   valid_ = valid;
     42   log_info_.reset(log ? new std::string(log) : NULL);
     43   if (translator && valid) {
     44     attrib_map_ = translator->attrib_map();
     45     uniform_map_ = translator->uniform_map();
     46     varying_map_ = translator->varying_map();
     47     name_map_ = translator->name_map();
     48   } else {
     49     attrib_map_.clear();
     50     uniform_map_.clear();
     51     varying_map_.clear();
     52     name_map_.clear();
     53   }
     54   if (valid && source_.get()) {
     55     signature_source_.reset(new std::string(source_->c_str()));
     56   } else {
     57     signature_source_.reset();
     58   }
     59 }
     60 
     61 const Shader::VariableInfo*
     62     Shader::GetAttribInfo(
     63         const std::string& name) const {
     64   VariableMap::const_iterator it = attrib_map_.find(name);
     65   return it != attrib_map_.end() ? &it->second : NULL;
     66 }
     67 
     68 const std::string* Shader::GetAttribMappedName(
     69     const std::string& original_name) const {
     70   for (VariableMap::const_iterator it = attrib_map_.begin();
     71        it != attrib_map_.end(); ++it) {
     72     if (it->second.name == original_name)
     73       return &(it->first);
     74   }
     75   return NULL;
     76 }
     77 
     78 const std::string* Shader::GetOriginalNameFromHashedName(
     79     const std::string& hashed_name) const {
     80   NameMap::const_iterator it = name_map_.find(hashed_name);
     81   if (it != name_map_.end())
     82     return &(it->second);
     83   return NULL;
     84 }
     85 
     86 const Shader::VariableInfo*
     87     Shader::GetUniformInfo(
     88         const std::string& name) const {
     89   VariableMap::const_iterator it = uniform_map_.find(name);
     90   return it != uniform_map_.end() ? &it->second : NULL;
     91 }
     92 
     93 ShaderManager::ShaderManager() {}
     94 
     95 ShaderManager::~ShaderManager() {
     96   DCHECK(shaders_.empty());
     97 }
     98 
     99 void ShaderManager::Destroy(bool have_context) {
    100   while (!shaders_.empty()) {
    101     if (have_context) {
    102       Shader* shader = shaders_.begin()->second.get();
    103       if (!shader->IsDeleted()) {
    104         glDeleteShader(shader->service_id());
    105         shader->MarkAsDeleted();
    106       }
    107     }
    108     shaders_.erase(shaders_.begin());
    109   }
    110 }
    111 
    112 Shader* ShaderManager::CreateShader(
    113     GLuint client_id,
    114     GLuint service_id,
    115     GLenum shader_type) {
    116   std::pair<ShaderMap::iterator, bool> result =
    117       shaders_.insert(std::make_pair(
    118           client_id, scoped_refptr<Shader>(
    119               new Shader(service_id, shader_type))));
    120   DCHECK(result.second);
    121   return result.first->second.get();
    122 }
    123 
    124 Shader* ShaderManager::GetShader(GLuint client_id) {
    125   ShaderMap::iterator it = shaders_.find(client_id);
    126   return it != shaders_.end() ? it->second.get() : NULL;
    127 }
    128 
    129 bool ShaderManager::GetClientId(GLuint service_id, GLuint* client_id) const {
    130   // This doesn't need to be fast. It's only used during slow queries.
    131   for (ShaderMap::const_iterator it = shaders_.begin();
    132        it != shaders_.end(); ++it) {
    133     if (it->second->service_id() == service_id) {
    134       *client_id = it->first;
    135       return true;
    136     }
    137   }
    138   return false;
    139 }
    140 
    141 bool ShaderManager::IsOwned(Shader* shader) {
    142   for (ShaderMap::iterator it = shaders_.begin();
    143        it != shaders_.end(); ++it) {
    144     if (it->second.get() == shader) {
    145       return true;
    146     }
    147   }
    148   return false;
    149 }
    150 
    151 void ShaderManager::RemoveShader(Shader* shader) {
    152   DCHECK(shader);
    153   DCHECK(IsOwned(shader));
    154   if (shader->IsDeleted() && !shader->InUse()) {
    155     for (ShaderMap::iterator it = shaders_.begin();
    156          it != shaders_.end(); ++it) {
    157       if (it->second.get() == shader) {
    158         shaders_.erase(it);
    159         return;
    160       }
    161     }
    162     NOTREACHED();
    163   }
    164 }
    165 
    166 void ShaderManager::MarkAsDeleted(Shader* shader) {
    167   DCHECK(shader);
    168   DCHECK(IsOwned(shader));
    169   shader->MarkAsDeleted();
    170   RemoveShader(shader);
    171 }
    172 
    173 void ShaderManager::UseShader(Shader* shader) {
    174   DCHECK(shader);
    175   DCHECK(IsOwned(shader));
    176   shader->IncUseCount();
    177 }
    178 
    179 void ShaderManager::UnuseShader(Shader* shader) {
    180   DCHECK(shader);
    181   DCHECK(IsOwned(shader));
    182   shader->DecUseCount();
    183   RemoveShader(shader);
    184 }
    185 
    186 }  // namespace gles2
    187 }  // namespace gpu
    188 
    189 
    190