• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 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 // Context.inl.h: Defines inline functions of gl::Context class
8 // Has to be included after libANGLE/Context.h when using one
9 // of the defined functions
10 
11 #ifndef LIBANGLE_CONTEXT_INL_H_
12 #define LIBANGLE_CONTEXT_INL_H_
13 
14 #include "libANGLE/Context.h"
15 #include "libANGLE/GLES1Renderer.h"
16 #include "libANGLE/renderer/ContextImpl.h"
17 
18 #define ANGLE_HANDLE_ERR(X) \
19     (void)(X);              \
20     return;
21 #define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR)
22 
23 namespace gl
24 {
25 constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
26     {PrimitiveMode::Points, 1},
27     {PrimitiveMode::Lines, 2},
28     {PrimitiveMode::LineLoop, 2},
29     {PrimitiveMode::LineStrip, 2},
30     {PrimitiveMode::Triangles, 3},
31     {PrimitiveMode::TriangleStrip, 3},
32     {PrimitiveMode::TriangleFan, 3},
33     {PrimitiveMode::LinesAdjacency, 2},
34     {PrimitiveMode::LineStripAdjacency, 2},
35     {PrimitiveMode::TrianglesAdjacency, 3},
36     {PrimitiveMode::TriangleStripAdjacency, 3},
37 }};
38 
MarkTransformFeedbackBufferUsage(const Context * context,GLsizei count,GLsizei instanceCount)39 ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
40                                                    GLsizei count,
41                                                    GLsizei instanceCount)
42 {
43     if (context->getStateCache().isTransformFeedbackActiveUnpaused())
44     {
45         TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
46         transformFeedback->onVerticesDrawn(context, count, instanceCount);
47     }
48 }
49 
MarkShaderStorageUsage(const Context * context)50 ANGLE_INLINE void MarkShaderStorageUsage(const Context *context)
51 {
52     for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices())
53     {
54         Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
55         if (buffer)
56         {
57             buffer->onDataChanged();
58         }
59     }
60 
61     for (size_t index : context->getStateCache().getActiveImageUnitIndices())
62     {
63         const ImageUnit &imageUnit = context->getState().getImageUnit(index);
64         const Texture *texture     = imageUnit.texture.get();
65         if (texture)
66         {
67             texture->onStateChange(angle::SubjectMessage::ContentsChanged);
68         }
69     }
70 }
71 
72 // Return true if the draw is a no-op, else return false.
73 //  If there is no active program for the vertex or fragment shader stages, the results of vertex
74 //  and fragment shader execution will respectively be undefined. However, this is not
75 //  an error. ANGLE will treat this as a no-op.
76 //  A no-op draw occurs if the count of vertices is less than the minimum required to
77 //  have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
noopDraw(PrimitiveMode mode,GLsizei count)78 ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const
79 {
80     // Make sure any pending link is done before checking whether draw is allowed.
81     mState.ensureNoPendingLink(this);
82 
83     if (!mStateCache.getCanDraw())
84     {
85         return true;
86     }
87 
88     return count < kMinimumPrimitiveCounts[mode];
89 }
90 
noopMultiDraw(GLsizei drawcount)91 ANGLE_INLINE bool Context::noopMultiDraw(GLsizei drawcount) const
92 {
93     return drawcount == 0 || !mStateCache.getCanDraw();
94 }
95 
syncAllDirtyBits(Command command)96 ANGLE_INLINE angle::Result Context::syncAllDirtyBits(Command command)
97 {
98     constexpr state::DirtyBits kAllDirtyBits                 = state::DirtyBits().set();
99     constexpr state::ExtendedDirtyBits kAllExtendedDirtyBits = state::ExtendedDirtyBits().set();
100     const state::DirtyBits dirtyBits                         = mState.getDirtyBits();
101     const state::ExtendedDirtyBits extendedDirtyBits         = mState.getExtendedDirtyBits();
102     ANGLE_TRY(mImplementation->syncState(this, dirtyBits, kAllDirtyBits, extendedDirtyBits,
103                                          kAllExtendedDirtyBits, command));
104     mState.clearDirtyBits();
105     mState.clearExtendedDirtyBits();
106     return angle::Result::Continue;
107 }
108 
syncDirtyBits(const state::DirtyBits bitMask,const state::ExtendedDirtyBits extendedBitMask,Command command)109 ANGLE_INLINE angle::Result Context::syncDirtyBits(const state::DirtyBits bitMask,
110                                                   const state::ExtendedDirtyBits extendedBitMask,
111                                                   Command command)
112 {
113     const state::DirtyBits dirtyBits = (mState.getDirtyBits() & bitMask);
114     const state::ExtendedDirtyBits extendedDirtyBits =
115         (mState.getExtendedDirtyBits() & extendedBitMask);
116     ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, extendedDirtyBits,
117                                          extendedBitMask, command));
118     mState.clearDirtyBits(dirtyBits);
119     mState.clearExtendedDirtyBits(extendedDirtyBits);
120     return angle::Result::Continue;
121 }
122 
syncDirtyObjects(const state::DirtyObjects & objectMask,Command command)123 ANGLE_INLINE angle::Result Context::syncDirtyObjects(const state::DirtyObjects &objectMask,
124                                                      Command command)
125 {
126     return mState.syncDirtyObjects(this, objectMask, command);
127 }
128 
prepareForDraw(PrimitiveMode mode)129 ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
130 {
131     if (mGLES1Renderer)
132     {
133         ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState, getMutableGLES1State()));
134     }
135 
136     ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw));
137     ASSERT(!isRobustResourceInitEnabled() ||
138            !mState.getDrawFramebuffer()->hasResourceThatNeedsInit());
139     return syncAllDirtyBits(Command::Draw);
140 }
141 
drawArrays(PrimitiveMode mode,GLint first,GLsizei count)142 ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
143 {
144     // No-op if count draws no primitives for given mode
145     if (noopDraw(mode, count))
146     {
147         ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
148         return;
149     }
150 
151     ANGLE_CONTEXT_TRY(prepareForDraw(mode));
152     ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
153     MarkTransformFeedbackBufferUsage(this, count, 1);
154 }
155 
drawElements(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices)156 ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
157                                         GLsizei count,
158                                         DrawElementsType type,
159                                         const void *indices)
160 {
161     // No-op if count draws no primitives for given mode
162     if (noopDraw(mode, count))
163     {
164         ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
165         return;
166     }
167 
168     ANGLE_CONTEXT_TRY(prepareForDraw(mode));
169     ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
170 }
171 
onBufferBindingChange(Context * context)172 ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context)
173 {
174     updateBasicDrawStatesError();
175     updateBasicDrawElementsError();
176 }
177 
bindBuffer(BufferBinding target,BufferID buffer)178 ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer)
179 {
180     Buffer *bufferObject =
181         mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
182 
183     // Early return if rebinding the same buffer
184     if (bufferObject == mState.getTargetBuffer(target))
185     {
186         return;
187     }
188 
189     mState.setBufferBinding(this, target, bufferObject);
190     mStateCache.onBufferBindingChange(this);
191 
192     if (bufferObject)
193     {
194         bufferObject->onBind(this, target);
195     }
196 }
197 
uniform1f(UniformLocation location,GLfloat x)198 ANGLE_INLINE void Context::uniform1f(UniformLocation location, GLfloat x)
199 {
200     Program *program = getActiveLinkedProgram();
201     program->getExecutable().setUniform1fv(location, 1, &x);
202 }
203 
uniform1fv(UniformLocation location,GLsizei count,const GLfloat * v)204 ANGLE_INLINE void Context::uniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
205 {
206     Program *program = getActiveLinkedProgram();
207     program->getExecutable().setUniform1fv(location, count, v);
208 }
209 
setUniform1iImpl(Program * program,UniformLocation location,GLsizei count,const GLint * v)210 ANGLE_INLINE void Context::setUniform1iImpl(Program *program,
211                                             UniformLocation location,
212                                             GLsizei count,
213                                             const GLint *v)
214 {
215     program->getExecutable().setUniform1iv(this, location, count, v);
216 }
217 
uniform1i(UniformLocation location,GLint x)218 ANGLE_INLINE void Context::uniform1i(UniformLocation location, GLint x)
219 {
220     Program *program = getActiveLinkedProgram();
221     setUniform1iImpl(program, location, 1, &x);
222 }
223 
uniform1iv(UniformLocation location,GLsizei count,const GLint * v)224 ANGLE_INLINE void Context::uniform1iv(UniformLocation location, GLsizei count, const GLint *v)
225 {
226     Program *program = getActiveLinkedProgram();
227     setUniform1iImpl(program, location, count, v);
228 }
229 
uniform2f(UniformLocation location,GLfloat x,GLfloat y)230 ANGLE_INLINE void Context::uniform2f(UniformLocation location, GLfloat x, GLfloat y)
231 {
232     GLfloat xy[2]    = {x, y};
233     Program *program = getActiveLinkedProgram();
234     program->getExecutable().setUniform2fv(location, 1, xy);
235 }
236 
uniform2fv(UniformLocation location,GLsizei count,const GLfloat * v)237 ANGLE_INLINE void Context::uniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
238 {
239     Program *program = getActiveLinkedProgram();
240     program->getExecutable().setUniform2fv(location, count, v);
241 }
242 
uniform2i(UniformLocation location,GLint x,GLint y)243 ANGLE_INLINE void Context::uniform2i(UniformLocation location, GLint x, GLint y)
244 {
245     GLint xy[2]      = {x, y};
246     Program *program = getActiveLinkedProgram();
247     program->getExecutable().setUniform2iv(location, 1, xy);
248 }
249 
uniform2iv(UniformLocation location,GLsizei count,const GLint * v)250 ANGLE_INLINE void Context::uniform2iv(UniformLocation location, GLsizei count, const GLint *v)
251 {
252     Program *program = getActiveLinkedProgram();
253     program->getExecutable().setUniform2iv(location, count, v);
254 }
255 
uniform3f(UniformLocation location,GLfloat x,GLfloat y,GLfloat z)256 ANGLE_INLINE void Context::uniform3f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z)
257 {
258     GLfloat xyz[3]   = {x, y, z};
259     Program *program = getActiveLinkedProgram();
260     program->getExecutable().setUniform3fv(location, 1, xyz);
261 }
262 
uniform3fv(UniformLocation location,GLsizei count,const GLfloat * v)263 ANGLE_INLINE void Context::uniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
264 {
265     Program *program = getActiveLinkedProgram();
266     program->getExecutable().setUniform3fv(location, count, v);
267 }
268 
uniform3i(UniformLocation location,GLint x,GLint y,GLint z)269 ANGLE_INLINE void Context::uniform3i(UniformLocation location, GLint x, GLint y, GLint z)
270 {
271     GLint xyz[3]     = {x, y, z};
272     Program *program = getActiveLinkedProgram();
273     program->getExecutable().setUniform3iv(location, 1, xyz);
274 }
275 
uniform3iv(UniformLocation location,GLsizei count,const GLint * v)276 ANGLE_INLINE void Context::uniform3iv(UniformLocation location, GLsizei count, const GLint *v)
277 {
278     Program *program = getActiveLinkedProgram();
279     program->getExecutable().setUniform3iv(location, count, v);
280 }
281 
uniform4f(UniformLocation location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)282 ANGLE_INLINE void Context::uniform4f(UniformLocation location,
283                                      GLfloat x,
284                                      GLfloat y,
285                                      GLfloat z,
286                                      GLfloat w)
287 {
288     GLfloat xyzw[4]  = {x, y, z, w};
289     Program *program = getActiveLinkedProgram();
290     program->getExecutable().setUniform4fv(location, 1, xyzw);
291 }
292 
uniform4fv(UniformLocation location,GLsizei count,const GLfloat * v)293 ANGLE_INLINE void Context::uniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
294 {
295     Program *program = getActiveLinkedProgram();
296     program->getExecutable().setUniform4fv(location, count, v);
297 }
298 
uniform4i(UniformLocation location,GLint x,GLint y,GLint z,GLint w)299 ANGLE_INLINE void Context::uniform4i(UniformLocation location, GLint x, GLint y, GLint z, GLint w)
300 {
301     GLint xyzw[4]    = {x, y, z, w};
302     Program *program = getActiveLinkedProgram();
303     program->getExecutable().setUniform4iv(location, 1, xyzw);
304 }
305 
uniform4iv(UniformLocation location,GLsizei count,const GLint * v)306 ANGLE_INLINE void Context::uniform4iv(UniformLocation location, GLsizei count, const GLint *v)
307 {
308     Program *program = getActiveLinkedProgram();
309     program->getExecutable().setUniform4iv(location, count, v);
310 }
311 
uniform1ui(UniformLocation location,GLuint v0)312 ANGLE_INLINE void Context::uniform1ui(UniformLocation location, GLuint v0)
313 {
314     Program *program = getActiveLinkedProgram();
315     program->getExecutable().setUniform1uiv(location, 1, &v0);
316 }
317 
uniform2ui(UniformLocation location,GLuint v0,GLuint v1)318 ANGLE_INLINE void Context::uniform2ui(UniformLocation location, GLuint v0, GLuint v1)
319 {
320     Program *program  = getActiveLinkedProgram();
321     const GLuint xy[] = {v0, v1};
322     program->getExecutable().setUniform2uiv(location, 1, xy);
323 }
324 
uniform3ui(UniformLocation location,GLuint v0,GLuint v1,GLuint v2)325 ANGLE_INLINE void Context::uniform3ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2)
326 {
327     Program *program   = getActiveLinkedProgram();
328     const GLuint xyz[] = {v0, v1, v2};
329     program->getExecutable().setUniform3uiv(location, 1, xyz);
330 }
331 
uniform4ui(UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)332 ANGLE_INLINE void Context::uniform4ui(UniformLocation location,
333                                       GLuint v0,
334                                       GLuint v1,
335                                       GLuint v2,
336                                       GLuint v3)
337 {
338     Program *program    = getActiveLinkedProgram();
339     const GLuint xyzw[] = {v0, v1, v2, v3};
340     program->getExecutable().setUniform4uiv(location, 1, xyzw);
341 }
342 
uniform1uiv(UniformLocation location,GLsizei count,const GLuint * value)343 ANGLE_INLINE void Context::uniform1uiv(UniformLocation location, GLsizei count, const GLuint *value)
344 {
345     Program *program = getActiveLinkedProgram();
346     program->getExecutable().setUniform1uiv(location, count, value);
347 }
348 
uniform2uiv(UniformLocation location,GLsizei count,const GLuint * value)349 ANGLE_INLINE void Context::uniform2uiv(UniformLocation location, GLsizei count, const GLuint *value)
350 {
351     Program *program = getActiveLinkedProgram();
352     program->getExecutable().setUniform2uiv(location, count, value);
353 }
354 
uniform3uiv(UniformLocation location,GLsizei count,const GLuint * value)355 ANGLE_INLINE void Context::uniform3uiv(UniformLocation location, GLsizei count, const GLuint *value)
356 {
357     Program *program = getActiveLinkedProgram();
358     program->getExecutable().setUniform3uiv(location, count, value);
359 }
360 
uniform4uiv(UniformLocation location,GLsizei count,const GLuint * value)361 ANGLE_INLINE void Context::uniform4uiv(UniformLocation location, GLsizei count, const GLuint *value)
362 {
363     Program *program = getActiveLinkedProgram();
364     program->getExecutable().setUniform4uiv(location, count, value);
365 }
366 
uniformMatrix2x3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)367 ANGLE_INLINE void Context::uniformMatrix2x3fv(UniformLocation location,
368                                               GLsizei count,
369                                               GLboolean transpose,
370                                               const GLfloat *value)
371 {
372     Program *program = getActiveLinkedProgram();
373     program->getExecutable().setUniformMatrix2x3fv(location, count, transpose, value);
374 }
375 
uniformMatrix3x2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)376 ANGLE_INLINE void Context::uniformMatrix3x2fv(UniformLocation location,
377                                               GLsizei count,
378                                               GLboolean transpose,
379                                               const GLfloat *value)
380 {
381     Program *program = getActiveLinkedProgram();
382     program->getExecutable().setUniformMatrix3x2fv(location, count, transpose, value);
383 }
384 
uniformMatrix2x4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)385 ANGLE_INLINE void Context::uniformMatrix2x4fv(UniformLocation location,
386                                               GLsizei count,
387                                               GLboolean transpose,
388                                               const GLfloat *value)
389 {
390     Program *program = getActiveLinkedProgram();
391     program->getExecutable().setUniformMatrix2x4fv(location, count, transpose, value);
392 }
393 
uniformMatrix4x2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)394 ANGLE_INLINE void Context::uniformMatrix4x2fv(UniformLocation location,
395                                               GLsizei count,
396                                               GLboolean transpose,
397                                               const GLfloat *value)
398 {
399     Program *program = getActiveLinkedProgram();
400     program->getExecutable().setUniformMatrix4x2fv(location, count, transpose, value);
401 }
402 
uniformMatrix3x4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)403 ANGLE_INLINE void Context::uniformMatrix3x4fv(UniformLocation location,
404                                               GLsizei count,
405                                               GLboolean transpose,
406                                               const GLfloat *value)
407 {
408     Program *program = getActiveLinkedProgram();
409     program->getExecutable().setUniformMatrix3x4fv(location, count, transpose, value);
410 }
411 
uniformMatrix4x3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)412 ANGLE_INLINE void Context::uniformMatrix4x3fv(UniformLocation location,
413                                               GLsizei count,
414                                               GLboolean transpose,
415                                               const GLfloat *value)
416 {
417     Program *program = getActiveLinkedProgram();
418     program->getExecutable().setUniformMatrix4x3fv(location, count, transpose, value);
419 }
420 
421 }  // namespace gl
422 
423 #endif  // LIBANGLE_CONTEXT_INL_H_
424