xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/ContextGL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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/Context.inl.h"
14 #include "libANGLE/PixelLocalStorage.h"
15 #include "libANGLE/renderer/OverlayImpl.h"
16 #include "libANGLE/renderer/gl/BufferGL.h"
17 #include "libANGLE/renderer/gl/CompilerGL.h"
18 #include "libANGLE/renderer/gl/FenceNVGL.h"
19 #include "libANGLE/renderer/gl/FramebufferGL.h"
20 #include "libANGLE/renderer/gl/FunctionsGL.h"
21 #include "libANGLE/renderer/gl/MemoryObjectGL.h"
22 #include "libANGLE/renderer/gl/ProgramExecutableGL.h"
23 #include "libANGLE/renderer/gl/ProgramGL.h"
24 #include "libANGLE/renderer/gl/ProgramPipelineGL.h"
25 #include "libANGLE/renderer/gl/QueryGL.h"
26 #include "libANGLE/renderer/gl/RenderbufferGL.h"
27 #include "libANGLE/renderer/gl/RendererGL.h"
28 #include "libANGLE/renderer/gl/SamplerGL.h"
29 #include "libANGLE/renderer/gl/SemaphoreGL.h"
30 #include "libANGLE/renderer/gl/ShaderGL.h"
31 #include "libANGLE/renderer/gl/StateManagerGL.h"
32 #include "libANGLE/renderer/gl/SyncGL.h"
33 #include "libANGLE/renderer/gl/TextureGL.h"
34 #include "libANGLE/renderer/gl/TransformFeedbackGL.h"
35 #include "libANGLE/renderer/gl/VertexArrayGL.h"
36 
37 namespace rx
38 {
39 namespace
40 {
GetDrawAdjustedInstanceCount(const gl::ProgramExecutable * executable)41 GLsizei GetDrawAdjustedInstanceCount(const gl::ProgramExecutable *executable)
42 {
43     const bool usesMultiview = executable->usesMultiview();
44     return usesMultiview ? executable->getNumViews() : 0;
45 }
46 
GetInstancedDrawAdjustedInstanceCount(const gl::ProgramExecutable * executable,GLsizei instanceCount)47 GLsizei GetInstancedDrawAdjustedInstanceCount(const gl::ProgramExecutable *executable,
48                                               GLsizei instanceCount)
49 {
50     GLsizei adjustedInstanceCount = instanceCount;
51     if (executable->usesMultiview())
52     {
53         adjustedInstanceCount *= executable->getNumViews();
54     }
55     return adjustedInstanceCount;
56 }
57 }  // anonymous namespace
58 
ContextGL(const gl::State & state,gl::ErrorSet * errorSet,const std::shared_ptr<RendererGL> & renderer,RobustnessVideoMemoryPurgeStatus robustnessVideoMemoryPurgeStatus)59 ContextGL::ContextGL(const gl::State &state,
60                      gl::ErrorSet *errorSet,
61                      const std::shared_ptr<RendererGL> &renderer,
62                      RobustnessVideoMemoryPurgeStatus robustnessVideoMemoryPurgeStatus)
63     : ContextImpl(state, errorSet),
64       mRenderer(renderer),
65       mRobustnessVideoMemoryPurgeStatus(robustnessVideoMemoryPurgeStatus)
66 {}
67 
~ContextGL()68 ContextGL::~ContextGL() {}
69 
initialize(const angle::ImageLoadContext & imageLoadContext)70 angle::Result ContextGL::initialize(const angle::ImageLoadContext &imageLoadContext)
71 {
72     return angle::Result::Continue;
73 }
74 
createCompiler()75 CompilerImpl *ContextGL::createCompiler()
76 {
77     return new CompilerGL(this);
78 }
79 
createShader(const gl::ShaderState & data)80 ShaderImpl *ContextGL::createShader(const gl::ShaderState &data)
81 {
82     const FunctionsGL *functions = getFunctions();
83     GLuint shader                = functions->createShader(ToGLenum(data.getShaderType()));
84 
85     return new ShaderGL(data, shader);
86 }
87 
createProgram(const gl::ProgramState & data)88 ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
89 {
90     return new ProgramGL(data, getFunctions(), getFeaturesGL(), getStateManager(), mRenderer);
91 }
92 
createProgramExecutable(const gl::ProgramExecutable * executable)93 ProgramExecutableImpl *ContextGL::createProgramExecutable(const gl::ProgramExecutable *executable)
94 {
95     return new ProgramExecutableGL(executable);
96 }
97 
createFramebuffer(const gl::FramebufferState & data)98 FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data)
99 {
100     const FunctionsGL *funcs = getFunctions();
101 
102     GLuint fbo = 0;
103     if (!data.isDefault())
104     {
105         funcs->genFramebuffers(1, &fbo);
106     }
107 
108     return new FramebufferGL(data, fbo, false);
109 }
110 
createTexture(const gl::TextureState & state)111 TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
112 {
113     const FunctionsGL *functions = getFunctions();
114     StateManagerGL *stateManager = getStateManager();
115 
116     GLuint texture = 0;
117     functions->genTextures(1, &texture);
118     stateManager->bindTexture(state.getType(), texture);
119 
120     return new TextureGL(state, texture);
121 }
122 
createRenderbuffer(const gl::RenderbufferState & state)123 RenderbufferImpl *ContextGL::createRenderbuffer(const gl::RenderbufferState &state)
124 {
125     const FunctionsGL *functions = getFunctions();
126     StateManagerGL *stateManager = getStateManager();
127 
128     GLuint renderbuffer = 0;
129     functions->genRenderbuffers(1, &renderbuffer);
130     stateManager->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
131 
132     return new RenderbufferGL(state, renderbuffer);
133 }
134 
createBuffer(const gl::BufferState & state)135 BufferImpl *ContextGL::createBuffer(const gl::BufferState &state)
136 {
137     const FunctionsGL *functions = getFunctions();
138 
139     GLuint buffer = 0;
140     functions->genBuffers(1, &buffer);
141 
142     return new BufferGL(state, buffer);
143 }
144 
createVertexArray(const gl::VertexArrayState & data)145 VertexArrayImpl *ContextGL::createVertexArray(const gl::VertexArrayState &data)
146 {
147     const FunctionsGL *functions      = getFunctions();
148     const angle::FeaturesGL &features = getFeaturesGL();
149 
150     // Use the shared default vertex array when forced to for workarounds
151     // (syncAllVertexArraysToDefault) or for the frontend default vertex array so that client data
152     // can be used directly
153     // Disable on external contexts so that the default VAO is not modified by both ANGLE and the
154     // external user.
155     if (features.syncAllVertexArraysToDefault.enabled ||
156         (features.syncDefaultVertexArraysToDefault.enabled && data.isDefault() &&
157          mState.areClientArraysEnabled()))
158     {
159         StateManagerGL *stateManager = getStateManager();
160 
161         return new VertexArrayGL(data, stateManager->getDefaultVAO(),
162                                  stateManager->getDefaultVAOState());
163     }
164     else
165     {
166         GLuint vao = 0;
167         functions->genVertexArrays(1, &vao);
168         return new VertexArrayGL(data, vao);
169     }
170 }
171 
createQuery(gl::QueryType type)172 QueryImpl *ContextGL::createQuery(gl::QueryType type)
173 {
174     switch (type)
175     {
176         case gl::QueryType::CommandsCompleted:
177             return new SyncQueryGL(type, getFunctions());
178 
179         default:
180             return new StandardQueryGL(type, getFunctions(), getStateManager());
181     }
182 }
183 
createFenceNV()184 FenceNVImpl *ContextGL::createFenceNV()
185 {
186     const FunctionsGL *functions = getFunctions();
187     if (FenceNVGL::Supported(functions))
188     {
189         return new FenceNVGL(functions);
190     }
191     else
192     {
193         ASSERT(FenceNVSyncGL::Supported(functions));
194         return new FenceNVSyncGL(functions);
195     }
196 }
197 
createSync()198 SyncImpl *ContextGL::createSync()
199 {
200     return new SyncGL(getFunctions());
201 }
202 
createTransformFeedback(const gl::TransformFeedbackState & state)203 TransformFeedbackImpl *ContextGL::createTransformFeedback(const gl::TransformFeedbackState &state)
204 {
205     return new TransformFeedbackGL(state, getFunctions(), getStateManager());
206 }
207 
createSampler(const gl::SamplerState & state)208 SamplerImpl *ContextGL::createSampler(const gl::SamplerState &state)
209 {
210     return new SamplerGL(state, getFunctions(), getStateManager());
211 }
212 
createProgramPipeline(const gl::ProgramPipelineState & data)213 ProgramPipelineImpl *ContextGL::createProgramPipeline(const gl::ProgramPipelineState &data)
214 {
215     return new ProgramPipelineGL(data, getFunctions());
216 }
217 
createMemoryObject()218 MemoryObjectImpl *ContextGL::createMemoryObject()
219 {
220     const FunctionsGL *functions = getFunctions();
221 
222     GLuint memoryObject = 0;
223     functions->createMemoryObjectsEXT(1, &memoryObject);
224 
225     return new MemoryObjectGL(memoryObject);
226 }
227 
createSemaphore()228 SemaphoreImpl *ContextGL::createSemaphore()
229 {
230     const FunctionsGL *functions = getFunctions();
231 
232     GLuint semaphore = 0;
233     functions->genSemaphoresEXT(1, &semaphore);
234 
235     return new SemaphoreGL(semaphore);
236 }
237 
createOverlay(const gl::OverlayState & state)238 OverlayImpl *ContextGL::createOverlay(const gl::OverlayState &state)
239 {
240     // Not implemented.
241     return new OverlayImpl(state);
242 }
243 
flush(const gl::Context * context)244 angle::Result ContextGL::flush(const gl::Context *context)
245 {
246     return mRenderer->flush();
247 }
248 
finish(const gl::Context * context)249 angle::Result ContextGL::finish(const gl::Context *context)
250 {
251     return mRenderer->finish();
252 }
253 
setDrawArraysState(const gl::Context * context,GLint first,GLsizei count,GLsizei instanceCount)254 ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *context,
255                                                          GLint first,
256                                                          GLsizei count,
257                                                          GLsizei instanceCount)
258 {
259     const angle::FeaturesGL &features = getFeaturesGL();
260     if (context->getStateCache().hasAnyActiveClientAttrib() ||
261         (features.shiftInstancedArrayDataWithOffset.enabled && first > 0))
262     {
263         const gl::State &glState                = context->getState();
264         const gl::ProgramExecutable *executable = getState().getProgramExecutable();
265         const gl::VertexArray *vao              = glState.getVertexArray();
266         const VertexArrayGL *vaoGL              = GetImplAs<VertexArrayGL>(vao);
267 
268         ANGLE_TRY(vaoGL->syncClientSideData(context, executable->getActiveAttribLocationsMask(),
269                                             first, count, instanceCount));
270 
271 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
272         ANGLE_TRY(vaoGL->validateState(context));
273 #endif  // ANGLE_STATE_VALIDATION_ENABLED
274     }
275     else if (features.shiftInstancedArrayDataWithOffset.enabled && first == 0)
276     {
277         // There could be previous draw call that has modified the attributes
278         // Instead of forcefully streaming attributes, we just rebind the original ones
279         const gl::State &glState   = context->getState();
280         const gl::VertexArray *vao = glState.getVertexArray();
281         const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
282         ANGLE_TRY(vaoGL->recoverForcedStreamingAttributesForDrawArraysInstanced(context));
283     }
284 
285     if (features.setPrimitiveRestartFixedIndexForDrawArrays.enabled)
286     {
287         StateManagerGL *stateManager           = getStateManager();
288         constexpr GLuint primitiveRestartIndex = gl::GetPrimitiveRestartIndexFromType<GLuint>();
289         ANGLE_TRY(stateManager->setPrimitiveRestartIndex(context, primitiveRestartIndex));
290     }
291 
292     return angle::Result::Continue;
293 }
294 
setDrawElementsState(const gl::Context * context,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instanceCount,const void ** outIndices)295 ANGLE_INLINE angle::Result ContextGL::setDrawElementsState(const gl::Context *context,
296                                                            GLsizei count,
297                                                            gl::DrawElementsType type,
298                                                            const void *indices,
299                                                            GLsizei instanceCount,
300                                                            const void **outIndices)
301 {
302     const gl::State &glState                = context->getState();
303     const gl::ProgramExecutable *executable = getState().getProgramExecutable();
304     const gl::VertexArray *vao              = glState.getVertexArray();
305     const gl::StateCache &stateCache        = context->getStateCache();
306 
307     const angle::FeaturesGL &features = getFeaturesGL();
308     if (features.shiftInstancedArrayDataWithOffset.enabled)
309     {
310         // There might be instanced arrays that are forced streaming for drawArraysInstanced
311         // They cannot be ELEMENT_ARRAY_BUFFER
312         const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
313         ANGLE_TRY(vaoGL->recoverForcedStreamingAttributesForDrawArraysInstanced(context));
314     }
315 
316     if (stateCache.hasAnyActiveClientAttrib() || vao->getElementArrayBuffer() == nullptr)
317     {
318         const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
319         ANGLE_TRY(vaoGL->syncDrawElementsState(context, executable->getActiveAttribLocationsMask(),
320                                                count, type, indices, instanceCount,
321                                                glState.isPrimitiveRestartEnabled(), outIndices));
322     }
323     else
324     {
325         *outIndices = indices;
326     }
327 
328     if (glState.isPrimitiveRestartEnabled() && features.emulatePrimitiveRestartFixedIndex.enabled)
329     {
330         StateManagerGL *stateManager = getStateManager();
331 
332         GLuint primitiveRestartIndex = gl::GetPrimitiveRestartIndex(type);
333         ANGLE_TRY(stateManager->setPrimitiveRestartIndex(context, primitiveRestartIndex));
334     }
335 
336 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
337     const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
338     ANGLE_TRY(vaoGL->validateState(context));
339 #endif  // ANGLE_STATE_VALIDATION_ENABLED
340 
341     return angle::Result::Continue;
342 }
343 
drawArrays(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count)344 angle::Result ContextGL::drawArrays(const gl::Context *context,
345                                     gl::PrimitiveMode mode,
346                                     GLint first,
347                                     GLsizei count)
348 {
349     const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
350     const GLsizei instanceCount             = GetDrawAdjustedInstanceCount(executable);
351 
352 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
353     validateState();
354 #endif
355 
356     ANGLE_TRY(setDrawArraysState(context, first, count, instanceCount));
357     if (!executable->usesMultiview())
358     {
359         ANGLE_GL_TRY(context, getFunctions()->drawArrays(ToGLenum(mode), first, count));
360     }
361     else
362     {
363         ANGLE_GL_TRY(context, getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count,
364                                                                   instanceCount));
365     }
366     mRenderer->markWorkSubmitted();
367 
368     return angle::Result::Continue;
369 }
370 
drawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)371 angle::Result ContextGL::drawArraysInstanced(const gl::Context *context,
372                                              gl::PrimitiveMode mode,
373                                              GLint first,
374                                              GLsizei count,
375                                              GLsizei instanceCount)
376 {
377     const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
378     const GLsizei adjustedInstanceCount =
379         GetInstancedDrawAdjustedInstanceCount(executable, instanceCount);
380 
381     ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
382     ANGLE_GL_TRY(context, getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count,
383                                                               adjustedInstanceCount));
384     mRenderer->markWorkSubmitted();
385 
386     return angle::Result::Continue;
387 }
388 
updateAttributesForBaseInstance(GLuint baseInstance)389 gl::AttributesMask ContextGL::updateAttributesForBaseInstance(GLuint baseInstance)
390 {
391     const gl::ProgramExecutable *executable = getState().getProgramExecutable();
392     gl::AttributesMask attribToUpdateMask;
393 
394     if (baseInstance != 0)
395     {
396         const FunctionsGL *functions = getFunctions();
397         const auto &attribs          = mState.getVertexArray()->getVertexAttributes();
398         const auto &bindings         = mState.getVertexArray()->getVertexBindings();
399         for (GLuint attribIndex = 0; attribIndex < attribs.size(); attribIndex++)
400         {
401             const gl::VertexAttribute &attrib = attribs[attribIndex];
402             const gl::VertexBinding &binding  = bindings[attrib.bindingIndex];
403             if (executable->isAttribLocationActive(attribIndex) && binding.getDivisor() != 0)
404             {
405                 attribToUpdateMask.set(attribIndex);
406                 const char *p             = static_cast<const char *>(attrib.pointer);
407                 const size_t sourceStride = gl::ComputeVertexAttributeStride(attrib, binding);
408                 const void *newPointer    = p + sourceStride * baseInstance;
409 
410                 const BufferGL *buffer = GetImplAs<BufferGL>(binding.getBuffer().get());
411                 // We often stream data from scratch buffers when client side data is being used
412                 // and that information is in VertexArrayGL.
413                 // Assert that the buffer is non-null because this case isn't handled.
414                 ASSERT(buffer);
415                 getStateManager()->bindBuffer(gl::BufferBinding::Array, buffer->getBufferID());
416                 if (attrib.format->isPureInt())
417                 {
418                     functions->vertexAttribIPointer(attribIndex, attrib.format->channelCount,
419                                                     gl::ToGLenum(attrib.format->vertexAttribType),
420                                                     attrib.vertexAttribArrayStride, newPointer);
421                 }
422                 else
423                 {
424                     functions->vertexAttribPointer(attribIndex, attrib.format->channelCount,
425                                                    gl::ToGLenum(attrib.format->vertexAttribType),
426                                                    attrib.format->isNorm(),
427                                                    attrib.vertexAttribArrayStride, newPointer);
428                 }
429             }
430         }
431     }
432 
433     return attribToUpdateMask;
434 }
435 
resetUpdatedAttributes(gl::AttributesMask attribMask)436 void ContextGL::resetUpdatedAttributes(gl::AttributesMask attribMask)
437 {
438     const FunctionsGL *functions = getFunctions();
439     for (size_t attribIndex : attribMask)
440     {
441         const gl::VertexAttribute &attrib =
442             mState.getVertexArray()->getVertexAttributes()[attribIndex];
443         const gl::VertexBinding &binding =
444             (mState.getVertexArray()->getVertexBindings())[attrib.bindingIndex];
445         getStateManager()->bindBuffer(
446             gl::BufferBinding::Array,
447             GetImplAs<BufferGL>(binding.getBuffer().get())->getBufferID());
448         if (attrib.format->isPureInt())
449         {
450             functions->vertexAttribIPointer(static_cast<GLuint>(attribIndex),
451                                             attrib.format->channelCount,
452                                             gl::ToGLenum(attrib.format->vertexAttribType),
453                                             attrib.vertexAttribArrayStride, attrib.pointer);
454         }
455         else
456         {
457             functions->vertexAttribPointer(
458                 static_cast<GLuint>(attribIndex), attrib.format->channelCount,
459                 gl::ToGLenum(attrib.format->vertexAttribType), attrib.format->isNorm(),
460                 attrib.vertexAttribArrayStride, attrib.pointer);
461         }
462     }
463 }
464 
drawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)465 angle::Result ContextGL::drawArraysInstancedBaseInstance(const gl::Context *context,
466                                                          gl::PrimitiveMode mode,
467                                                          GLint first,
468                                                          GLsizei count,
469                                                          GLsizei instanceCount,
470                                                          GLuint baseInstance)
471 {
472     const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
473     const GLsizei adjustedInstanceCount =
474         GetInstancedDrawAdjustedInstanceCount(executable, instanceCount);
475 
476     ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount));
477 
478     const FunctionsGL *functions = getFunctions();
479 
480     if (functions->drawArraysInstancedBaseInstance)
481     {
482         // GL 4.2+ or GL_EXT_base_instance
483         ANGLE_GL_TRY(context,
484                      functions->drawArraysInstancedBaseInstance(
485                          ToGLenum(mode), first, count, adjustedInstanceCount, baseInstance));
486     }
487     else
488     {
489         // GL 3.3+ or GLES 3.2+
490         // TODO(http://anglebug.com/42262554): This is a temporary solution by setting and resetting
491         // pointer offset calling vertexAttribPointer Will refactor stateCache and pass baseInstance
492         // to setDrawArraysState to set pointer offset
493 
494         gl::AttributesMask attribToResetMask = updateAttributesForBaseInstance(baseInstance);
495 
496         ANGLE_GL_TRY(context, functions->drawArraysInstanced(ToGLenum(mode), first, count,
497                                                              adjustedInstanceCount));
498 
499         resetUpdatedAttributes(attribToResetMask);
500     }
501 
502     mRenderer->markWorkSubmitted();
503 
504     return angle::Result::Continue;
505 }
506 
drawElements(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices)507 angle::Result ContextGL::drawElements(const gl::Context *context,
508                                       gl::PrimitiveMode mode,
509                                       GLsizei count,
510                                       gl::DrawElementsType type,
511                                       const void *indices)
512 {
513     const gl::State &glState                = context->getState();
514     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
515     const GLsizei instanceCount             = GetDrawAdjustedInstanceCount(executable);
516     const void *drawIndexPtr                = nullptr;
517 
518 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
519     validateState();
520 #endif  // ANGLE_STATE_VALIDATION_ENABLED
521 
522     ANGLE_TRY(setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPtr));
523     if (!executable->usesMultiview())
524     {
525         ANGLE_GL_TRY(context, getFunctions()->drawElements(ToGLenum(mode), count, ToGLenum(type),
526                                                            drawIndexPtr));
527     }
528     else
529     {
530         ANGLE_GL_TRY(context,
531                      getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type),
532                                                            drawIndexPtr, instanceCount));
533     }
534     mRenderer->markWorkSubmitted();
535 
536     return angle::Result::Continue;
537 }
538 
drawElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)539 angle::Result ContextGL::drawElementsBaseVertex(const gl::Context *context,
540                                                 gl::PrimitiveMode mode,
541                                                 GLsizei count,
542                                                 gl::DrawElementsType type,
543                                                 const void *indices,
544                                                 GLint baseVertex)
545 {
546     const gl::State &glState                = context->getState();
547     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
548     const GLsizei instanceCount             = GetDrawAdjustedInstanceCount(executable);
549     const void *drawIndexPtr                = nullptr;
550 
551 #if defined(ANGLE_STATE_VALIDATION_ENABLED)
552     validateState();
553 #endif  // ANGLE_STATE_VALIDATION_ENABLED
554 
555     ANGLE_TRY(setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPtr));
556     if (!executable->usesMultiview())
557     {
558         ANGLE_GL_TRY(context, getFunctions()->drawElementsBaseVertex(
559                                   ToGLenum(mode), count, ToGLenum(type), drawIndexPtr, baseVertex));
560     }
561     else
562     {
563         ANGLE_GL_TRY(context, getFunctions()->drawElementsInstancedBaseVertex(
564                                   ToGLenum(mode), count, ToGLenum(type), drawIndexPtr,
565                                   instanceCount, baseVertex));
566     }
567     mRenderer->markWorkSubmitted();
568 
569     return angle::Result::Continue;
570 }
571 
drawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances)572 angle::Result ContextGL::drawElementsInstanced(const gl::Context *context,
573                                                gl::PrimitiveMode mode,
574                                                GLsizei count,
575                                                gl::DrawElementsType type,
576                                                const void *indices,
577                                                GLsizei instances)
578 {
579     const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
580     const GLsizei adjustedInstanceCount =
581         GetInstancedDrawAdjustedInstanceCount(executable, instances);
582     const void *drawIndexPointer = nullptr;
583 
584     ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
585                                    &drawIndexPointer));
586     ANGLE_GL_TRY(context,
587                  getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type),
588                                                        drawIndexPointer, adjustedInstanceCount));
589     return angle::Result::Continue;
590 }
591 
drawElementsInstancedBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex)592 angle::Result ContextGL::drawElementsInstancedBaseVertex(const gl::Context *context,
593                                                          gl::PrimitiveMode mode,
594                                                          GLsizei count,
595                                                          gl::DrawElementsType type,
596                                                          const void *indices,
597                                                          GLsizei instances,
598                                                          GLint baseVertex)
599 {
600     const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
601     const GLsizei adjustedInstanceCount =
602         GetInstancedDrawAdjustedInstanceCount(executable, instances);
603     const void *drawIndexPointer = nullptr;
604 
605     ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
606                                    &drawIndexPointer));
607     ANGLE_GL_TRY(context, getFunctions()->drawElementsInstancedBaseVertex(
608                               ToGLenum(mode), count, ToGLenum(type), drawIndexPointer,
609                               adjustedInstanceCount, baseVertex));
610     mRenderer->markWorkSubmitted();
611 
612     return angle::Result::Continue;
613 }
614 
drawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,GLsizei count,gl::DrawElementsType type,const void * indices,GLsizei instances,GLint baseVertex,GLuint baseInstance)615 angle::Result ContextGL::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
616                                                                      gl::PrimitiveMode mode,
617                                                                      GLsizei count,
618                                                                      gl::DrawElementsType type,
619                                                                      const void *indices,
620                                                                      GLsizei instances,
621                                                                      GLint baseVertex,
622                                                                      GLuint baseInstance)
623 {
624     const gl::ProgramExecutable *executable = context->getState().getProgramExecutable();
625     const GLsizei adjustedInstanceCount =
626         GetInstancedDrawAdjustedInstanceCount(executable, instances);
627     const void *drawIndexPointer = nullptr;
628 
629     ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount,
630                                    &drawIndexPointer));
631 
632     const FunctionsGL *functions = getFunctions();
633 
634     if (functions->drawElementsInstancedBaseVertexBaseInstance)
635     {
636         // GL 4.2+ or GL_EXT_base_instance
637         ANGLE_GL_TRY(context, functions->drawElementsInstancedBaseVertexBaseInstance(
638                                   ToGLenum(mode), count, ToGLenum(type), drawIndexPointer,
639                                   adjustedInstanceCount, baseVertex, baseInstance));
640     }
641     else
642     {
643         // GL 3.3+ or GLES 3.2+
644         // TODO(http://anglebug.com/42262554): same as above
645         gl::AttributesMask attribToResetMask = updateAttributesForBaseInstance(baseInstance);
646 
647         ANGLE_GL_TRY(context, functions->drawElementsInstancedBaseVertex(
648                                   ToGLenum(mode), count, ToGLenum(type), drawIndexPointer,
649                                   adjustedInstanceCount, baseVertex));
650 
651         resetUpdatedAttributes(attribToResetMask);
652     }
653 
654     mRenderer->markWorkSubmitted();
655 
656     return angle::Result::Continue;
657 }
658 
drawRangeElements(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices)659 angle::Result ContextGL::drawRangeElements(const gl::Context *context,
660                                            gl::PrimitiveMode mode,
661                                            GLuint start,
662                                            GLuint end,
663                                            GLsizei count,
664                                            gl::DrawElementsType type,
665                                            const void *indices)
666 {
667     const gl::ProgramExecutable *executable = mState.getProgramExecutable();
668     const GLsizei instanceCount             = GetDrawAdjustedInstanceCount(executable);
669     const void *drawIndexPointer            = nullptr;
670 
671     ANGLE_TRY(
672         setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer));
673     if (!executable->usesMultiview())
674     {
675         ANGLE_GL_TRY(context, getFunctions()->drawRangeElements(ToGLenum(mode), start, end, count,
676                                                                 ToGLenum(type), drawIndexPointer));
677     }
678     else
679     {
680         ANGLE_GL_TRY(context,
681                      getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type),
682                                                            drawIndexPointer, instanceCount));
683     }
684     mRenderer->markWorkSubmitted();
685 
686     return angle::Result::Continue;
687 }
688 
drawRangeElementsBaseVertex(const gl::Context * context,gl::PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,gl::DrawElementsType type,const void * indices,GLint baseVertex)689 angle::Result ContextGL::drawRangeElementsBaseVertex(const gl::Context *context,
690                                                      gl::PrimitiveMode mode,
691                                                      GLuint start,
692                                                      GLuint end,
693                                                      GLsizei count,
694                                                      gl::DrawElementsType type,
695                                                      const void *indices,
696                                                      GLint baseVertex)
697 {
698     const gl::ProgramExecutable *executable = mState.getProgramExecutable();
699     const GLsizei instanceCount             = GetDrawAdjustedInstanceCount(executable);
700     const void *drawIndexPointer            = nullptr;
701 
702     ANGLE_TRY(
703         setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer));
704     if (!executable->usesMultiview())
705     {
706         ANGLE_GL_TRY(context, getFunctions()->drawRangeElementsBaseVertex(
707                                   ToGLenum(mode), start, end, count, ToGLenum(type),
708                                   drawIndexPointer, baseVertex));
709     }
710     else
711     {
712         ANGLE_GL_TRY(context, getFunctions()->drawElementsInstancedBaseVertex(
713                                   ToGLenum(mode), count, ToGLenum(type), drawIndexPointer,
714                                   instanceCount, baseVertex));
715     }
716     mRenderer->markWorkSubmitted();
717 
718     return angle::Result::Continue;
719 }
720 
drawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect)721 angle::Result ContextGL::drawArraysIndirect(const gl::Context *context,
722                                             gl::PrimitiveMode mode,
723                                             const void *indirect)
724 {
725     ANGLE_GL_TRY(context, getFunctions()->drawArraysIndirect(ToGLenum(mode), indirect));
726     mRenderer->markWorkSubmitted();
727 
728     return angle::Result::Continue;
729 }
730 
drawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect)731 angle::Result ContextGL::drawElementsIndirect(const gl::Context *context,
732                                               gl::PrimitiveMode mode,
733                                               gl::DrawElementsType type,
734                                               const void *indirect)
735 {
736     ANGLE_GL_TRY(context,
737                  getFunctions()->drawElementsIndirect(ToGLenum(mode), ToGLenum(type), indirect));
738     return angle::Result::Continue;
739 }
740 
multiDrawArrays(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)741 angle::Result ContextGL::multiDrawArrays(const gl::Context *context,
742                                          gl::PrimitiveMode mode,
743                                          const GLint *firsts,
744                                          const GLsizei *counts,
745                                          GLsizei drawcount)
746 {
747     mRenderer->markWorkSubmitted();
748 
749     return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
750 }
751 
multiDrawArraysInstanced(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)752 angle::Result ContextGL::multiDrawArraysInstanced(const gl::Context *context,
753                                                   gl::PrimitiveMode mode,
754                                                   const GLint *firsts,
755                                                   const GLsizei *counts,
756                                                   const GLsizei *instanceCounts,
757                                                   GLsizei drawcount)
758 {
759     mRenderer->markWorkSubmitted();
760 
761     return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
762                                                drawcount);
763 }
764 
multiDrawArraysIndirect(const gl::Context * context,gl::PrimitiveMode mode,const void * indirect,GLsizei drawcount,GLsizei stride)765 angle::Result ContextGL::multiDrawArraysIndirect(const gl::Context *context,
766                                                  gl::PrimitiveMode mode,
767                                                  const void *indirect,
768                                                  GLsizei drawcount,
769                                                  GLsizei stride)
770 {
771     mRenderer->markWorkSubmitted();
772 
773     return rx::MultiDrawArraysIndirectGeneral(this, context, mode, indirect, drawcount, stride);
774 }
775 
multiDrawElements(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)776 angle::Result ContextGL::multiDrawElements(const gl::Context *context,
777                                            gl::PrimitiveMode mode,
778                                            const GLsizei *counts,
779                                            gl::DrawElementsType type,
780                                            const GLvoid *const *indices,
781                                            GLsizei drawcount)
782 {
783     mRenderer->markWorkSubmitted();
784 
785     return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
786 }
787 
multiDrawElementsInstanced(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)788 angle::Result ContextGL::multiDrawElementsInstanced(const gl::Context *context,
789                                                     gl::PrimitiveMode mode,
790                                                     const GLsizei *counts,
791                                                     gl::DrawElementsType type,
792                                                     const GLvoid *const *indices,
793                                                     const GLsizei *instanceCounts,
794                                                     GLsizei drawcount)
795 {
796     mRenderer->markWorkSubmitted();
797 
798     return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
799                                                  instanceCounts, drawcount);
800 }
801 
multiDrawElementsIndirect(const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect,GLsizei drawcount,GLsizei stride)802 angle::Result ContextGL::multiDrawElementsIndirect(const gl::Context *context,
803                                                    gl::PrimitiveMode mode,
804                                                    gl::DrawElementsType type,
805                                                    const void *indirect,
806                                                    GLsizei drawcount,
807                                                    GLsizei stride)
808 {
809     mRenderer->markWorkSubmitted();
810 
811     return rx::MultiDrawElementsIndirectGeneral(this, context, mode, type, indirect, drawcount,
812                                                 stride);
813 }
814 
multiDrawArraysInstancedBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)815 angle::Result ContextGL::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
816                                                               gl::PrimitiveMode mode,
817                                                               const GLint *firsts,
818                                                               const GLsizei *counts,
819                                                               const GLsizei *instanceCounts,
820                                                               const GLuint *baseInstances,
821                                                               GLsizei drawcount)
822 {
823     mRenderer->markWorkSubmitted();
824 
825     return rx::MultiDrawArraysInstancedBaseInstanceGeneral(
826         this, context, mode, firsts, counts, instanceCounts, baseInstances, drawcount);
827 }
828 
multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,const GLint * baseVertices,const GLuint * baseInstances,GLsizei drawcount)829 angle::Result ContextGL::multiDrawElementsInstancedBaseVertexBaseInstance(
830     const gl::Context *context,
831     gl::PrimitiveMode mode,
832     const GLsizei *counts,
833     gl::DrawElementsType type,
834     const GLvoid *const *indices,
835     const GLsizei *instanceCounts,
836     const GLint *baseVertices,
837     const GLuint *baseInstances,
838     GLsizei drawcount)
839 {
840     mRenderer->markWorkSubmitted();
841 
842     return rx::MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(
843         this, context, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances,
844         drawcount);
845 }
846 
getResetStatus()847 gl::GraphicsResetStatus ContextGL::getResetStatus()
848 {
849     gl::GraphicsResetStatus resetStatus = mRenderer->getResetStatus();
850     if (resetStatus == gl::GraphicsResetStatus::PurgedContextResetNV)
851     {
852         if (mRobustnessVideoMemoryPurgeStatus == RobustnessVideoMemoryPurgeStatus::NOT_REQUESTED)
853         {
854             resetStatus = gl::GraphicsResetStatus::UnknownContextReset;
855         }
856     }
857     return resetStatus;
858 }
859 
insertEventMarker(GLsizei length,const char * marker)860 angle::Result ContextGL::insertEventMarker(GLsizei length, const char *marker)
861 {
862     mRenderer->insertEventMarker(length, marker);
863     return angle::Result::Continue;
864 }
865 
pushGroupMarker(GLsizei length,const char * marker)866 angle::Result ContextGL::pushGroupMarker(GLsizei length, const char *marker)
867 {
868     mRenderer->pushGroupMarker(length, marker);
869     return angle::Result::Continue;
870 }
871 
popGroupMarker()872 angle::Result ContextGL::popGroupMarker()
873 {
874     mRenderer->popGroupMarker();
875     return angle::Result::Continue;
876 }
877 
pushDebugGroup(const gl::Context * context,GLenum source,GLuint id,const std::string & message)878 angle::Result ContextGL::pushDebugGroup(const gl::Context *context,
879                                         GLenum source,
880                                         GLuint id,
881                                         const std::string &message)
882 {
883     mRenderer->pushDebugGroup(source, id, message);
884     return angle::Result::Continue;
885 }
886 
popDebugGroup(const gl::Context * context)887 angle::Result ContextGL::popDebugGroup(const gl::Context *context)
888 {
889     mRenderer->popDebugGroup();
890     return angle::Result::Continue;
891 }
892 
syncState(const gl::Context * context,const gl::state::DirtyBits dirtyBits,const gl::state::DirtyBits bitMask,const gl::state::ExtendedDirtyBits extendedDirtyBits,const gl::state::ExtendedDirtyBits extendedBitMask,gl::Command command)893 angle::Result ContextGL::syncState(const gl::Context *context,
894                                    const gl::state::DirtyBits dirtyBits,
895                                    const gl::state::DirtyBits bitMask,
896                                    const gl::state::ExtendedDirtyBits extendedDirtyBits,
897                                    const gl::state::ExtendedDirtyBits extendedBitMask,
898                                    gl::Command command)
899 {
900     return mRenderer->getStateManager()->syncState(context, dirtyBits, bitMask, extendedDirtyBits,
901                                                    extendedBitMask);
902 }
903 
getGPUDisjoint()904 GLint ContextGL::getGPUDisjoint()
905 {
906     return mRenderer->getGPUDisjoint();
907 }
908 
getTimestamp()909 GLint64 ContextGL::getTimestamp()
910 {
911     return mRenderer->getTimestamp();
912 }
913 
onMakeCurrent(const gl::Context * context)914 angle::Result ContextGL::onMakeCurrent(const gl::Context *context)
915 {
916     // Queries need to be paused/resumed on context switches
917     return mRenderer->getStateManager()->onMakeCurrent(context);
918 }
919 
onUnMakeCurrent(const gl::Context * context)920 angle::Result ContextGL::onUnMakeCurrent(const gl::Context *context)
921 {
922     ANGLE_TRY(flush(context));
923     if (getFeaturesGL().unbindFBOBeforeSwitchingContext.enabled)
924     {
925         mRenderer->getStateManager()->bindFramebuffer(GL_FRAMEBUFFER, 0);
926     }
927     return ContextImpl::onUnMakeCurrent(context);
928 }
929 
getNativeCaps() const930 gl::Caps ContextGL::getNativeCaps() const
931 {
932     return mRenderer->getNativeCaps();
933 }
934 
getNativeTextureCaps() const935 const gl::TextureCapsMap &ContextGL::getNativeTextureCaps() const
936 {
937     return mRenderer->getNativeTextureCaps();
938 }
939 
getNativeExtensions() const940 const gl::Extensions &ContextGL::getNativeExtensions() const
941 {
942     return mRenderer->getNativeExtensions();
943 }
944 
getNativeLimitations() const945 const gl::Limitations &ContextGL::getNativeLimitations() const
946 {
947     return mRenderer->getNativeLimitations();
948 }
949 
getNativePixelLocalStorageOptions() const950 const ShPixelLocalStorageOptions &ContextGL::getNativePixelLocalStorageOptions() const
951 {
952     return mRenderer->getNativePixelLocalStorageOptions();
953 }
954 
getStateManager()955 StateManagerGL *ContextGL::getStateManager()
956 {
957     return mRenderer->getStateManager();
958 }
959 
getFeaturesGL() const960 const angle::FeaturesGL &ContextGL::getFeaturesGL() const
961 {
962     return mRenderer->getFeatures();
963 }
964 
getBlitter() const965 BlitGL *ContextGL::getBlitter() const
966 {
967     return mRenderer->getBlitter();
968 }
969 
getMultiviewClearer() const970 ClearMultiviewGL *ContextGL::getMultiviewClearer() const
971 {
972     return mRenderer->getMultiviewClearer();
973 }
974 
dispatchCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)975 angle::Result ContextGL::dispatchCompute(const gl::Context *context,
976                                          GLuint numGroupsX,
977                                          GLuint numGroupsY,
978                                          GLuint numGroupsZ)
979 {
980     return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
981 }
982 
dispatchComputeIndirect(const gl::Context * context,GLintptr indirect)983 angle::Result ContextGL::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
984 {
985     return mRenderer->dispatchComputeIndirect(context, indirect);
986 }
987 
memoryBarrier(const gl::Context * context,GLbitfield barriers)988 angle::Result ContextGL::memoryBarrier(const gl::Context *context, GLbitfield barriers)
989 {
990     return mRenderer->memoryBarrier(barriers);
991 }
memoryBarrierByRegion(const gl::Context * context,GLbitfield barriers)992 angle::Result ContextGL::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
993 {
994     return mRenderer->memoryBarrierByRegion(barriers);
995 }
996 
framebufferFetchBarrier()997 void ContextGL::framebufferFetchBarrier()
998 {
999     mRenderer->framebufferFetchBarrier();
1000 }
1001 
startTiling(const gl::Context * context,const gl::Rectangle & area,GLbitfield preserveMask)1002 angle::Result ContextGL::startTiling(const gl::Context *context,
1003                                      const gl::Rectangle &area,
1004                                      GLbitfield preserveMask)
1005 {
1006     const FunctionsGL *functions = getFunctions();
1007     ANGLE_GL_TRY(context,
1008                  functions->startTilingQCOM(area.x, area.y, area.width, area.height, preserveMask));
1009     return angle::Result::Continue;
1010 }
1011 
endTiling(const gl::Context * context,GLbitfield preserveMask)1012 angle::Result ContextGL::endTiling(const gl::Context *context, GLbitfield preserveMask)
1013 {
1014     const FunctionsGL *functions = getFunctions();
1015     ANGLE_GL_TRY(context, functions->endTilingQCOM(preserveMask));
1016     return angle::Result::Continue;
1017 }
1018 
setMaxShaderCompilerThreads(GLuint count)1019 void ContextGL::setMaxShaderCompilerThreads(GLuint count)
1020 {
1021     mRenderer->setMaxShaderCompilerThreads(count);
1022 }
1023 
invalidateTexture(gl::TextureType target)1024 void ContextGL::invalidateTexture(gl::TextureType target)
1025 {
1026     mRenderer->getStateManager()->invalidateTexture(target);
1027 }
1028 
validateState() const1029 void ContextGL::validateState() const
1030 {
1031     const StateManagerGL *stateManager = mRenderer->getStateManager();
1032     stateManager->validateState();
1033 }
1034 
setNeedsFlushBeforeDeleteTextures()1035 void ContextGL::setNeedsFlushBeforeDeleteTextures()
1036 {
1037     mRenderer->setNeedsFlushBeforeDeleteTextures();
1038 }
1039 
flushIfNecessaryBeforeDeleteTextures()1040 void ContextGL::flushIfNecessaryBeforeDeleteTextures()
1041 {
1042     mRenderer->flushIfNecessaryBeforeDeleteTextures();
1043 }
1044 
markWorkSubmitted()1045 void ContextGL::markWorkSubmitted()
1046 {
1047     mRenderer->markWorkSubmitted();
1048 }
1049 
getMultiviewImplementationType() const1050 MultiviewImplementationTypeGL ContextGL::getMultiviewImplementationType() const
1051 {
1052     return mRenderer->getMultiviewImplementationType();
1053 }
1054 
hasNativeParallelCompile()1055 bool ContextGL::hasNativeParallelCompile()
1056 {
1057     return mRenderer->hasNativeParallelCompile();
1058 }
1059 
1060 }  // namespace rx
1061