• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 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 // ContextGL:
7 //   OpenGL-specific functionality associated with a GL Context.
8 //
9 
10 #include "libANGLE/renderer/gl/ContextGL.h"
11 
12 #include "libANGLE/Context.h"
13 #include "libANGLE/renderer/OverlayImpl.h"
14 #include "libANGLE/renderer/gl/BufferGL.h"
15 #include "libANGLE/renderer/gl/CompilerGL.h"
16 #include "libANGLE/renderer/gl/FenceNVGL.h"
17 #include "libANGLE/renderer/gl/FramebufferGL.h"
18 #include "libANGLE/renderer/gl/FunctionsGL.h"
19 #include "libANGLE/renderer/gl/MemoryObjectGL.h"
20 #include "libANGLE/renderer/gl/ProgramGL.h"
21 #include "libANGLE/renderer/gl/ProgramPipelineGL.h"
22 #include "libANGLE/renderer/gl/QueryGL.h"
23 #include "libANGLE/renderer/gl/RenderbufferGL.h"
24 #include "libANGLE/renderer/gl/RendererGL.h"
25 #include "libANGLE/renderer/gl/SamplerGL.h"
26 #include "libANGLE/renderer/gl/SemaphoreGL.h"
27 #include "libANGLE/renderer/gl/ShaderGL.h"
28 #include "libANGLE/renderer/gl/StateManagerGL.h"
29 #include "libANGLE/renderer/gl/SyncGL.h"
30 #include "libANGLE/renderer/gl/TextureGL.h"
31 #include "libANGLE/renderer/gl/TransformFeedbackGL.h"
32 #include "libANGLE/renderer/gl/VertexArrayGL.h"
33 
34 namespace rx
35 {
36 
ContextGL(const gl::State & state,gl::ErrorSet * errorSet,const std::shared_ptr<RendererGL> & renderer)37 ContextGL::ContextGL(const gl::State &state,
38                      gl::ErrorSet *errorSet,
39                      const std::shared_ptr<RendererGL> &renderer)
40     : ContextImpl(state, errorSet), mRenderer(renderer)
41 {}
42 
~ContextGL()43 ContextGL::~ContextGL() {}
44 
initialize()45 angle::Result ContextGL::initialize()
46 {
47     return angle::Result::Continue;
48 }
49 
createCompiler()50 CompilerImpl *ContextGL::createCompiler()
51 {
52     return new CompilerGL(getFunctions());
53 }
54 
createShader(const gl::ShaderState & data)55 ShaderImpl *ContextGL::createShader(const gl::ShaderState &data)
56 {
57     const FunctionsGL *functions = getFunctions();
58     GLuint shader                = functions->createShader(ToGLenum(data.getShaderType()));
59 
60     return new ShaderGL(data, shader, mRenderer->getMultiviewImplementationType(), mRenderer);
61 }
62 
createProgram(const gl::ProgramState & data)63 ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
64 {
65     return new ProgramGL(data, getFunctions(), getFeaturesGL(), getStateManager(), mRenderer);
66 }
67 
createFramebuffer(const gl::FramebufferState & data)68 FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data)
69 {
70     const FunctionsGL *funcs = getFunctions();
71 
72     GLuint fbo = 0;
73     funcs->genFramebuffers(1, &fbo);
74 
75     return new FramebufferGL(data, fbo, false, false);
76 }
77 
createTexture(const gl::TextureState & state)78 TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
79 {
80     const FunctionsGL *functions = getFunctions();
81     StateManagerGL *stateManager = getStateManager();
82 
83     GLuint texture = 0;
84     functions->genTextures(1, &texture);
85     stateManager->bindTexture(state.getType(), texture);
86 
87     return new TextureGL(state, texture);
88 }
89 
createRenderbuffer(const gl::RenderbufferState & state)90 RenderbufferImpl *ContextGL::createRenderbuffer(const gl::RenderbufferState &state)
91 {
92     const FunctionsGL *functions = getFunctions();
93     StateManagerGL *stateManager = getStateManager();
94 
95     GLuint renderbuffer = 0;
96     functions->genRenderbuffers(1, &renderbuffer);
97     stateManager->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
98 
99     return new RenderbufferGL(state, renderbuffer);
100 }
101 
createBuffer(const gl::BufferState & state)102 BufferImpl *ContextGL::createBuffer(const gl::BufferState &state)
103 {
104     return new BufferGL(state, getFunctions(), getStateManager());
105 }
106 
createVertexArray(const gl::VertexArrayState & data)107 VertexArrayImpl *ContextGL::createVertexArray(const gl::VertexArrayState &data)
108 {
109     return new VertexArrayGL(data, getFunctions(), getStateManager());
110 }
111 
createQuery(gl::QueryType type)112 QueryImpl *ContextGL::createQuery(gl::QueryType type)
113 {
114     switch (type)
115     {
116         case gl::QueryType::CommandsCompleted:
117             return new SyncQueryGL(type, getFunctions());
118 
119         default:
120             return new StandardQueryGL(type, getFunctions(), getStateManager());
121     }
122 }
123 
createFenceNV()124 FenceNVImpl *ContextGL::createFenceNV()
125 {
126     const FunctionsGL *functions = getFunctions();
127     if (FenceNVGL::Supported(functions))
128     {
129         return new FenceNVGL(functions);
130     }
131     else
132     {
133         ASSERT(FenceNVSyncGL::Supported(functions));
134         return new FenceNVSyncGL(functions);
135     }
136 }
137 
createSync()138 SyncImpl *ContextGL::createSync()
139 {
140     return new SyncGL(getFunctions());
141 }
142 
createTransformFeedback(const gl::TransformFeedbackState & state)143 TransformFeedbackImpl *ContextGL::createTransformFeedback(const gl::TransformFeedbackState &state)
144 {
145     return new TransformFeedbackGL(state, getFunctions(), getStateManager());
146 }
147 
createSampler(const gl::SamplerState & state)148 SamplerImpl *ContextGL::createSampler(const gl::SamplerState &state)
149 {
150     return new SamplerGL(state, getFunctions(), getStateManager());
151 }
152 
createProgramPipeline(const gl::ProgramPipelineState & data)153 ProgramPipelineImpl *ContextGL::createProgramPipeline(const gl::ProgramPipelineState &data)
154 {
155     return new ProgramPipelineGL(data, getFunctions());
156 }
157 
createMemoryObject()158 MemoryObjectImpl *ContextGL::createMemoryObject()
159 {
160     const FunctionsGL *functions = getFunctions();
161 
162     GLuint memoryObject = 0;
163     functions->createMemoryObjectsEXT(1, &memoryObject);
164 
165     return new MemoryObjectGL(memoryObject);
166 }
167 
createSemaphore()168 SemaphoreImpl *ContextGL::createSemaphore()
169 {
170     const FunctionsGL *functions = getFunctions();
171 
172     GLuint semaphore = 0;
173     functions->genSemaphoresEXT(1, &semaphore);
174 
175     return new SemaphoreGL(semaphore);
176 }
177 
createOverlay(const gl::OverlayState & state)178 OverlayImpl *ContextGL::createOverlay(const gl::OverlayState &state)
179 {
180     // Not implemented.
181     return new OverlayImpl(state);
182 }
183 
flush(const gl::Context * context)184 angle::Result ContextGL::flush(const gl::Context *context)
185 {
186     return mRenderer->flush();
187 }
188 
finish(const gl::Context * context)189 angle::Result ContextGL::finish(const gl::Context *context)
190 {
191     return mRenderer->finish();
192 }
193 
setDrawArraysState(const gl::Context * context,GLint first,GLsizei count,GLsizei instanceCount)194 ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *context,
195                                                          GLint first,
196                                                          GLsizei count,
197                                                          GLsizei instanceCount)
198 {
199     if (context->getStateCache().hasAnyActiveClientAttrib())
200     {
201         const gl::State &glState                = context->getState();
202         const gl::ProgramExecutable *executable = getState().getProgramExecutable();
203         const gl::VertexArray *vao              = glState.getVertexArray();
204         const VertexArrayGL *vaoGL              = GetImplAs<VertexArrayGL>(vao);
205 
206         ANGLE_TRY(vaoGL->syncClientSideData(context, executable->getActiveAttribLocationsMask(),
207                                             first, count, instanceCount));
208 
209 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
210         vaoGL->validateState();
211 #endif  // ANGLE_STATE_VALIDATION_ENABLED
212     }
213 
214     const angle::FeaturesGL &features = getFeaturesGL();
215     if (features.setPrimitiveRestartFixedIndexForDrawArrays.enabled)
216     {
217         StateManagerGL *stateManager           = getStateManager();
218         constexpr GLuint primitiveRestartIndex = gl::GetPrimitiveRestartIndexFromType<GLuint>();
219         ANGLE_TRY(stateManager->setPrimitiveRestartIndex(context, primitiveRestartIndex));
220     }
221 
222     return angle::Result::Continue;
223 }
224 
setDrawElementsState(const gl::Context * context,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instanceCount,const void ** outIndices)225 ANGLE_INLINE angle::Result ContextGL::setDrawElementsState(const gl::Context *context,
226                                                            GLsizei count,
227                                                            gl::DrawElementsType type,
228                                                            const void *indices,
229                                                            GLsizei instanceCount,
230                                                            const void **outIndices)
231 {
232     const gl::State &glState                = context->getState();
233     const gl::ProgramExecutable *executable = getState().getProgramExecutable();
234     const gl::VertexArray *vao              = glState.getVertexArray();
235     const gl::StateCache &stateCache        = context->getStateCache();
236 
237     if (stateCache.hasAnyActiveClientAttrib() || vao->getElementArrayBuffer() == nullptr)
238     {
239         const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
240         ANGLE_TRY(vaoGL->syncDrawElementsState(context, executable->getActiveAttribLocationsMask(),
241                                                count, type, indices, instanceCount,
242                                                glState.isPrimitiveRestartEnabled(), outIndices));
243     }
244     else
245     {
246         *outIndices = indices;
247     }
248 
249     const angle::FeaturesGL &features = getFeaturesGL();
250     if (glState.isPrimitiveRestartEnabled() && features.emulatePrimitiveRestartFixedIndex.enabled)
251     {
252         StateManagerGL *stateManager = getStateManager();
253 
254         GLuint primitiveRestartIndex = gl::GetPrimitiveRestartIndex(type);
255         ANGLE_TRY(stateManager->setPrimitiveRestartIndex(context, primitiveRestartIndex));
256     }
257 
258 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
259     const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
260     vaoGL->validateState();
261 #endif  // ANGLE_STATE_VALIDATION_ENABLED
262 
263     return angle::Result::Continue;
264 }
265 
drawArrays(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count)266 angle::Result ContextGL::drawArrays(const gl::Context *context,
267                                     gl::PrimitiveMode mode,
268                                     GLint first,
269                                     GLsizei count)
270 {
271     const gl::Program *program  = context->getState().getProgram();
272     const bool usesMultiview    = program->usesMultiview();
273     const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
274 
275 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
276     validateState();
277 #endif
278 
279     ANGLE_TRY(setDrawArraysState(context, first, count, instanceCount));
280     if (!usesMultiview)
281     {
282         getFunctions()->drawArrays(ToGLenum(mode), first, count);
283     }
284     else
285     {
286         getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count, instanceCount);
287     }
288     return angle::Result::Continue;
289 }
290 
drawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)291 angle::Result ContextGL::drawArraysInstanced(const gl::Context *context,
292                                              gl::PrimitiveMode mode,
293                                              GLint first,
294                                              GLsizei count,
295                                              GLsizei instanceCount)
296 {
297     GLsizei adjustedInstanceCount = instanceCount;
298     const gl::Program *program    = context->getState().getProgram();
299     if (program->usesMultiview())
300     {
301         adjustedInstanceCount *= program->getNumViews();
302     }
303 
304     ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
305     getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count, adjustedInstanceCount);
306     return angle::Result::Continue;
307 }
308 
updateAttributesForBaseInstance(const gl::Program * program,GLuint baseInstance)309 gl::AttributesMask ContextGL::updateAttributesForBaseInstance(const gl::Program *program,
310                                                               GLuint baseInstance)
311 {
312     const gl::ProgramExecutable *executable = getState().getProgramExecutable();
313     gl::AttributesMask attribToUpdateMask;
314 
315     if (baseInstance != 0)
316     {
317         const FunctionsGL *functions = getFunctions();
318         const auto &attribs          = mState.getVertexArray()->getVertexAttributes();
319         const auto &bindings         = mState.getVertexArray()->getVertexBindings();
320         for (GLuint attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
321         {
322             const gl::VertexAttribute &attrib = attribs[attribIndex];
323             const gl::VertexBinding &binding  = bindings[attrib.bindingIndex];
324             if (executable->isAttribLocationActive(attribIndex) && binding.getDivisor() != 0)
325             {
326                 attribToUpdateMask.set(attribIndex);
327                 const char *p             = static_cast<const char *>(attrib.pointer);
328                 const size_t sourceStride = gl::ComputeVertexAttributeStride(attrib, binding);
329                 const void *newPointer    = p + sourceStride * baseInstance;
330 
331                 const BufferGL *buffer = GetImplAs<BufferGL>(binding.getBuffer().get());
332                 // We often stream data from scratch buffers when client side data is being used
333                 // and that information is in VertexArrayGL.
334                 // Assert that the buffer is non-null because this case isn't handled.
335                 ASSERT(buffer);
336                 getStateManager()->bindBuffer(gl::BufferBinding::Array, buffer->getBufferID());
337                 if (attrib.format->isPureInt())
338                 {
339                     functions->vertexAttribIPointer(attribIndex, attrib.format->channelCount,
340                                                     gl::ToGLenum(attrib.format->vertexAttribType),
341                                                     attrib.vertexAttribArrayStride, newPointer);
342                 }
343                 else
344                 {
345                     functions->vertexAttribPointer(attribIndex, attrib.format->channelCount,
346                                                    gl::ToGLenum(attrib.format->vertexAttribType),
347                                                    attrib.format->isNorm(),
348                                                    attrib.vertexAttribArrayStride, newPointer);
349                 }
350             }
351         }
352     }
353 
354     return attribToUpdateMask;
355 }
356 
resetUpdatedAttributes(gl::AttributesMask attribMask)357 void ContextGL::resetUpdatedAttributes(gl::AttributesMask attribMask)
358 {
359     const FunctionsGL *functions = getFunctions();
360     for (size_t attribIndex : attribMask)
361     {
362         const gl::VertexAttribute &attrib =
363             mState.getVertexArray()->getVertexAttributes()[attribIndex];
364         const gl::VertexBinding &binding =
365             (mState.getVertexArray()->getVertexBindings())[attrib.bindingIndex];
366         getStateManager()->bindBuffer(
367             gl::BufferBinding::Array,
368             GetImplAs<BufferGL>(binding.getBuffer().get())->getBufferID());
369         if (attrib.format->isPureInt())
370         {
371             functions->vertexAttribIPointer(static_cast<GLuint>(attribIndex),
372                                             attrib.format->channelCount,
373                                             gl::ToGLenum(attrib.format->vertexAttribType),
374                                             attrib.vertexAttribArrayStride, attrib.pointer);
375         }
376         else
377         {
378             functions->vertexAttribPointer(
379                 static_cast<GLuint>(attribIndex), attrib.format->channelCount,
380                 gl::ToGLenum(attrib.format->vertexAttribType), attrib.format->isNorm(),
381                 attrib.vertexAttribArrayStride, attrib.pointer);
382         }
383     }
384 }
385 
drawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)386 angle::Result ContextGL::drawArraysInstancedBaseInstance(const gl::Context *context,
387                                                          gl::PrimitiveMode mode,
388                                                          GLint first,
389                                                          GLsizei count,
390                                                          GLsizei instanceCount,
391                                                          GLuint baseInstance)
392 {
393     GLsizei adjustedInstanceCount = instanceCount;
394     const gl::Program *program    = context->getState().getProgram();
395     if (program->usesMultiview())
396     {
397         adjustedInstanceCount *= program->getNumViews();
398     }
399 
400     ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
401 
402     const FunctionsGL *functions = getFunctions();
403 
404     if (functions->drawArraysInstancedBaseInstance)
405     {
406         // GL 4.2+ or GL_EXT_base_instance
407         functions->drawArraysInstancedBaseInstance(ToGLenum(mode), first, count,
408                                                    adjustedInstanceCount, baseInstance);
409     }
410     else
411     {
412         // GL 3.3+ or GLES 3.2+
413         // TODO(http://anglebug.com/3910): This is a temporary solution by setting and resetting
414         // pointer offset calling vertexAttribPointer Will refactor stateCache and pass baseInstance
415         // to setDrawArraysState to set pointer offset
416 
417         gl::AttributesMask attribToResetMask =
418             updateAttributesForBaseInstance(program, baseInstance);
419 
420         functions->drawArraysInstanced(ToGLenum(mode), first, count, adjustedInstanceCount);
421 
422         resetUpdatedAttributes(attribToResetMask);
423     }
424 
425     return angle::Result::Continue;
426 }
427 
drawElements(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices)428 angle::Result ContextGL::drawElements(const gl::Context *context,
429                                       gl::PrimitiveMode mode,
430                                       GLsizei count,
431                                       gl::DrawElementsType type,
432                                       const void *indices)
433 {
434     const gl::State &glState    = context->getState();
435     const gl::Program *program  = glState.getProgram();
436     const bool usesMultiview    = program->usesMultiview();
437     const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
438     const void *drawIndexPtr    = nullptr;
439 
440 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
441     validateState();
442 #endif  // ANGLE_STATE_VALIDATION_ENABLED
443 
444     ANGLE_TRY(setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPtr));
445     if (!usesMultiview)
446     {
447         getFunctions()->drawElements(ToGLenum(mode), count, ToGLenum(type), drawIndexPtr);
448     }
449     else
450     {
451         getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type), drawIndexPtr,
452                                               instanceCount);
453     }
454     return angle::Result::Continue;
455 }
456 
drawElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)457 angle::Result ContextGL::drawElementsBaseVertex(const gl::Context *context,
458                                                 gl::PrimitiveMode mode,
459                                                 GLsizei count,
460                                                 gl::DrawElementsType type,
461                                                 const void *indices,
462                                                 GLint baseVertex)
463 {
464     const gl::State &glState    = context->getState();
465     const gl::Program *program  = glState.getProgram();
466     const bool usesMultiview    = program->usesMultiview();
467     const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
468     const void *drawIndexPtr    = nullptr;
469 
470 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
471     validateState();
472 #endif  // ANGLE_STATE_VALIDATION_ENABLED
473 
474     ANGLE_TRY(setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPtr));
475     if (!usesMultiview)
476     {
477         getFunctions()->drawElementsBaseVertex(ToGLenum(mode), count, ToGLenum(type), drawIndexPtr,
478                                                baseVertex);
479     }
480     else
481     {
482         getFunctions()->drawElementsInstancedBaseVertex(ToGLenum(mode), count, ToGLenum(type),
483                                                         drawIndexPtr, instanceCount, baseVertex);
484     }
485     return angle::Result::Continue;
486 }
487 
drawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances)488 angle::Result ContextGL::drawElementsInstanced(const gl::Context *context,
489                                                gl::PrimitiveMode mode,
490                                                GLsizei count,
491                                                gl::DrawElementsType type,
492                                                const void *indices,
493                                                GLsizei instances)
494 {
495     GLsizei adjustedInstanceCount = instances;
496     const gl::Program *program    = context->getState().getProgram();
497     if (program->usesMultiview())
498     {
499         adjustedInstanceCount *= program->getNumViews();
500     }
501     const void *drawIndexPointer = nullptr;
502 
503     ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
504                                    &drawIndexPointer));
505     getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type), drawIndexPointer,
506                                           adjustedInstanceCount);
507     return angle::Result::Continue;
508 }
509 
drawElementsInstancedBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex)510 angle::Result ContextGL::drawElementsInstancedBaseVertex(const gl::Context *context,
511                                                          gl::PrimitiveMode mode,
512                                                          GLsizei count,
513                                                          gl::DrawElementsType type,
514                                                          const void *indices,
515                                                          GLsizei instances,
516                                                          GLint baseVertex)
517 {
518     GLsizei adjustedInstanceCount = instances;
519     const gl::Program *program    = context->getState().getProgram();
520     if (program->usesMultiview())
521     {
522         adjustedInstanceCount *= program->getNumViews();
523     }
524     const void *drawIndexPointer = nullptr;
525 
526     ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
527                                    &drawIndexPointer));
528     getFunctions()->drawElementsInstancedBaseVertex(
529         ToGLenum(mode), count, ToGLenum(type), drawIndexPointer, adjustedInstanceCount, baseVertex);
530     return angle::Result::Continue;
531 }
532 
drawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex,GLuint baseInstance)533 angle::Result ContextGL::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
534                                                                      gl::PrimitiveMode mode,
535                                                                      GLsizei count,
536                                                                      gl::DrawElementsType type,
537                                                                      const void *indices,
538                                                                      GLsizei instances,
539                                                                      GLint baseVertex,
540                                                                      GLuint baseInstance)
541 {
542     GLsizei adjustedInstanceCount = instances;
543     const gl::Program *program    = context->getState().getProgram();
544     if (program->usesMultiview())
545     {
546         adjustedInstanceCount *= program->getNumViews();
547     }
548     const void *drawIndexPointer = nullptr;
549 
550     ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
551                                    &drawIndexPointer));
552 
553     const FunctionsGL *functions = getFunctions();
554 
555     if (functions->drawElementsInstancedBaseVertexBaseInstance)
556     {
557         // GL 4.2+ or GL_EXT_base_instance
558         functions->drawElementsInstancedBaseVertexBaseInstance(
559             ToGLenum(mode), count, ToGLenum(type), drawIndexPointer, adjustedInstanceCount,
560             baseVertex, baseInstance);
561     }
562     else
563     {
564         // GL 3.3+ or GLES 3.2+
565         // TODO(http://anglebug.com/3910): same as above
566         gl::AttributesMask attribToResetMask =
567             updateAttributesForBaseInstance(program, baseInstance);
568 
569         functions->drawElementsInstancedBaseVertex(ToGLenum(mode), count, ToGLenum(type),
570                                                    drawIndexPointer, adjustedInstanceCount,
571                                                    baseVertex);
572 
573         resetUpdatedAttributes(attribToResetMask);
574     }
575 
576     return angle::Result::Continue;
577 }
578 
drawRangeElements(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices)579 angle::Result ContextGL::drawRangeElements(const gl::Context *context,
580                                            gl::PrimitiveMode mode,
581                                            GLuint start,
582                                            GLuint end,
583                                            GLsizei count,
584                                            gl::DrawElementsType type,
585                                            const void *indices)
586 {
587     const gl::Program *program   = context->getState().getProgram();
588     const bool usesMultiview     = program->usesMultiview();
589     const GLsizei instanceCount  = usesMultiview ? program->getNumViews() : 0;
590     const void *drawIndexPointer = nullptr;
591 
592     ANGLE_TRY(
593         setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer));
594     if (!usesMultiview)
595     {
596         getFunctions()->drawRangeElements(ToGLenum(mode), start, end, count, ToGLenum(type),
597                                           drawIndexPointer);
598     }
599     else
600     {
601         getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type),
602                                               drawIndexPointer, instanceCount);
603     }
604     return angle::Result::Continue;
605 }
606 
drawRangeElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)607 angle::Result ContextGL::drawRangeElementsBaseVertex(const gl::Context *context,
608                                                      gl::PrimitiveMode mode,
609                                                      GLuint start,
610                                                      GLuint end,
611                                                      GLsizei count,
612                                                      gl::DrawElementsType type,
613                                                      const void *indices,
614                                                      GLint baseVertex)
615 {
616     const gl::Program *program   = context->getState().getProgram();
617     const bool usesMultiview     = program->usesMultiview();
618     const GLsizei instanceCount  = usesMultiview ? program->getNumViews() : 0;
619     const void *drawIndexPointer = nullptr;
620 
621     ANGLE_TRY(
622         setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer));
623     if (!usesMultiview)
624     {
625         getFunctions()->drawRangeElementsBaseVertex(ToGLenum(mode), start, end, count,
626                                                     ToGLenum(type), drawIndexPointer, baseVertex);
627     }
628     else
629     {
630         getFunctions()->drawElementsInstancedBaseVertex(
631             ToGLenum(mode), count, ToGLenum(type), drawIndexPointer, instanceCount, baseVertex);
632     }
633     return angle::Result::Continue;
634 }
635 
drawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect)636 angle::Result ContextGL::drawArraysIndirect(const gl::Context *context,
637                                             gl::PrimitiveMode mode,
638                                             const void *indirect)
639 {
640     getFunctions()->drawArraysIndirect(ToGLenum(mode), indirect);
641     return angle::Result::Continue;
642 }
643 
drawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect)644 angle::Result ContextGL::drawElementsIndirect(const gl::Context *context,
645                                               gl::PrimitiveMode mode,
646                                               gl::DrawElementsType type,
647                                               const void *indirect)
648 {
649     getFunctions()->drawElementsIndirect(ToGLenum(mode), ToGLenum(type), indirect);
650     return angle::Result::Continue;
651 }
652 
getResetStatus()653 gl::GraphicsResetStatus ContextGL::getResetStatus()
654 {
655     return mRenderer->getResetStatus();
656 }
657 
getVendorString() const658 std::string ContextGL::getVendorString() const
659 {
660     return mRenderer->getVendorString();
661 }
662 
getRendererDescription() const663 std::string ContextGL::getRendererDescription() const
664 {
665     return mRenderer->getRendererDescription();
666 }
667 
insertEventMarker(GLsizei length,const char * marker)668 angle::Result ContextGL::insertEventMarker(GLsizei length, const char *marker)
669 {
670     mRenderer->insertEventMarker(length, marker);
671     return angle::Result::Continue;
672 }
673 
pushGroupMarker(GLsizei length,const char * marker)674 angle::Result ContextGL::pushGroupMarker(GLsizei length, const char *marker)
675 {
676     mRenderer->pushGroupMarker(length, marker);
677     return angle::Result::Continue;
678 }
679 
popGroupMarker()680 angle::Result ContextGL::popGroupMarker()
681 {
682     mRenderer->popGroupMarker();
683     return angle::Result::Continue;
684 }
685 
pushDebugGroup(const gl::Context * context,GLenum source,GLuint id,const std::string & message)686 angle::Result ContextGL::pushDebugGroup(const gl::Context *context,
687                                         GLenum source,
688                                         GLuint id,
689                                         const std::string &message)
690 {
691     mRenderer->pushDebugGroup(source, id, message);
692     return angle::Result::Continue;
693 }
694 
popDebugGroup(const gl::Context * context)695 angle::Result ContextGL::popDebugGroup(const gl::Context *context)
696 {
697     mRenderer->popDebugGroup();
698     return angle::Result::Continue;
699 }
700 
syncState(const gl::Context * context,const gl::State::DirtyBits & dirtyBits,const gl::State::DirtyBits & bitMask)701 angle::Result ContextGL::syncState(const gl::Context *context,
702                                    const gl::State::DirtyBits &dirtyBits,
703                                    const gl::State::DirtyBits &bitMask)
704 {
705     return mRenderer->getStateManager()->syncState(context, dirtyBits, bitMask);
706 }
707 
getGPUDisjoint()708 GLint ContextGL::getGPUDisjoint()
709 {
710     return mRenderer->getGPUDisjoint();
711 }
712 
getTimestamp()713 GLint64 ContextGL::getTimestamp()
714 {
715     return mRenderer->getTimestamp();
716 }
717 
onMakeCurrent(const gl::Context * context)718 angle::Result ContextGL::onMakeCurrent(const gl::Context *context)
719 {
720     // Queries need to be paused/resumed on context switches
721     return mRenderer->getStateManager()->onMakeCurrent(context);
722 }
723 
getNativeCaps() const724 gl::Caps ContextGL::getNativeCaps() const
725 {
726     return mRenderer->getNativeCaps();
727 }
728 
getNativeTextureCaps() const729 const gl::TextureCapsMap &ContextGL::getNativeTextureCaps() const
730 {
731     return mRenderer->getNativeTextureCaps();
732 }
733 
getNativeExtensions() const734 const gl::Extensions &ContextGL::getNativeExtensions() const
735 {
736     return mRenderer->getNativeExtensions();
737 }
738 
getNativeLimitations() const739 const gl::Limitations &ContextGL::getNativeLimitations() const
740 {
741     return mRenderer->getNativeLimitations();
742 }
743 
getStateManager()744 StateManagerGL *ContextGL::getStateManager()
745 {
746     return mRenderer->getStateManager();
747 }
748 
getFeaturesGL() const749 const angle::FeaturesGL &ContextGL::getFeaturesGL() const
750 {
751     return mRenderer->getFeatures();
752 }
753 
getBlitter() const754 BlitGL *ContextGL::getBlitter() const
755 {
756     return mRenderer->getBlitter();
757 }
758 
getMultiviewClearer() const759 ClearMultiviewGL *ContextGL::getMultiviewClearer() const
760 {
761     return mRenderer->getMultiviewClearer();
762 }
763 
dispatchCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)764 angle::Result ContextGL::dispatchCompute(const gl::Context *context,
765                                          GLuint numGroupsX,
766                                          GLuint numGroupsY,
767                                          GLuint numGroupsZ)
768 {
769     return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
770 }
771 
dispatchComputeIndirect(const gl::Context * context,GLintptr indirect)772 angle::Result ContextGL::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
773 {
774     return mRenderer->dispatchComputeIndirect(context, indirect);
775 }
776 
memoryBarrier(const gl::Context * context,GLbitfield barriers)777 angle::Result ContextGL::memoryBarrier(const gl::Context *context, GLbitfield barriers)
778 {
779     return mRenderer->memoryBarrier(barriers);
780 }
memoryBarrierByRegion(const gl::Context * context,GLbitfield barriers)781 angle::Result ContextGL::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
782 {
783     return mRenderer->memoryBarrierByRegion(barriers);
784 }
785 
setMaxShaderCompilerThreads(GLuint count)786 void ContextGL::setMaxShaderCompilerThreads(GLuint count)
787 {
788     mRenderer->setMaxShaderCompilerThreads(count);
789 }
790 
invalidateTexture(gl::TextureType target)791 void ContextGL::invalidateTexture(gl::TextureType target)
792 {
793     mRenderer->getStateManager()->invalidateTexture(target);
794 }
795 
validateState() const796 void ContextGL::validateState() const
797 {
798     const StateManagerGL *stateManager = mRenderer->getStateManager();
799     stateManager->validateState();
800 }
801 
setNeedsFlushBeforeDeleteTextures()802 void ContextGL::setNeedsFlushBeforeDeleteTextures()
803 {
804     mRenderer->setNeedsFlushBeforeDeleteTextures();
805 }
806 
flushIfNecessaryBeforeDeleteTextures()807 void ContextGL::flushIfNecessaryBeforeDeleteTextures()
808 {
809     mRenderer->flushIfNecessaryBeforeDeleteTextures();
810 }
811 
812 }  // namespace rx
813