15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "gpu/command_buffer/client/program_info_manager.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/synchronization/lock.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NonCachedProgramInfoManager : public ProgramInfoManager {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NonCachedProgramInfoManager();
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NonCachedProgramInfoManager();
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CreateInfo(GLuint program) OVERRIDE;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DeleteInfo(GLuint program) OVERRIDE;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetProgramiv(GLES2Implementation* gl,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GLuint program,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GLenum pname,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GLint* params) OVERRIDE;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual GLint GetAttribLocation(GLES2Implementation* gl,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GLuint program,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const char* name) OVERRIDE;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual GLint GetUniformLocation(GLES2Implementation* gl,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GLuint program,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const char* name) OVERRIDE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetActiveAttrib(GLES2Implementation* gl,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLuint program,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLuint index,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLsizei bufsize,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLsizei* length,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLint* size,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLenum* type,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               char* name) OVERRIDE;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetActiveUniform(GLES2Implementation* gl,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLuint program,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLuint index,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLsizei bufsize,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLsizei* length,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLint* size,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLenum* type,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                char* name) OVERRIDE;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NonCachedProgramInfoManager::NonCachedProgramInfoManager() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NonCachedProgramInfoManager::~NonCachedProgramInfoManager() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonCachedProgramInfoManager::CreateInfo(GLuint /* program */) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonCachedProgramInfoManager::DeleteInfo(GLuint /* program */) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NonCachedProgramInfoManager::GetProgramiv(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* /* gl */,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint /* program */,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum /* pname */,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint* /* params */) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLint NonCachedProgramInfoManager::GetAttribLocation(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl, GLuint program, const char* name) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetAttribLocationHelper(program, name);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLint NonCachedProgramInfoManager::GetUniformLocation(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl, GLuint program, const char* name) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetUniformLocationHelper(program, name);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NonCachedProgramInfoManager::GetActiveAttrib(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint* size, GLenum* type, char* name) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetActiveAttribHelper(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      program, index, bufsize, length, size, type, name);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NonCachedProgramInfoManager::GetActiveUniform(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint* size, GLenum* type, char* name) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetActiveUniformHelper(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      program, index, bufsize, length, size, type, name);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CachedProgramInfoManager : public ProgramInfoManager {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CachedProgramInfoManager();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CachedProgramInfoManager();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CreateInfo(GLuint program) OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DeleteInfo(GLuint program) OVERRIDE;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetProgramiv(GLES2Implementation* gl,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GLuint program,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GLenum pname,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GLint* params) OVERRIDE;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual GLint GetAttribLocation(GLES2Implementation* gl,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GLuint program,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const char* name) OVERRIDE;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual GLint GetUniformLocation(GLES2Implementation* gl,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GLuint program,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const char* name) OVERRIDE;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetActiveAttrib(GLES2Implementation* gl,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLuint program,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLuint index,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLsizei bufsize,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLsizei* length,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLint* size,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GLenum* type,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               char* name) OVERRIDE;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetActiveUniform(GLES2Implementation* gl,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLuint program,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLuint index,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLsizei bufsize,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLsizei* length,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLint* size,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GLenum* type,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                char* name) OVERRIDE;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Program {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct UniformInfo {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UniformInfo(GLsizei _size, GLenum _type, const std::string& _name);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLsizei size;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLenum type;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool is_array;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string name;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<GLint> element_locations;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    struct VertexAttrib {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GLint _location)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          : size(_size),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            type(_type),
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            location(_location),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name(_name) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLsizei size;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLenum type;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLint location;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string name;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef std::vector<UniformInfo> UniformInfoVector;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    typedef std::vector<VertexAttrib> AttribInfoVector;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Program();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AttribInfoVector& GetAttribInfos() const {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return attrib_infos_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const VertexAttrib* GetAttribInfo(GLint index) const {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return (static_cast<size_t>(index) < attrib_infos_.size()) ?
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         &attrib_infos_[index] : NULL;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint GetAttribLocation(const std::string& name) const;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const UniformInfo* GetUniformInfo(GLint index) const {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return (static_cast<size_t>(index) < uniform_infos_.size()) ?
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         &uniform_infos_[index] : NULL;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Gets the location of a uniform by name.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint GetUniformLocation(const std::string& name) const;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool GetProgramiv(GLenum pname, GLint* params);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Updates the program info after a successful link.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Update(GLES2Implementation* gl, GLuint program);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool cached_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei max_attrib_name_length_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Attrib by index.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AttribInfoVector attrib_infos_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei max_uniform_name_length_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Uniform info by index.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UniformInfoVector uniform_infos_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is true if glLinkProgram was successful last time it was called.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool link_status_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* GetProgramInfo(GLES2Implementation* gl, GLuint program);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gman): Switch to a faster container.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<GLuint, Program> ProgramInfoMap;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramInfoMap program_infos_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  mutable base::Lock lock_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CachedProgramInfoManager::Program::UniformInfo::UniformInfo(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei _size, GLenum _type, const std::string& _name)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : size(_size),
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type(_type),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name(_name) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_array = (!name.empty() && name[name.size() - 1] == ']');
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!(size > 1 && !is_array));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CachedProgramInfoManager::Program::Program()
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cached_(false),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_attrib_name_length_(0),
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_uniform_name_length_(0),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      link_status_(false) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(gman): Add a faster lookup.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLint CachedProgramInfoManager::Program::GetAttribLocation(
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name) const {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const VertexAttrib& info = attrib_infos_[ii];
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info.name == name) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return info.location;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLint CachedProgramInfoManager::Program::GetUniformLocation(
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name) const {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool getting_array_location = false;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t open_pos = std::string::npos;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int index = 0;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GLES2Util::ParseUniformName(
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name, &open_pos, &index, &getting_array_location)) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const UniformInfo& info = uniform_infos_[ii];
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info.name == name ||
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (info.is_array &&
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         info.name.compare(0, info.name.size() - 3, name) == 0)) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return info.element_locations[0];
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (getting_array_location && info.is_array) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Look for an array specification.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t open_pos_2 = info.name.find_last_of('[');
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (open_pos_2 == open_pos &&
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          name.compare(0, open_pos, info.name, 0, open_pos) == 0) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (index >= 0 && index < info.size) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return info.element_locations[index];
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CachedProgramInfoManager::Program::GetProgramiv(
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum pname, GLint* params) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (pname) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_LINK_STATUS:
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *params = link_status_;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_ACTIVE_ATTRIBUTES:
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *params = attrib_infos_.size();
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *params = max_attrib_name_length_;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_ACTIVE_UNIFORMS:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *params = uniform_infos_.size();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *params = max_uniform_name_length_;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> static T LocalGetAs(
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<int8>& data, uint32 offset, size_t size) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int8* p = &data[0] + offset;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (offset + size > data.size()) {
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<T>(static_cast<const void*>(p));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CachedProgramInfoManager::Program::Update(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl, GLuint program) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cached_) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int8> result;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gl->GetProgramInfoCHROMIUMHelper(program, &result);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.empty()) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This should only happen on a lost context.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(result.size(), sizeof(ProgramInfoHeader));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>(
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result, 0, sizeof(header));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_status_ = header->link_status != 0;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!link_status_) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrib_infos_.clear();
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uniform_infos_.clear();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_attrib_name_length_ = 0;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_uniform_name_length_ = 0;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProgramInput* inputs = LocalGetAs<const ProgramInput*>(
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result, sizeof(*header),
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProgramInput* input = inputs;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int32* location = LocalGetAs<const int32*>(
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result, input->location_offset, sizeof(int32));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* name_buf = LocalGetAs<const char*>(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result, input->name_offset, input->name_length);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(name_buf, input->name_length);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attrib_infos_.push_back(
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        VertexAttrib(input->size, input->type, name, *location));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_attrib_name_length_ = std::max(
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<GLsizei>(name.size() + 1), max_attrib_name_length_);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++input;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int32* locations = LocalGetAs<const int32*>(
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result, input->location_offset, sizeof(int32) * input->size);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* name_buf = LocalGetAs<const char*>(
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result, input->name_offset, input->name_length);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(name_buf, input->name_length);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UniformInfo info(input->size, input->type, name);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_uniform_name_length_ = std::max(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<GLsizei>(name.size() + 1), max_uniform_name_length_);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int32 jj = 0; jj < input->size; ++jj) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.element_locations.push_back(locations[jj]);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uniform_infos_.push_back(info);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++input;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(header->num_attribs + header->num_uniforms,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                static_cast<uint32>(input - inputs));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cached_ = true;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CachedProgramInfoManager::CachedProgramInfoManager() {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CachedProgramInfoManager::~CachedProgramInfoManager() {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CachedProgramInfoManager::Program*
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CachedProgramInfoManager::GetProgramInfo(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GLES2Implementation* gl, GLuint program) {
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  lock_.AssertAcquired();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramInfoMap::iterator it = program_infos_.find(program);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == program_infos_.end()) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info = &it->second;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->Update(gl, program);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CachedProgramInfoManager::CreateInfo(GLuint program) {
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  program_infos_.erase(program);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::pair<ProgramInfoMap::iterator, bool> result =
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      program_infos_.insert(std::make_pair(program, Program()));
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(result.second);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CachedProgramInfoManager::DeleteInfo(GLuint program) {
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  program_infos_.erase(program);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CachedProgramInfoManager::GetProgramiv(
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) {
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info = GetProgramInfo(gl, program);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!info) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info->GetProgramiv(pname, params);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLint CachedProgramInfoManager::GetAttribLocation(
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl, GLuint program, const char* name) {
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info = GetProgramInfo(gl, program);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return info->GetAttribLocation(name);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetAttribLocationHelper(program, name);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLint CachedProgramInfoManager::GetUniformLocation(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl, GLuint program, const char* name) {
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info = GetProgramInfo(gl, program);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return info->GetUniformLocation(name);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetUniformLocationHelper(program, name);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CachedProgramInfoManager::GetActiveAttrib(
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint* size, GLenum* type, char* name) {
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info = GetProgramInfo(gl, program);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Program::VertexAttrib* attrib_info =
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info->GetAttribInfo(index);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (attrib_info) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (size) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *size = attrib_info->size;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (type) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *type = attrib_info->type;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (length || name) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::max(static_cast<size_t>(0),
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             attrib_info->name.size()));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (length) {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *length = max_size;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (name && bufsize > 0) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          memcpy(name, attrib_info->name.c_str(), max_size);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          name[max_size] = '\0';
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetActiveAttribHelper(
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      program, index, bufsize, length, size, type, name);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CachedProgramInfoManager::GetActiveUniform(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Implementation* gl,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint* size, GLenum* type, char* name) {
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info = GetProgramInfo(gl, program);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Program::UniformInfo* uniform_info = info->GetUniformInfo(index);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (uniform_info) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (size) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *size = uniform_info->size;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (type) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *type = uniform_info->type;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (length || name) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::max(static_cast<size_t>(0),
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             uniform_info->name.size()));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (length) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *length = max_size;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (name && bufsize > 0) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          memcpy(name, uniform_info->name.c_str(), max_size);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          name[max_size] = '\0';
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gl->GetActiveUniformHelper(
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      program, index, bufsize, length, size, type, name);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProgramInfoManager::ProgramInfoManager() {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProgramInfoManager::~ProgramInfoManager() {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProgramInfoManager* ProgramInfoManager::Create(
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool shared_resources_across_processes) {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (shared_resources_across_processes) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new NonCachedProgramInfoManager();
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new CachedProgramInfoManager();
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
527