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