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