blob: f9fcad38a46e126c8aceefdb6583c25d28d9f207 [file] [log] [blame]
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
8
9#include "libGLESv2/renderer/ProgramImpl.h"
10
11#include "common/utilities.h"
12#include "libGLESv2/main.h"
13
14namespace rx
15{
16
17namespace
18{
19
20unsigned int ParseAndStripArrayIndex(std::string* name)
21{
22 unsigned int subscript = GL_INVALID_INDEX;
23
24 // Strip any trailing array operator and retrieve the subscript
25 size_t open = name->find_last_of('[');
26 size_t close = name->find_last_of(']');
27 if (open != std::string::npos && close == name->length() - 1)
28 {
29 subscript = atoi(name->substr(open + 1).c_str());
30 name->erase(open);
31 }
32
33 return subscript;
34}
35
36}
37
38ProgramImpl::~ProgramImpl()
39{
40 // Ensure that reset was called by the inherited class during destruction
41 ASSERT(mUniformIndex.size() == 0);
42}
43
44gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
45{
46 ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
47 return mUniforms[mUniformIndex[location].index];
48}
49
50gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
51{
52 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
53 {
54 if (mUniforms[uniformIndex]->name == name)
55 {
56 return mUniforms[uniformIndex];
57 }
58 }
59
60 return NULL;
61}
62
63gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const
64{
65 ASSERT(blockIndex < mUniformBlocks.size());
66 return mUniformBlocks[blockIndex];
67}
68
69GLint ProgramImpl::getUniformLocation(std::string name)
70{
71 unsigned int subscript = ParseAndStripArrayIndex(&name);
72
73 unsigned int numUniforms = mUniformIndex.size();
74 for (unsigned int location = 0; location < numUniforms; location++)
75 {
76 if (mUniformIndex[location].name == name)
77 {
78 const int index = mUniformIndex[location].index;
79 const bool isArray = mUniforms[index]->isArray();
80
81 if ((isArray && mUniformIndex[location].element == subscript) ||
82 (subscript == GL_INVALID_INDEX))
83 {
84 return location;
85 }
86 }
87 }
88
89 return -1;
90}
91
92GLuint ProgramImpl::getUniformIndex(std::string name)
93{
94 unsigned int subscript = ParseAndStripArrayIndex(&name);
95
96 // The app is not allowed to specify array indices other than 0 for arrays of basic types
97 if (subscript != 0 && subscript != GL_INVALID_INDEX)
98 {
99 return GL_INVALID_INDEX;
100 }
101
102 unsigned int numUniforms = mUniforms.size();
103 for (unsigned int index = 0; index < numUniforms; index++)
104 {
105 if (mUniforms[index]->name == name)
106 {
107 if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
108 {
109 return index;
110 }
111 }
112 }
113
114 return GL_INVALID_INDEX;
115}
116
117GLuint ProgramImpl::getUniformBlockIndex(std::string name) const
118{
119 unsigned int subscript = ParseAndStripArrayIndex(&name);
120
121 unsigned int numUniformBlocks = mUniformBlocks.size();
122 for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
123 {
124 const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
125 if (uniformBlock.name == name)
126 {
127 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
128 if (subscript == uniformBlock.elementIndex || arrayElementZero)
129 {
130 return blockIndex;
131 }
132 }
133 }
134
135 return GL_INVALID_INDEX;
136}
137
138void ProgramImpl::reset()
139{
140 SafeDeleteContainer(mUniforms);
141 mUniformIndex.clear();
142 SafeDeleteContainer(mUniformBlocks);
143 mTransformFeedbackLinkedVaryings.clear();
144}
145
146}