Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/canvas/WebGL2ContextUniforms.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "WebGL2Context.h"
7
8
#include "GLContext.h"
9
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
10
#include "mozilla/RefPtr.h"
11
#include "WebGLBuffer.h"
12
#include "WebGLContext.h"
13
#include "WebGLProgram.h"
14
#include "WebGLUniformLocation.h"
15
#include "WebGLVertexArray.h"
16
#include "WebGLVertexAttribData.h"
17
18
namespace mozilla {
19
20
// -------------------------------------------------------------------------
21
// Uniforms
22
23
void
24
WebGLContext::Uniform1ui(WebGLUniformLocation* loc, GLuint v0)
25
0
{
26
0
    const FuncScope funcScope(*this, "uniform1ui");
27
0
    if (!ValidateUniformSetter(loc, 1, LOCAL_GL_UNSIGNED_INT))
28
0
        return;
29
0
30
0
    gl->fUniform1ui(loc->mLoc, v0);
31
0
}
32
33
void
34
WebGLContext::Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1)
35
0
{
36
0
    const FuncScope funcScope(*this, "uniform2ui");
37
0
    if (!ValidateUniformSetter(loc, 2, LOCAL_GL_UNSIGNED_INT))
38
0
        return;
39
0
40
0
    gl->fUniform2ui(loc->mLoc, v0, v1);
41
0
}
42
43
void
44
WebGLContext::Uniform3ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2)
45
0
{
46
0
    const FuncScope funcScope(*this, "uniform3ui");
47
0
    if (!ValidateUniformSetter(loc, 3, LOCAL_GL_UNSIGNED_INT))
48
0
        return;
49
0
50
0
    gl->fUniform3ui(loc->mLoc, v0, v1, v2);
51
0
}
52
53
void
54
WebGLContext::Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2,
55
                         GLuint v3)
56
0
{
57
0
    const FuncScope funcScope(*this, "uniform4ui");
58
0
    if (!ValidateUniformSetter(loc, 4, LOCAL_GL_UNSIGNED_INT))
59
0
        return;
60
0
61
0
    gl->fUniform4ui(loc->mLoc, v0, v1, v2, v3);
62
0
}
63
64
// -------------------------------------------------------------------------
65
// Uniform Buffer Objects and Transform Feedback Buffers
66
67
void
68
WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target, GLuint index,
69
                                   JS::MutableHandleValue retval, ErrorResult& out_error)
70
0
{
71
0
    const FuncScope funcScope(*this, "getIndexedParameter");
72
0
    retval.set(JS::NullValue());
73
0
    if (IsContextLost())
74
0
        return;
75
0
76
0
    const std::vector<IndexedBufferBinding>* bindings;
77
0
    switch (target) {
78
0
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
79
0
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START:
80
0
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
81
0
        bindings = &(mBoundTransformFeedback->mIndexedBindings);
82
0
        break;
83
0
84
0
    case LOCAL_GL_UNIFORM_BUFFER_BINDING:
85
0
    case LOCAL_GL_UNIFORM_BUFFER_START:
86
0
    case LOCAL_GL_UNIFORM_BUFFER_SIZE:
87
0
        bindings = &mIndexedUniformBufferBindings;
88
0
        break;
89
0
90
0
    default:
91
0
        ErrorInvalidEnumInfo("target", target);
92
0
        return;
93
0
    }
94
0
95
0
    if (index >= bindings->size()) {
96
0
        ErrorInvalidValue("`index` must be < %s.",
97
0
                          "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
98
0
        return;
99
0
    }
100
0
    const auto& binding = (*bindings)[index];
101
0
102
0
    JS::Value ret = JS::NullValue();
103
0
104
0
    switch (target) {
105
0
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
106
0
    case LOCAL_GL_UNIFORM_BUFFER_BINDING:
107
0
        if (binding.mBufferBinding) {
108
0
            ret = WebGLObjectAsJSValue(cx, binding.mBufferBinding.get(), out_error);
109
0
        }
110
0
        break;
111
0
112
0
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START:
113
0
    case LOCAL_GL_UNIFORM_BUFFER_START:
114
0
        ret = JS::NumberValue(binding.mRangeStart);
115
0
        break;
116
0
117
0
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
118
0
    case LOCAL_GL_UNIFORM_BUFFER_SIZE:
119
0
        ret = JS::NumberValue(binding.mRangeSize);
120
0
        break;
121
0
    }
122
0
123
0
    retval.set(ret);
124
0
}
125
126
void
127
WebGL2Context::GetUniformIndices(const WebGLProgram& program,
128
                                 const dom::Sequence<nsString>& uniformNames,
129
                                 dom::Nullable< nsTArray<GLuint> >& retval)
130
0
{
131
0
    const FuncScope funcScope(*this, "getUniformIndices");
132
0
    retval.SetNull();
133
0
    if (IsContextLost())
134
0
        return;
135
0
136
0
    if (!ValidateObject("program", program))
137
0
        return;
138
0
139
0
    if (!uniformNames.Length())
140
0
        return;
141
0
142
0
    program.GetUniformIndices(uniformNames, retval);
143
0
}
144
145
void
146
WebGL2Context::GetActiveUniforms(JSContext* cx, const WebGLProgram& program,
147
                                 const dom::Sequence<GLuint>& uniformIndices,
148
                                 GLenum pname, JS::MutableHandleValue retval)
149
0
{
150
0
    const FuncScope funcScope(*this, "getActiveUniforms");
151
0
    retval.setNull();
152
0
    if (IsContextLost())
153
0
        return;
154
0
155
0
    switch (pname) {
156
0
    case LOCAL_GL_UNIFORM_TYPE:
157
0
    case LOCAL_GL_UNIFORM_SIZE:
158
0
    case LOCAL_GL_UNIFORM_BLOCK_INDEX:
159
0
    case LOCAL_GL_UNIFORM_OFFSET:
160
0
    case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
161
0
    case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
162
0
    case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
163
0
        break;
164
0
165
0
    default:
166
0
        ErrorInvalidEnumInfo("pname", pname);
167
0
        return;
168
0
    }
169
0
170
0
    if (!ValidateObject("program", program))
171
0
        return;
172
0
173
0
    if (!program.IsLinked()) {
174
0
        ErrorInvalidOperation("`program` must be linked.");
175
0
        return;
176
0
    }
177
0
178
0
    const auto& numActiveUniforms = program.LinkInfo()->uniforms.size();
179
0
    for (const auto& curIndex : uniformIndices) {
180
0
        if (curIndex >= numActiveUniforms) {
181
0
            ErrorInvalidValue("Too-large active uniform index queried.");
182
0
            return;
183
0
        }
184
0
    }
185
0
186
0
    const auto& count = uniformIndices.Length();
187
0
188
0
    JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, count));
189
0
    UniquePtr<GLint[]> samples(new GLint[count]);
190
0
    if (!array || !samples) {
191
0
        ErrorOutOfMemory("Failed to allocate buffers.");
192
0
        return;
193
0
    }
194
0
    retval.setObject(*array);
195
0
196
0
    gl->fGetActiveUniformsiv(program.mGLName, count, uniformIndices.Elements(), pname,
197
0
                             samples.get());
198
0
199
0
    switch (pname) {
200
0
    case LOCAL_GL_UNIFORM_TYPE:
201
0
    case LOCAL_GL_UNIFORM_SIZE:
202
0
    case LOCAL_GL_UNIFORM_BLOCK_INDEX:
203
0
    case LOCAL_GL_UNIFORM_OFFSET:
204
0
    case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
205
0
    case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
206
0
        for (size_t i = 0; i < count; ++i) {
207
0
            JS::RootedValue value(cx);
208
0
            value = JS::Int32Value(samples[i]);
209
0
            if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE))
210
0
                return;
211
0
        }
212
0
        break;
213
0
    case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
214
0
        for (size_t i = 0; i < count; ++i) {
215
0
            JS::RootedValue value(cx);
216
0
            value = JS::BooleanValue(samples[i]);
217
0
            if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE))
218
0
                return;
219
0
        }
220
0
        break;
221
0
222
0
    default:
223
0
        MOZ_CRASH("Invalid pname");
224
0
    }
225
0
}
226
227
GLuint
228
WebGL2Context::GetUniformBlockIndex(const WebGLProgram& program,
229
                                    const nsAString& uniformBlockName)
230
0
{
231
0
    const FuncScope funcScope(*this, "getUniformBlockIndex");
232
0
    if (IsContextLost())
233
0
        return 0;
234
0
235
0
    if (!ValidateObject("program", program))
236
0
        return 0;
237
0
238
0
    return program.GetUniformBlockIndex(uniformBlockName);
239
0
}
240
241
void
242
WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, const WebGLProgram& program,
243
                                              GLuint uniformBlockIndex, GLenum pname,
244
                                              JS::MutableHandleValue out_retval,
245
                                              ErrorResult& out_error)
246
0
{
247
0
    const FuncScope funcScope(*this, "getActiveUniformBlockParameter");
248
0
    out_retval.setNull();
249
0
    if (IsContextLost())
250
0
        return;
251
0
252
0
    if (!ValidateObject("program", program))
253
0
        return;
254
0
255
0
    switch(pname) {
256
0
    case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
257
0
    case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
258
0
    case LOCAL_GL_UNIFORM_BLOCK_BINDING:
259
0
    case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE:
260
0
    case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
261
0
        out_retval.set(program.GetActiveUniformBlockParam(uniformBlockIndex, pname));
262
0
        return;
263
0
264
0
    case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
265
0
        out_retval.set(program.GetActiveUniformBlockActiveUniforms(cx, uniformBlockIndex,
266
0
                                                                   &out_error));
267
0
        return;
268
0
    }
269
0
270
0
    ErrorInvalidEnumInfo("parameter", pname);
271
0
}
272
273
void
274
WebGL2Context::GetActiveUniformBlockName(const WebGLProgram& program,
275
                                         GLuint uniformBlockIndex, nsAString& retval)
276
0
{
277
0
    const FuncScope funcScope(*this, "getActiveUniformBlockName");
278
0
    retval.SetIsVoid(true);
279
0
    if (IsContextLost())
280
0
        return;
281
0
282
0
    if (!ValidateObject("program", program))
283
0
        return;
284
0
285
0
    program.GetActiveUniformBlockName(uniformBlockIndex, retval);
286
0
}
287
288
void
289
WebGL2Context::UniformBlockBinding(WebGLProgram& program, GLuint uniformBlockIndex,
290
                                   GLuint uniformBlockBinding)
291
0
{
292
0
    const FuncScope funcScope(*this, "uniformBlockBinding");
293
0
    if (IsContextLost())
294
0
        return;
295
0
296
0
    if (!ValidateObject("program", program))
297
0
        return;
298
0
299
0
    program.UniformBlockBinding(uniformBlockIndex, uniformBlockBinding);
300
0
}
301
302
} // namespace mozilla