1//
2// Copyright (c) 2002-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// Shader.cpp: Implements the gl::Shader class and its  derived classes
8// VertexShader and FragmentShader. Implements GL shader objects and related
9// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
10
11#include "libGLESv2/Shader.h"
12#include "libGLESv2/renderer/Renderer.h"
13#include "libGLESv2/renderer/ShaderImpl.h"
14#include "libGLESv2/Constants.h"
15#include "libGLESv2/ResourceManager.h"
16
17#include "common/utilities.h"
18
19#include "GLSLANG/ShaderLang.h"
20
21#include <sstream>
22
23namespace gl
24{
25
26Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle)
27    : mShader(impl),
28      mType(type),
29      mHandle(handle),
30      mResourceManager(manager),
31      mRefCount(0),
32      mDeleteStatus(false),
33      mCompiled(false)
34{
35    ASSERT(impl);
36}
37
38Shader::~Shader()
39{
40}
41
42GLuint Shader::getHandle() const
43{
44    return mHandle;
45}
46
47void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
48{
49    std::ostringstream stream;
50
51    for (int i = 0; i < count; i++)
52    {
53        stream << string[i];
54    }
55
56    mSource = stream.str();
57}
58
59int Shader::getInfoLogLength() const
60{
61    return  mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1);
62}
63
64void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
65{
66    int index = 0;
67
68    if (bufSize > 0)
69    {
70        index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length()));
71        memcpy(infoLog, mShader->getInfoLog().c_str(), index);
72
73        infoLog[index] = '\0';
74    }
75
76    if (length)
77    {
78        *length = index;
79    }
80}
81
82int Shader::getSourceLength() const
83{
84    return mSource.empty() ? 0 : (mSource.length() + 1);
85}
86
87int Shader::getTranslatedSourceLength() const
88{
89    return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1);
90}
91
92void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
93{
94    int index = 0;
95
96    if (bufSize > 0)
97    {
98        index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
99        memcpy(buffer, source.c_str(), index);
100
101        buffer[index] = '\0';
102    }
103
104    if (length)
105    {
106        *length = index;
107    }
108}
109
110void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
111{
112    getSourceImpl(mSource, bufSize, length, buffer);
113}
114
115void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
116{
117    getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
118}
119
120void Shader::compile()
121{
122    mCompiled = mShader->compile(mSource);
123}
124
125void Shader::addRef()
126{
127    mRefCount++;
128}
129
130void Shader::release()
131{
132    mRefCount--;
133
134    if (mRefCount == 0 && mDeleteStatus)
135    {
136        mResourceManager->deleteShader(mHandle);
137    }
138}
139
140unsigned int Shader::getRefCount() const
141{
142    return mRefCount;
143}
144
145bool Shader::isFlaggedForDeletion() const
146{
147    return mDeleteStatus;
148}
149
150void Shader::flagForDeletion()
151{
152    mDeleteStatus = true;
153}
154
155const std::vector<gl::PackedVarying> &Shader::getVaryings() const
156{
157    return mShader->getVaryings();
158}
159
160const std::vector<sh::Uniform> &Shader::getUniforms() const
161{
162    return mShader->getUniforms();
163}
164
165const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
166{
167    return mShader->getInterfaceBlocks();
168}
169
170const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
171{
172    return mShader->getActiveAttributes();
173}
174
175const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const
176{
177    return mShader->getActiveOutputVariables();
178}
179
180std::vector<gl::PackedVarying> &Shader::getVaryings()
181{
182    return mShader->getVaryings();
183}
184
185std::vector<sh::Uniform> &Shader::getUniforms()
186{
187    return mShader->getUniforms();
188}
189
190std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
191{
192    return mShader->getInterfaceBlocks();
193}
194
195std::vector<sh::Attribute> &Shader::getActiveAttributes()
196{
197    return mShader->getActiveAttributes();
198}
199
200std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
201{
202    return mShader->getActiveOutputVariables();
203}
204
205}
206