1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
8 // rendering operations. It is the GLES2 specific implementation of EGLContext.
9
10 #include "libANGLE/Context.h"
11 #include "libANGLE/Context.inl.h"
12
13 #include <string.h>
14 #include <iterator>
15 #include <sstream>
16 #include <vector>
17
18 #include "common/PackedEnums.h"
19 #include "common/matrix_utils.h"
20 #include "common/platform.h"
21 #include "common/utilities.h"
22 #include "common/version.h"
23 #include "libANGLE/Buffer.h"
24 #include "libANGLE/Compiler.h"
25 #include "libANGLE/Display.h"
26 #include "libANGLE/Fence.h"
27 #include "libANGLE/FrameCapture.h"
28 #include "libANGLE/Framebuffer.h"
29 #include "libANGLE/FramebufferAttachment.h"
30 #include "libANGLE/MemoryObject.h"
31 #include "libANGLE/Program.h"
32 #include "libANGLE/ProgramPipeline.h"
33 #include "libANGLE/Query.h"
34 #include "libANGLE/Renderbuffer.h"
35 #include "libANGLE/ResourceManager.h"
36 #include "libANGLE/Sampler.h"
37 #include "libANGLE/Semaphore.h"
38 #include "libANGLE/Surface.h"
39 #include "libANGLE/Texture.h"
40 #include "libANGLE/TransformFeedback.h"
41 #include "libANGLE/VertexArray.h"
42 #include "libANGLE/formatutils.h"
43 #include "libANGLE/queryconversions.h"
44 #include "libANGLE/queryutils.h"
45 #include "libANGLE/renderer/DisplayImpl.h"
46 #include "libANGLE/renderer/Format.h"
47 #include "libANGLE/validationES.h"
48
49 namespace gl
50 {
51 namespace
52 {
AllocateOrGetShareGroup(egl::Display * display,const gl::Context * shareContext)53 egl::ShareGroup *AllocateOrGetShareGroup(egl::Display *display, const gl::Context *shareContext)
54 {
55 if (shareContext)
56 {
57 egl::ShareGroup *shareGroup = shareContext->getState().getShareGroup();
58 shareGroup->addRef();
59 return shareGroup;
60 }
61 else
62 {
63 return new egl::ShareGroup(display->getImplementation());
64 }
65 }
66
67 template <typename T>
GetQueryObjectParameter(const Context * context,Query * query,GLenum pname,T * params)68 angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params)
69 {
70 ASSERT(query != nullptr || pname == GL_QUERY_RESULT_AVAILABLE_EXT);
71
72 switch (pname)
73 {
74 case GL_QUERY_RESULT_EXT:
75 return query->getResult(context, params);
76 case GL_QUERY_RESULT_AVAILABLE_EXT:
77 {
78 bool available = false;
79 if (context->isContextLost())
80 {
81 available = true;
82 }
83 else
84 {
85 ANGLE_TRY(query->isResultAvailable(context, &available));
86 }
87 *params = CastFromStateValue<T>(pname, static_cast<GLuint>(available));
88 return angle::Result::Continue;
89 }
90 default:
91 UNREACHABLE();
92 return angle::Result::Stop;
93 }
94 }
95
96 // Attribute map queries.
GetClientMajorVersion(const egl::AttributeMap & attribs)97 EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
98 {
99 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
100 }
101
GetClientMinorVersion(const egl::AttributeMap & attribs)102 EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
103 {
104 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
105 }
106
GetBackwardCompatibleContext(const egl::AttributeMap & attribs)107 bool GetBackwardCompatibleContext(const egl::AttributeMap &attribs)
108 {
109 return attribs.get(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_TRUE) == EGL_TRUE;
110 }
111
GetClientVersion(egl::Display * display,const egl::AttributeMap & attribs)112 Version GetClientVersion(egl::Display *display, const egl::AttributeMap &attribs)
113 {
114 Version requestedVersion =
115 Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
116 if (GetBackwardCompatibleContext(attribs))
117 {
118 if (requestedVersion.major == 1)
119 {
120 // If the user requests an ES1 context, we cannot return an ES 2+ context.
121 return Version(1, 1);
122 }
123 else
124 {
125 // Always up the version to at least the max conformant version this display supports.
126 // Only return a higher client version if requested.
127 return std::max(display->getImplementation()->getMaxConformantESVersion(),
128 requestedVersion);
129 }
130 }
131 else
132 {
133 return requestedVersion;
134 }
135 }
136
GetResetStrategy(const egl::AttributeMap & attribs)137 GLenum GetResetStrategy(const egl::AttributeMap &attribs)
138 {
139 EGLAttrib attrib =
140 attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION);
141 switch (attrib)
142 {
143 case EGL_NO_RESET_NOTIFICATION:
144 return GL_NO_RESET_NOTIFICATION_EXT;
145 case EGL_LOSE_CONTEXT_ON_RESET:
146 return GL_LOSE_CONTEXT_ON_RESET_EXT;
147 default:
148 UNREACHABLE();
149 return GL_NONE;
150 }
151 }
152
GetRobustAccess(const egl::AttributeMap & attribs)153 bool GetRobustAccess(const egl::AttributeMap &attribs)
154 {
155 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
156 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
157 0);
158 }
159
GetDebug(const egl::AttributeMap & attribs)160 bool GetDebug(const egl::AttributeMap &attribs)
161 {
162 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
163 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
164 }
165
GetNoError(const egl::AttributeMap & attribs)166 bool GetNoError(const egl::AttributeMap &attribs)
167 {
168 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
169 }
170
GetWebGLContext(const egl::AttributeMap & attribs)171 bool GetWebGLContext(const egl::AttributeMap &attribs)
172 {
173 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
174 }
175
GetExtensionsEnabled(const egl::AttributeMap & attribs,bool webGLContext)176 bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext)
177 {
178 // If the context is WebGL, extensions are disabled by default
179 EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE;
180 return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE);
181 }
182
GetBindGeneratesResource(const egl::AttributeMap & attribs)183 bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
184 {
185 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
186 }
187
GetClientArraysEnabled(const egl::AttributeMap & attribs)188 bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
189 {
190 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
191 }
192
GetRobustResourceInit(const egl::AttributeMap & attribs)193 bool GetRobustResourceInit(const egl::AttributeMap &attribs)
194 {
195 return (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
196 }
197
GetContextPriority(const egl::AttributeMap & attribs)198 EGLenum GetContextPriority(const egl::AttributeMap &attribs)
199 {
200 return static_cast<EGLenum>(
201 attribs.getAsInt(EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_MEDIUM_IMG));
202 }
203
GetObjectLabelFromPointer(GLsizei length,const GLchar * label)204 std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
205 {
206 std::string labelName;
207 if (label != nullptr)
208 {
209 size_t labelLength = length < 0 ? strlen(label) : length;
210 labelName = std::string(label, labelLength);
211 }
212 return labelName;
213 }
214
GetObjectLabelBase(const std::string & objectLabel,GLsizei bufSize,GLsizei * length,GLchar * label)215 void GetObjectLabelBase(const std::string &objectLabel,
216 GLsizei bufSize,
217 GLsizei *length,
218 GLchar *label)
219 {
220 size_t writeLength = objectLabel.length();
221 if (label != nullptr && bufSize > 0)
222 {
223 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
224 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
225 label[writeLength] = '\0';
226 }
227
228 if (length != nullptr)
229 {
230 *length = static_cast<GLsizei>(writeLength);
231 }
232 }
233
234 // The rest default to false.
235 constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
236 kValidBasicDrawModes = {{
237 {PrimitiveMode::Points, true},
238 {PrimitiveMode::Lines, true},
239 {PrimitiveMode::LineLoop, true},
240 {PrimitiveMode::LineStrip, true},
241 {PrimitiveMode::Triangles, true},
242 {PrimitiveMode::TriangleStrip, true},
243 {PrimitiveMode::TriangleFan, true},
244 }};
245
246 enum SubjectIndexes : angle::SubjectIndex
247 {
248 kTexture0SubjectIndex = 0,
249 kTextureMaxSubjectIndex = kTexture0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
250 kImage0SubjectIndex = kTextureMaxSubjectIndex,
251 kImageMaxSubjectIndex = kImage0SubjectIndex + IMPLEMENTATION_MAX_IMAGE_UNITS,
252 kUniformBuffer0SubjectIndex = kImageMaxSubjectIndex,
253 kUniformBufferMaxSubjectIndex =
254 kUniformBuffer0SubjectIndex + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
255 kSampler0SubjectIndex = kUniformBufferMaxSubjectIndex,
256 kSamplerMaxSubjectIndex = kSampler0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
257 kVertexArraySubjectIndex = kSamplerMaxSubjectIndex,
258 kReadFramebufferSubjectIndex,
259 kDrawFramebufferSubjectIndex
260 };
261 } // anonymous namespace
262
Context(egl::Display * display,const egl::Config * config,const Context * shareContext,TextureManager * shareTextures,MemoryProgramCache * memoryProgramCache,const EGLenum clientType,const egl::AttributeMap & attribs,const egl::DisplayExtensions & displayExtensions,const egl::ClientExtensions & clientExtensions)263 Context::Context(egl::Display *display,
264 const egl::Config *config,
265 const Context *shareContext,
266 TextureManager *shareTextures,
267 MemoryProgramCache *memoryProgramCache,
268 const EGLenum clientType,
269 const egl::AttributeMap &attribs,
270 const egl::DisplayExtensions &displayExtensions,
271 const egl::ClientExtensions &clientExtensions)
272 : mState(shareContext ? &shareContext->mState : nullptr,
273 AllocateOrGetShareGroup(display, shareContext),
274 shareTextures,
275 &mOverlay,
276 clientType,
277 GetClientVersion(display, attribs),
278 GetDebug(attribs),
279 GetBindGeneratesResource(attribs),
280 GetClientArraysEnabled(attribs),
281 GetRobustResourceInit(attribs),
282 memoryProgramCache != nullptr,
283 GetContextPriority(attribs)),
284 mShared(shareContext != nullptr),
285 mSkipValidation(GetNoError(attribs)),
286 mDisplayTextureShareGroup(shareTextures != nullptr),
287 mErrors(this),
288 mImplementation(display->getImplementation()
289 ->createContext(mState, &mErrors, config, shareContext, attribs)),
290 mLabel(nullptr),
291 mCompiler(),
292 mConfig(config),
293 mHasBeenCurrent(false),
294 mContextLost(false),
295 mResetStatus(GraphicsResetStatus::NoError),
296 mContextLostForced(false),
297 mResetStrategy(GetResetStrategy(attribs)),
298 mRobustAccess(GetRobustAccess(attribs)),
299 mSurfacelessSupported(displayExtensions.surfacelessContext),
300 mExplicitContextAvailable(clientExtensions.explicitContext),
301 mCurrentDrawSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
302 mCurrentReadSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
303 mDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
304 mWebGLContext(GetWebGLContext(attribs)),
305 mBufferAccessValidationEnabled(false),
306 mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
307 mMemoryProgramCache(memoryProgramCache),
308 mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
309 mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
310 mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
311 mThreadPool(nullptr),
312 mFrameCapture(new angle::FrameCapture),
313 mOverlay(mImplementation.get())
314 {
315 for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex;
316 uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex)
317 {
318 mUniformBufferObserverBindings.emplace_back(this, uboIndex);
319 }
320
321 for (angle::SubjectIndex samplerIndex = kSampler0SubjectIndex;
322 samplerIndex < kSamplerMaxSubjectIndex; ++samplerIndex)
323 {
324 mSamplerObserverBindings.emplace_back(this, samplerIndex);
325 }
326
327 for (angle::SubjectIndex imageIndex = kImage0SubjectIndex; imageIndex < kImageMaxSubjectIndex;
328 ++imageIndex)
329 {
330 mImageObserverBindings.emplace_back(this, imageIndex);
331 }
332 }
333
initialize()334 void Context::initialize()
335 {
336 mImplementation->setMemoryProgramCache(mMemoryProgramCache);
337
338 initCaps();
339
340 if (mDisplay->getFrontendFeatures().syncFramebufferBindingsOnTexImage.enabled)
341 {
342 mTexImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
343 mTexImageDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
344 }
345
346 mState.initialize(this);
347
348 mFenceNVHandleAllocator.setBaseHandle(0);
349
350 // [OpenGL ES 2.0.24] section 3.7 page 83:
351 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
352 // and cube map texture state vectors respectively associated with them.
353 // In order that access to these initial textures not be lost, they are treated as texture
354 // objects all of whose names are 0.
355
356 Texture *zeroTexture2D = new Texture(mImplementation.get(), {0}, TextureType::_2D);
357 mZeroTextures[TextureType::_2D].set(this, zeroTexture2D);
358
359 Texture *zeroTextureCube = new Texture(mImplementation.get(), {0}, TextureType::CubeMap);
360 mZeroTextures[TextureType::CubeMap].set(this, zeroTextureCube);
361
362 if (getClientVersion() >= Version(3, 0) || mSupportedExtensions.texture3DOES)
363 {
364 Texture *zeroTexture3D = new Texture(mImplementation.get(), {0}, TextureType::_3D);
365 mZeroTextures[TextureType::_3D].set(this, zeroTexture3D);
366 }
367 if (getClientVersion() >= Version(3, 0))
368 {
369 Texture *zeroTexture2DArray =
370 new Texture(mImplementation.get(), {0}, TextureType::_2DArray);
371 mZeroTextures[TextureType::_2DArray].set(this, zeroTexture2DArray);
372 }
373 if (getClientVersion() >= Version(3, 1) || mSupportedExtensions.textureMultisample)
374 {
375 Texture *zeroTexture2DMultisample =
376 new Texture(mImplementation.get(), {0}, TextureType::_2DMultisample);
377 mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample);
378 }
379 if (getClientVersion() >= Version(3, 1))
380 {
381 Texture *zeroTexture2DMultisampleArray =
382 new Texture(mImplementation.get(), {0}, TextureType::_2DMultisampleArray);
383 mZeroTextures[TextureType::_2DMultisampleArray].set(this, zeroTexture2DMultisampleArray);
384
385 for (int i = 0; i < mState.mCaps.maxAtomicCounterBufferBindings; i++)
386 {
387 bindBufferRange(BufferBinding::AtomicCounter, i, {0}, 0, 0);
388 }
389
390 for (int i = 0; i < mState.mCaps.maxShaderStorageBufferBindings; i++)
391 {
392 bindBufferRange(BufferBinding::ShaderStorage, i, {0}, 0, 0);
393 }
394 }
395
396 if (getClientVersion() >= Version(3, 2) || mSupportedExtensions.textureCubeMapArrayAny())
397 {
398 Texture *zeroTextureCubeMapArray =
399 new Texture(mImplementation.get(), {0}, TextureType::CubeMapArray);
400 mZeroTextures[TextureType::CubeMapArray].set(this, zeroTextureCubeMapArray);
401 }
402
403 if (mSupportedExtensions.textureRectangle)
404 {
405 Texture *zeroTextureRectangle =
406 new Texture(mImplementation.get(), {0}, TextureType::Rectangle);
407 mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle);
408 }
409
410 if (mSupportedExtensions.eglImageExternalOES ||
411 mSupportedExtensions.eglStreamConsumerExternalNV)
412 {
413 Texture *zeroTextureExternal =
414 new Texture(mImplementation.get(), {0}, TextureType::External);
415 mZeroTextures[TextureType::External].set(this, zeroTextureExternal);
416 }
417
418 // This may change native TEXTURE_2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE,
419 // binding states. Ensure state manager is aware of this when binding
420 // this texture type.
421 if (mSupportedExtensions.webglVideoTexture)
422 {
423 Texture *zeroTextureVideoImage =
424 new Texture(mImplementation.get(), {0}, TextureType::VideoImage);
425 mZeroTextures[TextureType::VideoImage].set(this, zeroTextureVideoImage);
426 }
427
428 mState.initializeZeroTextures(this, mZeroTextures);
429
430 ANGLE_CONTEXT_TRY(mImplementation->initialize());
431
432 bindVertexArray({0});
433
434 if (getClientVersion() >= Version(3, 0))
435 {
436 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
437 // In the initial state, a default transform feedback object is bound and treated as
438 // a transform feedback object with a name of zero. That object is bound any time
439 // BindTransformFeedback is called with id of zero
440 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
441 }
442
443 for (auto type : angle::AllEnums<BufferBinding>())
444 {
445 bindBuffer(type, {0});
446 }
447
448 bindRenderbuffer(GL_RENDERBUFFER, {0});
449
450 for (int i = 0; i < mState.mCaps.maxUniformBufferBindings; i++)
451 {
452 bindBufferRange(BufferBinding::Uniform, i, {0}, 0, -1);
453 }
454
455 // Initialize GLES1 renderer if appropriate.
456 if (getClientVersion() < Version(2, 0))
457 {
458 mGLES1Renderer.reset(new GLES1Renderer());
459 }
460
461 // Initialize dirty bit masks
462 mAllDirtyBits.set();
463
464 mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
465 mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY);
466 mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
467 mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
468 mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
469 mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
470 mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
471
472 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
473 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
474 // No dirty objects.
475
476 // Readpixels uses the pack state and read FBO
477 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
478 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
479 mReadPixelsDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
480 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
481
482 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
483 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
484 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
485 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
486 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
487 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
488 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
489 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
490 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
491 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
492 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
493 mClearDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
494
495 // We sync the draw Framebuffer manually in prepareForClear to allow the clear calls to do
496 // more custom handling for robust resource init.
497
498 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
499 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
500 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
501 mBlitDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
502 mBlitDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
503 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
504 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
505
506 mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
507 mComputeDirtyBits.set(State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
508 mComputeDirtyBits.set(State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
509 mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING);
510 mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE);
511 mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS);
512 mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
513 mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS);
514 mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
515 mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
516 mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
517 mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
518 mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
519 mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
520
521 mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
522 mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
523
524 // Initialize overlay after implementation is initialized.
525 ANGLE_CONTEXT_TRY(mOverlay.init(this));
526 }
527
onDestroy(const egl::Display * display)528 egl::Error Context::onDestroy(const egl::Display *display)
529 {
530 // Dump frame capture if enabled.
531 mFrameCapture->onEndFrame(this);
532
533 if (mGLES1Renderer)
534 {
535 mGLES1Renderer->onDestroy(this, &mState);
536 }
537
538 ANGLE_TRY(unMakeCurrent(display));
539
540 for (auto fence : mFenceNVMap)
541 {
542 if (fence.second)
543 {
544 fence.second->onDestroy(this);
545 }
546 SafeDelete(fence.second);
547 }
548 mFenceNVMap.clear();
549
550 for (auto query : mQueryMap)
551 {
552 if (query.second != nullptr)
553 {
554 query.second->release(this);
555 }
556 }
557 mQueryMap.clear();
558
559 for (auto vertexArray : mVertexArrayMap)
560 {
561 if (vertexArray.second)
562 {
563 vertexArray.second->onDestroy(this);
564 }
565 }
566 mVertexArrayMap.clear();
567
568 for (auto transformFeedback : mTransformFeedbackMap)
569 {
570 if (transformFeedback.second != nullptr)
571 {
572 transformFeedback.second->release(this);
573 }
574 }
575 mTransformFeedbackMap.clear();
576
577 for (BindingPointer<Texture> &zeroTexture : mZeroTextures)
578 {
579 if (zeroTexture.get() != nullptr)
580 {
581 zeroTexture.set(this, nullptr);
582 }
583 }
584
585 releaseShaderCompiler();
586
587 mState.reset(this);
588
589 mState.mBufferManager->release(this);
590 // mProgramPipelineManager must be before mShaderProgramManager to give each
591 // PPO the chance to release any references they have to the Programs that
592 // are bound to them before the Programs are released()'ed.
593 mState.mProgramPipelineManager->release(this);
594 mState.mShaderProgramManager->release(this);
595 mState.mTextureManager->release(this);
596 mState.mRenderbufferManager->release(this);
597 mState.mSamplerManager->release(this);
598 mState.mSyncManager->release(this);
599 mState.mFramebufferManager->release(this);
600 mState.mMemoryObjectManager->release(this);
601 mState.mSemaphoreManager->release(this);
602 mState.mShareGroup->release(this);
603
604 mThreadPool.reset();
605
606 mImplementation->onDestroy(this);
607
608 mOverlay.destroy(this);
609
610 return egl::NoError();
611 }
612
~Context()613 Context::~Context() {}
614
setLabel(EGLLabelKHR label)615 void Context::setLabel(EGLLabelKHR label)
616 {
617 mLabel = label;
618 }
619
getLabel() const620 EGLLabelKHR Context::getLabel() const
621 {
622 return mLabel;
623 }
624
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface)625 egl::Error Context::makeCurrent(egl::Display *display,
626 egl::Surface *drawSurface,
627 egl::Surface *readSurface)
628 {
629 mDisplay = display;
630
631 if (!mHasBeenCurrent)
632 {
633 initialize();
634 initRendererString();
635 initVersionStrings();
636 initExtensionStrings();
637
638 int width = 0;
639 int height = 0;
640 if (drawSurface != nullptr)
641 {
642 width = drawSurface->getWidth();
643 height = drawSurface->getHeight();
644 }
645
646 mState.setViewportParams(0, 0, width, height);
647 mState.setScissorParams(0, 0, width, height);
648
649 mHasBeenCurrent = true;
650 }
651
652 // TODO(jmadill): Rework this when we support ContextImpl
653 mState.setAllDirtyBits();
654 mState.setAllDirtyObjects();
655
656 ANGLE_TRY(setDefaultFramebuffer(drawSurface, readSurface));
657
658 // Notify the renderer of a context switch.
659 angle::Result implResult = mImplementation->onMakeCurrent(this);
660
661 // If the implementation fails onMakeCurrent, unset the default framebuffer.
662 if (implResult != angle::Result::Continue)
663 {
664 ANGLE_TRY(unsetDefaultFramebuffer());
665 return angle::ResultToEGL(implResult);
666 }
667
668 return egl::NoError();
669 }
670
unMakeCurrent(const egl::Display * display)671 egl::Error Context::unMakeCurrent(const egl::Display *display)
672 {
673 ANGLE_TRY(unsetDefaultFramebuffer());
674
675 ANGLE_TRY(angle::ResultToEGL(mImplementation->onUnMakeCurrent(this)));
676
677 // Return the scratch buffers to the display so they can be shared with other contexts while
678 // this one is not current.
679 if (mScratchBuffer.valid())
680 {
681 mDisplay->returnScratchBuffer(mScratchBuffer.release());
682 }
683 if (mZeroFilledBuffer.valid())
684 {
685 mDisplay->returnZeroFilledBuffer(mZeroFilledBuffer.release());
686 }
687
688 return egl::NoError();
689 }
690
createBuffer()691 BufferID Context::createBuffer()
692 {
693 return mState.mBufferManager->createBuffer();
694 }
695
createProgram()696 GLuint Context::createProgram()
697 {
698 return mState.mShaderProgramManager->createProgram(mImplementation.get()).value;
699 }
700
createShader(ShaderType type)701 GLuint Context::createShader(ShaderType type)
702 {
703 return mState.mShaderProgramManager
704 ->createShader(mImplementation.get(), mState.mLimitations, type)
705 .value;
706 }
707
createTexture()708 TextureID Context::createTexture()
709 {
710 return mState.mTextureManager->createTexture();
711 }
712
createRenderbuffer()713 RenderbufferID Context::createRenderbuffer()
714 {
715 return mState.mRenderbufferManager->createRenderbuffer();
716 }
717
718 // Returns an unused framebuffer name
createFramebuffer()719 FramebufferID Context::createFramebuffer()
720 {
721 return mState.mFramebufferManager->createFramebuffer();
722 }
723
genFencesNV(GLsizei n,FenceNVID * fences)724 void Context::genFencesNV(GLsizei n, FenceNVID *fences)
725 {
726 for (int i = 0; i < n; i++)
727 {
728 GLuint handle = mFenceNVHandleAllocator.allocate();
729 mFenceNVMap.assign({handle}, new FenceNV(mImplementation.get()));
730 fences[i] = {handle};
731 }
732 }
733
createProgramPipeline()734 ProgramPipelineID Context::createProgramPipeline()
735 {
736 return mState.mProgramPipelineManager->createProgramPipeline();
737 }
738
createShaderProgramv(ShaderType type,GLsizei count,const GLchar * const * strings)739 GLuint Context::createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings)
740 {
741 const ShaderProgramID shaderID = FromGL<ShaderProgramID>(createShader(type));
742 if (shaderID.value)
743 {
744 Shader *shaderObject = getShader(shaderID);
745 ASSERT(shaderObject);
746 shaderObject->setSource(count, strings, nullptr);
747 shaderObject->compile(this);
748 const ShaderProgramID programID = FromGL<ShaderProgramID>(createProgram());
749 if (programID.value)
750 {
751 gl::Program *programObject = getProgramNoResolveLink(programID);
752 ASSERT(programObject);
753
754 if (shaderObject->isCompiled())
755 {
756 // As per Khronos issue 2261:
757 // https://gitlab.khronos.org/Tracker/vk-gl-cts/issues/2261
758 // We must wait to mark the program separable until it's successfully compiled.
759 programObject->setSeparable(true);
760
761 programObject->attachShader(this, shaderObject);
762
763 if (programObject->link(this) != angle::Result::Continue)
764 {
765 deleteShader(shaderID);
766 deleteProgram(programID);
767 return 0u;
768 }
769 if (onProgramLink(programObject) != angle::Result::Continue)
770 {
771 deleteShader(shaderID);
772 deleteProgram(programID);
773 return 0u;
774 }
775
776 // Need to manually resolveLink(), since onProgramLink() doesn't think the program
777 // is in use. For the normal glDetachShader() API call path, this is done during
778 // ValidateDetachShader() via gl::GetValidProgram().
779 programObject->resolveLink(this);
780 programObject->detachShader(this, shaderObject);
781 }
782
783 InfoLog &programInfoLog = programObject->getExecutable().getInfoLog();
784 programInfoLog << shaderObject->getInfoLogString();
785 }
786
787 deleteShader(shaderID);
788
789 return programID.value;
790 }
791
792 return 0u;
793 }
794
createMemoryObject()795 MemoryObjectID Context::createMemoryObject()
796 {
797 return mState.mMemoryObjectManager->createMemoryObject(mImplementation.get());
798 }
799
createSemaphore()800 SemaphoreID Context::createSemaphore()
801 {
802 return mState.mSemaphoreManager->createSemaphore(mImplementation.get());
803 }
804
deleteBuffer(BufferID bufferName)805 void Context::deleteBuffer(BufferID bufferName)
806 {
807 Buffer *buffer = mState.mBufferManager->getBuffer(bufferName);
808 if (buffer)
809 {
810 detachBuffer(buffer);
811 }
812
813 mState.mBufferManager->deleteObject(this, bufferName);
814 }
815
deleteShader(ShaderProgramID shader)816 void Context::deleteShader(ShaderProgramID shader)
817 {
818 mState.mShaderProgramManager->deleteShader(this, shader);
819 }
820
deleteProgram(ShaderProgramID program)821 void Context::deleteProgram(ShaderProgramID program)
822 {
823 mState.mShaderProgramManager->deleteProgram(this, program);
824 }
825
deleteTexture(TextureID texture)826 void Context::deleteTexture(TextureID texture)
827 {
828 if (mState.mTextureManager->getTexture(texture))
829 {
830 detachTexture(texture);
831 }
832
833 mState.mTextureManager->deleteObject(this, texture);
834 }
835
deleteRenderbuffer(RenderbufferID renderbuffer)836 void Context::deleteRenderbuffer(RenderbufferID renderbuffer)
837 {
838 if (mState.mRenderbufferManager->getRenderbuffer(renderbuffer))
839 {
840 detachRenderbuffer(renderbuffer);
841 }
842
843 mState.mRenderbufferManager->deleteObject(this, renderbuffer);
844 }
845
deleteSync(GLsync sync)846 void Context::deleteSync(GLsync sync)
847 {
848 // The spec specifies the underlying Fence object is not deleted until all current
849 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
850 // and since our API is currently designed for being called from a single thread, we can delete
851 // the fence immediately.
852 mState.mSyncManager->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
853 }
854
deleteProgramPipeline(ProgramPipelineID pipelineID)855 void Context::deleteProgramPipeline(ProgramPipelineID pipelineID)
856 {
857 ProgramPipeline *pipeline = mState.mProgramPipelineManager->getProgramPipeline(pipelineID);
858 if (pipeline)
859 {
860 detachProgramPipeline(pipelineID);
861 }
862
863 mState.mProgramPipelineManager->deleteObject(this, pipelineID);
864 }
865
deleteMemoryObject(MemoryObjectID memoryObject)866 void Context::deleteMemoryObject(MemoryObjectID memoryObject)
867 {
868 mState.mMemoryObjectManager->deleteMemoryObject(this, memoryObject);
869 }
870
deleteSemaphore(SemaphoreID semaphore)871 void Context::deleteSemaphore(SemaphoreID semaphore)
872 {
873 mState.mSemaphoreManager->deleteSemaphore(this, semaphore);
874 }
875
876 // GL_CHROMIUM_lose_context
loseContext(GraphicsResetStatus current,GraphicsResetStatus other)877 void Context::loseContext(GraphicsResetStatus current, GraphicsResetStatus other)
878 {
879 // TODO(geofflang): mark the rest of the share group lost. Requires access to the entire share
880 // group from a context. http://anglebug.com/3379
881 markContextLost(current);
882 }
883
deleteFramebuffer(FramebufferID framebuffer)884 void Context::deleteFramebuffer(FramebufferID framebuffer)
885 {
886 if (mState.mFramebufferManager->getFramebuffer(framebuffer))
887 {
888 detachFramebuffer(framebuffer);
889 }
890
891 mState.mFramebufferManager->deleteObject(this, framebuffer);
892 }
893
deleteFencesNV(GLsizei n,const FenceNVID * fences)894 void Context::deleteFencesNV(GLsizei n, const FenceNVID *fences)
895 {
896 for (int i = 0; i < n; i++)
897 {
898 FenceNVID fence = fences[i];
899
900 FenceNV *fenceObject = nullptr;
901 if (mFenceNVMap.erase(fence, &fenceObject))
902 {
903 mFenceNVHandleAllocator.release(fence.value);
904 if (fenceObject)
905 {
906 fenceObject->onDestroy(this);
907 }
908 delete fenceObject;
909 }
910 }
911 }
912
getBuffer(BufferID handle) const913 Buffer *Context::getBuffer(BufferID handle) const
914 {
915 return mState.mBufferManager->getBuffer(handle);
916 }
917
getRenderbuffer(RenderbufferID handle) const918 Renderbuffer *Context::getRenderbuffer(RenderbufferID handle) const
919 {
920 return mState.mRenderbufferManager->getRenderbuffer(handle);
921 }
922
getContextPriority() const923 EGLenum Context::getContextPriority() const
924 {
925 return egl::ToEGLenum(mImplementation->getContextPriority());
926 }
927
getSync(GLsync handle) const928 Sync *Context::getSync(GLsync handle) const
929 {
930 return mState.mSyncManager->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
931 }
932
getVertexArray(VertexArrayID handle) const933 VertexArray *Context::getVertexArray(VertexArrayID handle) const
934 {
935 return mVertexArrayMap.query(handle);
936 }
937
getSampler(SamplerID handle) const938 Sampler *Context::getSampler(SamplerID handle) const
939 {
940 return mState.mSamplerManager->getSampler(handle);
941 }
942
getTransformFeedback(TransformFeedbackID handle) const943 TransformFeedback *Context::getTransformFeedback(TransformFeedbackID handle) const
944 {
945 return mTransformFeedbackMap.query(handle);
946 }
947
getProgramPipeline(ProgramPipelineID handle) const948 ProgramPipeline *Context::getProgramPipeline(ProgramPipelineID handle) const
949 {
950 return mState.mProgramPipelineManager->getProgramPipeline(handle);
951 }
952
getLabeledObject(GLenum identifier,GLuint name) const953 gl::LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
954 {
955 switch (identifier)
956 {
957 case GL_BUFFER:
958 return getBuffer({name});
959 case GL_SHADER:
960 return getShader({name});
961 case GL_PROGRAM:
962 return getProgramNoResolveLink({name});
963 case GL_VERTEX_ARRAY:
964 return getVertexArray({name});
965 case GL_QUERY:
966 return getQuery({name});
967 case GL_TRANSFORM_FEEDBACK:
968 return getTransformFeedback({name});
969 case GL_SAMPLER:
970 return getSampler({name});
971 case GL_TEXTURE:
972 return getTexture({name});
973 case GL_RENDERBUFFER:
974 return getRenderbuffer({name});
975 case GL_FRAMEBUFFER:
976 return getFramebuffer({name});
977 case GL_PROGRAM_PIPELINE:
978 return getProgramPipeline({name});
979 default:
980 UNREACHABLE();
981 return nullptr;
982 }
983 }
984
getLabeledObjectFromPtr(const void * ptr) const985 gl::LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
986 {
987 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
988 }
989
objectLabel(GLenum identifier,GLuint name,GLsizei length,const GLchar * label)990 void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
991 {
992 gl::LabeledObject *object = getLabeledObject(identifier, name);
993 ASSERT(object != nullptr);
994
995 std::string labelName = GetObjectLabelFromPointer(length, label);
996 object->setLabel(this, labelName);
997
998 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
999 // specified object is active until we do this.
1000 mState.setObjectDirty(identifier);
1001 }
1002
objectPtrLabel(const void * ptr,GLsizei length,const GLchar * label)1003 void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
1004 {
1005 gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
1006 ASSERT(object != nullptr);
1007
1008 std::string labelName = GetObjectLabelFromPointer(length, label);
1009 object->setLabel(this, labelName);
1010 }
1011
getObjectLabel(GLenum identifier,GLuint name,GLsizei bufSize,GLsizei * length,GLchar * label)1012 void Context::getObjectLabel(GLenum identifier,
1013 GLuint name,
1014 GLsizei bufSize,
1015 GLsizei *length,
1016 GLchar *label)
1017 {
1018 gl::LabeledObject *object = getLabeledObject(identifier, name);
1019 ASSERT(object != nullptr);
1020
1021 const std::string &objectLabel = object->getLabel();
1022 GetObjectLabelBase(objectLabel, bufSize, length, label);
1023 }
1024
getObjectPtrLabel(const void * ptr,GLsizei bufSize,GLsizei * length,GLchar * label)1025 void Context::getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)
1026 {
1027 gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
1028 ASSERT(object != nullptr);
1029
1030 const std::string &objectLabel = object->getLabel();
1031 GetObjectLabelBase(objectLabel, bufSize, length, label);
1032 }
1033
isSampler(SamplerID samplerName) const1034 GLboolean Context::isSampler(SamplerID samplerName) const
1035 {
1036 return mState.mSamplerManager->isSampler(samplerName);
1037 }
1038
bindTexture(TextureType target,TextureID handle)1039 void Context::bindTexture(TextureType target, TextureID handle)
1040 {
1041 Texture *texture = nullptr;
1042
1043 if (handle.value == 0)
1044 {
1045 texture = mZeroTextures[target].get();
1046 }
1047 else
1048 {
1049 texture =
1050 mState.mTextureManager->checkTextureAllocation(mImplementation.get(), handle, target);
1051 }
1052
1053 ASSERT(texture);
1054 mState.setSamplerTexture(this, target, texture);
1055 mStateCache.onActiveTextureChange(this);
1056 }
1057
bindReadFramebuffer(FramebufferID framebufferHandle)1058 void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
1059 {
1060 Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
1061 mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID());
1062 mState.setReadFramebufferBinding(framebuffer);
1063 mReadFramebufferObserverBinding.bind(framebuffer);
1064 }
1065
bindDrawFramebuffer(FramebufferID framebufferHandle)1066 void Context::bindDrawFramebuffer(FramebufferID framebufferHandle)
1067 {
1068 Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
1069 mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID());
1070 mState.setDrawFramebufferBinding(framebuffer);
1071 mDrawFramebufferObserverBinding.bind(framebuffer);
1072 mStateCache.onDrawFramebufferChange(this);
1073 }
1074
bindVertexArray(VertexArrayID vertexArrayHandle)1075 void Context::bindVertexArray(VertexArrayID vertexArrayHandle)
1076 {
1077 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
1078 mState.setVertexArrayBinding(this, vertexArray);
1079 mVertexArrayObserverBinding.bind(vertexArray);
1080 mStateCache.onVertexArrayBindingChange(this);
1081 }
1082
bindVertexBuffer(GLuint bindingIndex,BufferID bufferHandle,GLintptr offset,GLsizei stride)1083 void Context::bindVertexBuffer(GLuint bindingIndex,
1084 BufferID bufferHandle,
1085 GLintptr offset,
1086 GLsizei stride)
1087 {
1088 Buffer *buffer =
1089 mState.mBufferManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
1090 mState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
1091 mStateCache.onVertexArrayStateChange(this);
1092 }
1093
bindSampler(GLuint textureUnit,SamplerID samplerHandle)1094 void Context::bindSampler(GLuint textureUnit, SamplerID samplerHandle)
1095 {
1096 ASSERT(textureUnit < static_cast<GLuint>(mState.mCaps.maxCombinedTextureImageUnits));
1097 Sampler *sampler =
1098 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
1099 mState.setSamplerBinding(this, textureUnit, sampler);
1100 mSamplerObserverBindings[textureUnit].bind(sampler);
1101 mStateCache.onActiveTextureChange(this);
1102 }
1103
bindImageTexture(GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1104 void Context::bindImageTexture(GLuint unit,
1105 TextureID texture,
1106 GLint level,
1107 GLboolean layered,
1108 GLint layer,
1109 GLenum access,
1110 GLenum format)
1111 {
1112 Texture *tex = mState.mTextureManager->getTexture(texture);
1113 mState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1114 mImageObserverBindings[unit].bind(tex);
1115 }
1116
useProgram(ShaderProgramID program)1117 void Context::useProgram(ShaderProgramID program)
1118 {
1119 ANGLE_CONTEXT_TRY(mState.setProgram(this, getProgramResolveLink(program)));
1120 mStateCache.onProgramExecutableChange(this);
1121 }
1122
useProgramStages(ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID program)1123 void Context::useProgramStages(ProgramPipelineID pipeline,
1124 GLbitfield stages,
1125 ShaderProgramID program)
1126 {
1127 Program *shaderProgram = getProgramNoResolveLink(program);
1128 ProgramPipeline *programPipeline =
1129 mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
1130 pipeline);
1131
1132 ASSERT(programPipeline);
1133 ANGLE_CONTEXT_TRY(mState.useProgramStages(this, programPipeline, stages, shaderProgram));
1134 mStateCache.onProgramExecutableChange(this);
1135 }
1136
bindTransformFeedback(GLenum target,TransformFeedbackID transformFeedbackHandle)1137 void Context::bindTransformFeedback(GLenum target, TransformFeedbackID transformFeedbackHandle)
1138 {
1139 ASSERT(target == GL_TRANSFORM_FEEDBACK);
1140 TransformFeedback *transformFeedback =
1141 checkTransformFeedbackAllocation(transformFeedbackHandle);
1142 mState.setTransformFeedbackBinding(this, transformFeedback);
1143 }
1144
bindProgramPipeline(ProgramPipelineID pipelineHandle)1145 void Context::bindProgramPipeline(ProgramPipelineID pipelineHandle)
1146 {
1147 ProgramPipeline *pipeline = mState.mProgramPipelineManager->checkProgramPipelineAllocation(
1148 mImplementation.get(), pipelineHandle);
1149 ANGLE_CONTEXT_TRY(mState.setProgramPipelineBinding(this, pipeline));
1150 mStateCache.onProgramExecutableChange(this);
1151 }
1152
beginQuery(QueryType target,QueryID query)1153 void Context::beginQuery(QueryType target, QueryID query)
1154 {
1155 Query *queryObject = getOrCreateQuery(query, target);
1156 ASSERT(queryObject);
1157
1158 // begin query
1159 ANGLE_CONTEXT_TRY(queryObject->begin(this));
1160
1161 // set query as active for specified target only if begin succeeded
1162 mState.setActiveQuery(this, target, queryObject);
1163 mStateCache.onQueryChange(this);
1164 }
1165
endQuery(QueryType target)1166 void Context::endQuery(QueryType target)
1167 {
1168 Query *queryObject = mState.getActiveQuery(target);
1169 ASSERT(queryObject);
1170
1171 // Intentionally don't call try here. We don't want an early return.
1172 (void)(queryObject->end(this));
1173
1174 // Always unbind the query, even if there was an error. This may delete the query object.
1175 mState.setActiveQuery(this, target, nullptr);
1176 mStateCache.onQueryChange(this);
1177 }
1178
queryCounter(QueryID id,QueryType target)1179 void Context::queryCounter(QueryID id, QueryType target)
1180 {
1181 ASSERT(target == QueryType::Timestamp);
1182
1183 Query *queryObject = getOrCreateQuery(id, target);
1184 ASSERT(queryObject);
1185
1186 ANGLE_CONTEXT_TRY(queryObject->queryCounter(this));
1187 }
1188
getQueryiv(QueryType target,GLenum pname,GLint * params)1189 void Context::getQueryiv(QueryType target, GLenum pname, GLint *params)
1190 {
1191 switch (pname)
1192 {
1193 case GL_CURRENT_QUERY_EXT:
1194 params[0] = mState.getActiveQueryId(target).value;
1195 break;
1196 case GL_QUERY_COUNTER_BITS_EXT:
1197 switch (target)
1198 {
1199 case QueryType::TimeElapsed:
1200 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1201 break;
1202 case QueryType::Timestamp:
1203 params[0] = getExtensions().queryCounterBitsTimestamp;
1204 break;
1205 default:
1206 UNREACHABLE();
1207 params[0] = 0;
1208 break;
1209 }
1210 break;
1211 default:
1212 UNREACHABLE();
1213 return;
1214 }
1215 }
1216
getQueryivRobust(QueryType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1217 void Context::getQueryivRobust(QueryType target,
1218 GLenum pname,
1219 GLsizei bufSize,
1220 GLsizei *length,
1221 GLint *params)
1222 {
1223 getQueryiv(target, pname, params);
1224 }
1225
getUnsignedBytev(GLenum pname,GLubyte * data)1226 void Context::getUnsignedBytev(GLenum pname, GLubyte *data)
1227 {
1228 UNIMPLEMENTED();
1229 }
1230
getUnsignedBytei_v(GLenum target,GLuint index,GLubyte * data)1231 void Context::getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data)
1232 {
1233 UNIMPLEMENTED();
1234 }
1235
getQueryObjectiv(QueryID id,GLenum pname,GLint * params)1236 void Context::getQueryObjectiv(QueryID id, GLenum pname, GLint *params)
1237 {
1238 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1239 }
1240
getQueryObjectivRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1241 void Context::getQueryObjectivRobust(QueryID id,
1242 GLenum pname,
1243 GLsizei bufSize,
1244 GLsizei *length,
1245 GLint *params)
1246 {
1247 getQueryObjectiv(id, pname, params);
1248 }
1249
getQueryObjectuiv(QueryID id,GLenum pname,GLuint * params)1250 void Context::getQueryObjectuiv(QueryID id, GLenum pname, GLuint *params)
1251 {
1252 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1253 }
1254
getQueryObjectuivRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)1255 void Context::getQueryObjectuivRobust(QueryID id,
1256 GLenum pname,
1257 GLsizei bufSize,
1258 GLsizei *length,
1259 GLuint *params)
1260 {
1261 getQueryObjectuiv(id, pname, params);
1262 }
1263
getQueryObjecti64v(QueryID id,GLenum pname,GLint64 * params)1264 void Context::getQueryObjecti64v(QueryID id, GLenum pname, GLint64 *params)
1265 {
1266 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1267 }
1268
getQueryObjecti64vRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLint64 * params)1269 void Context::getQueryObjecti64vRobust(QueryID id,
1270 GLenum pname,
1271 GLsizei bufSize,
1272 GLsizei *length,
1273 GLint64 *params)
1274 {
1275 getQueryObjecti64v(id, pname, params);
1276 }
1277
getQueryObjectui64v(QueryID id,GLenum pname,GLuint64 * params)1278 void Context::getQueryObjectui64v(QueryID id, GLenum pname, GLuint64 *params)
1279 {
1280 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1281 }
1282
getQueryObjectui64vRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint64 * params)1283 void Context::getQueryObjectui64vRobust(QueryID id,
1284 GLenum pname,
1285 GLsizei bufSize,
1286 GLsizei *length,
1287 GLuint64 *params)
1288 {
1289 getQueryObjectui64v(id, pname, params);
1290 }
1291
getFramebuffer(FramebufferID handle) const1292 Framebuffer *Context::getFramebuffer(FramebufferID handle) const
1293 {
1294 return mState.mFramebufferManager->getFramebuffer(handle);
1295 }
1296
getFenceNV(FenceNVID handle) const1297 FenceNV *Context::getFenceNV(FenceNVID handle) const
1298 {
1299 return mFenceNVMap.query(handle);
1300 }
1301
getOrCreateQuery(QueryID handle,QueryType type)1302 Query *Context::getOrCreateQuery(QueryID handle, QueryType type)
1303 {
1304 if (!mQueryMap.contains(handle))
1305 {
1306 return nullptr;
1307 }
1308
1309 Query *query = mQueryMap.query(handle);
1310 if (!query)
1311 {
1312 ASSERT(type != QueryType::InvalidEnum);
1313 query = new Query(mImplementation.get(), type, handle);
1314 query->addRef();
1315 mQueryMap.assign(handle, query);
1316 }
1317 return query;
1318 }
1319
getQuery(QueryID handle) const1320 Query *Context::getQuery(QueryID handle) const
1321 {
1322 return mQueryMap.query(handle);
1323 }
1324
getTextureByType(TextureType type) const1325 Texture *Context::getTextureByType(TextureType type) const
1326 {
1327 ASSERT(ValidTextureTarget(this, type) || ValidTextureExternalTarget(this, type));
1328 return mState.getTargetTexture(type);
1329 }
1330
getTextureByTarget(TextureTarget target) const1331 Texture *Context::getTextureByTarget(TextureTarget target) const
1332 {
1333 return getTextureByType(TextureTargetToType(target));
1334 }
1335
getSamplerTexture(unsigned int sampler,TextureType type) const1336 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1337 {
1338 return mState.getSamplerTexture(sampler, type);
1339 }
1340
getCompiler() const1341 Compiler *Context::getCompiler() const
1342 {
1343 if (mCompiler.get() == nullptr)
1344 {
1345 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
1346 }
1347 return mCompiler.get();
1348 }
1349
getBooleanvImpl(GLenum pname,GLboolean * params) const1350 void Context::getBooleanvImpl(GLenum pname, GLboolean *params) const
1351 {
1352 switch (pname)
1353 {
1354 case GL_SHADER_COMPILER:
1355 *params = GL_TRUE;
1356 break;
1357 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1358 *params = ConvertToGLBoolean(mRobustAccess);
1359 break;
1360
1361 default:
1362 mState.getBooleanv(pname, params);
1363 break;
1364 }
1365 }
1366
getFloatvImpl(GLenum pname,GLfloat * params) const1367 void Context::getFloatvImpl(GLenum pname, GLfloat *params) const
1368 {
1369 // Queries about context capabilities and maximums are answered by Context.
1370 // Queries about current GL state values are answered by State.
1371 switch (pname)
1372 {
1373 case GL_ALIASED_LINE_WIDTH_RANGE:
1374 params[0] = mState.mCaps.minAliasedLineWidth;
1375 params[1] = mState.mCaps.maxAliasedLineWidth;
1376 break;
1377 case GL_ALIASED_POINT_SIZE_RANGE:
1378 params[0] = mState.mCaps.minAliasedPointSize;
1379 params[1] = mState.mCaps.maxAliasedPointSize;
1380 break;
1381 case GL_SMOOTH_POINT_SIZE_RANGE:
1382 params[0] = mState.mCaps.minSmoothPointSize;
1383 params[1] = mState.mCaps.maxSmoothPointSize;
1384 break;
1385 case GL_SMOOTH_LINE_WIDTH_RANGE:
1386 params[0] = mState.mCaps.minSmoothLineWidth;
1387 params[1] = mState.mCaps.maxSmoothLineWidth;
1388 break;
1389 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1390 ASSERT(mState.mExtensions.textureFilterAnisotropic);
1391 *params = mState.mExtensions.maxTextureAnisotropy;
1392 break;
1393 case GL_MAX_TEXTURE_LOD_BIAS:
1394 *params = mState.mCaps.maxLODBias;
1395 break;
1396 default:
1397 mState.getFloatv(pname, params);
1398 break;
1399 }
1400 }
1401
getIntegervImpl(GLenum pname,GLint * params) const1402 void Context::getIntegervImpl(GLenum pname, GLint *params) const
1403 {
1404 // Queries about context capabilities and maximums are answered by Context.
1405 // Queries about current GL state values are answered by State.
1406
1407 switch (pname)
1408 {
1409 case GL_MAX_VERTEX_ATTRIBS:
1410 *params = mState.mCaps.maxVertexAttributes;
1411 break;
1412 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1413 *params = mState.mCaps.maxVertexUniformVectors;
1414 break;
1415 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1416 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Vertex];
1417 break;
1418 case GL_MAX_VARYING_VECTORS:
1419 *params = mState.mCaps.maxVaryingVectors;
1420 break;
1421 case GL_MAX_VARYING_COMPONENTS:
1422 *params = mState.mCaps.maxVaryingVectors * 4;
1423 break;
1424 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1425 *params = mState.mCaps.maxCombinedTextureImageUnits;
1426 break;
1427 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1428 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Vertex];
1429 break;
1430 case GL_MAX_TEXTURE_IMAGE_UNITS:
1431 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Fragment];
1432 break;
1433 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1434 *params = mState.mCaps.maxFragmentUniformVectors;
1435 break;
1436 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1437 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Fragment];
1438 break;
1439 case GL_MAX_RENDERBUFFER_SIZE:
1440 *params = mState.mCaps.maxRenderbufferSize;
1441 break;
1442 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1443 *params = mState.mCaps.maxColorAttachments;
1444 break;
1445 case GL_MAX_DRAW_BUFFERS_EXT:
1446 *params = mState.mCaps.maxDrawBuffers;
1447 break;
1448 case GL_SUBPIXEL_BITS:
1449 *params = mState.mCaps.subPixelBits;
1450 break;
1451 case GL_MAX_TEXTURE_SIZE:
1452 *params = mState.mCaps.max2DTextureSize;
1453 break;
1454 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1455 *params = mState.mCaps.maxRectangleTextureSize;
1456 break;
1457 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1458 *params = mState.mCaps.maxCubeMapTextureSize;
1459 break;
1460 case GL_MAX_3D_TEXTURE_SIZE:
1461 *params = mState.mCaps.max3DTextureSize;
1462 break;
1463 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1464 *params = mState.mCaps.maxArrayTextureLayers;
1465 break;
1466 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1467 *params = mState.mCaps.uniformBufferOffsetAlignment;
1468 break;
1469 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1470 *params = mState.mCaps.maxUniformBufferBindings;
1471 break;
1472 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1473 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex];
1474 break;
1475 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1476 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment];
1477 break;
1478 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1479 *params = mState.mCaps.maxCombinedUniformBlocks;
1480 break;
1481 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1482 *params = mState.mCaps.maxVertexOutputComponents;
1483 break;
1484 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1485 *params = mState.mCaps.maxFragmentInputComponents;
1486 break;
1487 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1488 *params = mState.mCaps.minProgramTexelOffset;
1489 break;
1490 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1491 *params = mState.mCaps.maxProgramTexelOffset;
1492 break;
1493 case GL_MAJOR_VERSION:
1494 *params = getClientVersion().major;
1495 break;
1496 case GL_MINOR_VERSION:
1497 *params = getClientVersion().minor;
1498 break;
1499 case GL_MAX_ELEMENTS_INDICES:
1500 *params = mState.mCaps.maxElementsIndices;
1501 break;
1502 case GL_MAX_ELEMENTS_VERTICES:
1503 *params = mState.mCaps.maxElementsVertices;
1504 break;
1505 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1506 *params = mState.mCaps.maxTransformFeedbackInterleavedComponents;
1507 break;
1508 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1509 *params = mState.mCaps.maxTransformFeedbackSeparateAttributes;
1510 break;
1511 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1512 *params = mState.mCaps.maxTransformFeedbackSeparateComponents;
1513 break;
1514 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1515 *params = static_cast<GLint>(mState.mCaps.compressedTextureFormats.size());
1516 break;
1517 case GL_MAX_SAMPLES_ANGLE:
1518 *params = mState.mCaps.maxSamples;
1519 break;
1520 case GL_MAX_VIEWPORT_DIMS:
1521 {
1522 params[0] = mState.mCaps.maxViewportWidth;
1523 params[1] = mState.mCaps.maxViewportHeight;
1524 }
1525 break;
1526 case GL_COMPRESSED_TEXTURE_FORMATS:
1527 std::copy(mState.mCaps.compressedTextureFormats.begin(),
1528 mState.mCaps.compressedTextureFormats.end(), params);
1529 break;
1530 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1531 *params = mResetStrategy;
1532 break;
1533 case GL_NUM_SHADER_BINARY_FORMATS:
1534 *params = static_cast<GLint>(mState.mCaps.shaderBinaryFormats.size());
1535 break;
1536 case GL_SHADER_BINARY_FORMATS:
1537 std::copy(mState.mCaps.shaderBinaryFormats.begin(),
1538 mState.mCaps.shaderBinaryFormats.end(), params);
1539 break;
1540 case GL_NUM_PROGRAM_BINARY_FORMATS:
1541 *params = static_cast<GLint>(mState.mCaps.programBinaryFormats.size());
1542 break;
1543 case GL_PROGRAM_BINARY_FORMATS:
1544 std::copy(mState.mCaps.programBinaryFormats.begin(),
1545 mState.mCaps.programBinaryFormats.end(), params);
1546 break;
1547 case GL_NUM_EXTENSIONS:
1548 *params = static_cast<GLint>(mExtensionStrings.size());
1549 break;
1550
1551 // Desktop client flags
1552 case GL_CONTEXT_FLAGS:
1553 ASSERT(getClientType() == EGL_OPENGL_API);
1554 *params = 0;
1555 break;
1556 case GL_CONTEXT_PROFILE_MASK:
1557 ASSERT(getClientType() == EGL_OPENGL_API);
1558 *params = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
1559 break;
1560
1561 // GL_ANGLE_request_extension
1562 case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
1563 *params = static_cast<GLint>(mRequestableExtensionStrings.size());
1564 break;
1565
1566 // GL_KHR_debug
1567 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1568 *params = mState.mExtensions.maxDebugMessageLength;
1569 break;
1570 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1571 *params = mState.mExtensions.maxDebugLoggedMessages;
1572 break;
1573 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1574 *params = mState.mExtensions.maxDebugGroupStackDepth;
1575 break;
1576 case GL_MAX_LABEL_LENGTH:
1577 *params = mState.mExtensions.maxLabelLength;
1578 break;
1579
1580 // GL_OVR_multiview2
1581 case GL_MAX_VIEWS_OVR:
1582 *params = mState.mExtensions.maxViews;
1583 break;
1584
1585 // GL_EXT_disjoint_timer_query
1586 case GL_GPU_DISJOINT_EXT:
1587 *params = mImplementation->getGPUDisjoint();
1588 break;
1589 case GL_MAX_FRAMEBUFFER_WIDTH:
1590 *params = mState.mCaps.maxFramebufferWidth;
1591 break;
1592 case GL_MAX_FRAMEBUFFER_HEIGHT:
1593 *params = mState.mCaps.maxFramebufferHeight;
1594 break;
1595 case GL_MAX_FRAMEBUFFER_SAMPLES:
1596 *params = mState.mCaps.maxFramebufferSamples;
1597 break;
1598 case GL_MAX_SAMPLE_MASK_WORDS:
1599 *params = mState.mCaps.maxSampleMaskWords;
1600 break;
1601 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1602 *params = mState.mCaps.maxColorTextureSamples;
1603 break;
1604 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1605 *params = mState.mCaps.maxDepthTextureSamples;
1606 break;
1607 case GL_MAX_INTEGER_SAMPLES:
1608 *params = mState.mCaps.maxIntegerSamples;
1609 break;
1610 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1611 *params = mState.mCaps.maxVertexAttribRelativeOffset;
1612 break;
1613 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1614 *params = mState.mCaps.maxVertexAttribBindings;
1615 break;
1616 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1617 *params = mState.mCaps.maxVertexAttribStride;
1618 break;
1619 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1620 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
1621 break;
1622 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1623 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Vertex];
1624 break;
1625 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1626 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Vertex];
1627 break;
1628 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1629 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Vertex];
1630 break;
1631 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1632 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
1633 break;
1634 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1635 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Fragment];
1636 break;
1637 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1638 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment];
1639 break;
1640 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1641 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Fragment];
1642 break;
1643 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1644 *params = mState.mCaps.minProgramTextureGatherOffset;
1645 break;
1646 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1647 *params = mState.mCaps.maxProgramTextureGatherOffset;
1648 break;
1649 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1650 *params = mState.mCaps.maxComputeWorkGroupInvocations;
1651 break;
1652 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1653 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute];
1654 break;
1655 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1656 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Compute];
1657 break;
1658 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1659 *params = mState.mCaps.maxComputeSharedMemorySize;
1660 break;
1661 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1662 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Compute];
1663 break;
1664 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1665 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
1666 break;
1667 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1668 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Compute];
1669 break;
1670 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1671 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Compute];
1672 break;
1673 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1674 *params = static_cast<GLint>(
1675 mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Compute]);
1676 break;
1677 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1678 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Compute];
1679 break;
1680 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1681 *params = mState.mCaps.maxCombinedShaderOutputResources;
1682 break;
1683 case GL_MAX_UNIFORM_LOCATIONS:
1684 *params = mState.mCaps.maxUniformLocations;
1685 break;
1686 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1687 *params = mState.mCaps.maxAtomicCounterBufferBindings;
1688 break;
1689 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1690 *params = mState.mCaps.maxAtomicCounterBufferSize;
1691 break;
1692 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1693 *params = mState.mCaps.maxCombinedAtomicCounterBuffers;
1694 break;
1695 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1696 *params = mState.mCaps.maxCombinedAtomicCounters;
1697 break;
1698 case GL_MAX_IMAGE_UNITS:
1699 *params = mState.mCaps.maxImageUnits;
1700 break;
1701 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1702 *params = mState.mCaps.maxCombinedImageUniforms;
1703 break;
1704 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1705 *params = mState.mCaps.maxShaderStorageBufferBindings;
1706 break;
1707 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1708 *params = mState.mCaps.maxCombinedShaderStorageBlocks;
1709 break;
1710 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1711 *params = mState.mCaps.shaderStorageBufferOffsetAlignment;
1712 break;
1713
1714 // GL_EXT_geometry_shader
1715 case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
1716 *params = mState.mCaps.maxFramebufferLayers;
1717 break;
1718 case GL_LAYER_PROVOKING_VERTEX_EXT:
1719 *params = mState.mCaps.layerProvokingVertex;
1720 break;
1721 case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
1722 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Geometry];
1723 break;
1724 case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
1725 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry];
1726 break;
1727 case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
1728 *params = static_cast<GLint>(
1729 mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Geometry]);
1730 break;
1731 case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
1732 *params = mState.mCaps.maxGeometryInputComponents;
1733 break;
1734 case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
1735 *params = mState.mCaps.maxGeometryOutputComponents;
1736 break;
1737 case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
1738 *params = mState.mCaps.maxGeometryOutputVertices;
1739 break;
1740 case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
1741 *params = mState.mCaps.maxGeometryTotalOutputComponents;
1742 break;
1743 case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
1744 *params = mState.mCaps.maxGeometryShaderInvocations;
1745 break;
1746 case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
1747 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Geometry];
1748 break;
1749 case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
1750 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
1751 break;
1752 case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
1753 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Geometry];
1754 break;
1755 case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
1756 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Geometry];
1757 break;
1758 case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
1759 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Geometry];
1760 break;
1761 // GLES1 emulation: Caps queries
1762 case GL_MAX_TEXTURE_UNITS:
1763 *params = mState.mCaps.maxMultitextureUnits;
1764 break;
1765 case GL_MAX_MODELVIEW_STACK_DEPTH:
1766 *params = mState.mCaps.maxModelviewMatrixStackDepth;
1767 break;
1768 case GL_MAX_PROJECTION_STACK_DEPTH:
1769 *params = mState.mCaps.maxProjectionMatrixStackDepth;
1770 break;
1771 case GL_MAX_TEXTURE_STACK_DEPTH:
1772 *params = mState.mCaps.maxTextureMatrixStackDepth;
1773 break;
1774 case GL_MAX_LIGHTS:
1775 *params = mState.mCaps.maxLights;
1776 break;
1777
1778 // case GL_MAX_CLIP_DISTANCES_EXT: Conflict enum value
1779 case GL_MAX_CLIP_PLANES:
1780 if (getClientVersion().major >= 2)
1781 {
1782 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1783 *params = mState.mCaps.maxClipDistances;
1784 }
1785 else
1786 {
1787 *params = mState.mCaps.maxClipPlanes;
1788 }
1789 break;
1790 // GLES1 emulation: Vertex attribute queries
1791 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1792 case GL_NORMAL_ARRAY_BUFFER_BINDING:
1793 case GL_COLOR_ARRAY_BUFFER_BINDING:
1794 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1795 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
1796 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, params);
1797 break;
1798 case GL_VERTEX_ARRAY_STRIDE:
1799 case GL_NORMAL_ARRAY_STRIDE:
1800 case GL_COLOR_ARRAY_STRIDE:
1801 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1802 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1803 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_STRIDE, params);
1804 break;
1805 case GL_VERTEX_ARRAY_SIZE:
1806 case GL_COLOR_ARRAY_SIZE:
1807 case GL_TEXTURE_COORD_ARRAY_SIZE:
1808 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_SIZE, params);
1809 break;
1810 case GL_VERTEX_ARRAY_TYPE:
1811 case GL_COLOR_ARRAY_TYPE:
1812 case GL_NORMAL_ARRAY_TYPE:
1813 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1814 case GL_TEXTURE_COORD_ARRAY_TYPE:
1815 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_TYPE, params);
1816 break;
1817
1818 // GL_KHR_parallel_shader_compile
1819 case GL_MAX_SHADER_COMPILER_THREADS_KHR:
1820 *params = mState.getMaxShaderCompilerThreads();
1821 break;
1822
1823 // GL_EXT_blend_func_extended
1824 case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT:
1825 *params = mState.mExtensions.maxDualSourceDrawBuffers;
1826 break;
1827
1828 default:
1829 ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params));
1830 break;
1831 }
1832 }
1833
getIntegerVertexAttribImpl(GLenum pname,GLenum attribpname,GLint * params) const1834 void Context::getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const
1835 {
1836 getVertexAttribivImpl(static_cast<GLuint>(vertexArrayIndex(ParamToVertexArrayType(pname))),
1837 attribpname, params);
1838 }
1839
getInteger64vImpl(GLenum pname,GLint64 * params) const1840 void Context::getInteger64vImpl(GLenum pname, GLint64 *params) const
1841 {
1842 // Queries about context capabilities and maximums are answered by Context.
1843 // Queries about current GL state values are answered by State.
1844 switch (pname)
1845 {
1846 case GL_MAX_ELEMENT_INDEX:
1847 *params = mState.mCaps.maxElementIndex;
1848 break;
1849 case GL_MAX_UNIFORM_BLOCK_SIZE:
1850 *params = mState.mCaps.maxUniformBlockSize;
1851 break;
1852 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1853 *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Vertex];
1854 break;
1855 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1856 *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Fragment];
1857 break;
1858 case GL_MAX_SERVER_WAIT_TIMEOUT:
1859 *params = mState.mCaps.maxServerWaitTimeout;
1860 break;
1861
1862 // GL_EXT_disjoint_timer_query
1863 case GL_TIMESTAMP_EXT:
1864 *params = mImplementation->getTimestamp();
1865 break;
1866
1867 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1868 *params = mState.mCaps.maxShaderStorageBlockSize;
1869 break;
1870 default:
1871 UNREACHABLE();
1872 break;
1873 }
1874 }
1875
getPointerv(GLenum pname,void ** params)1876 void Context::getPointerv(GLenum pname, void **params)
1877 {
1878 mState.getPointerv(this, pname, params);
1879 }
1880
getPointervRobustANGLERobust(GLenum pname,GLsizei bufSize,GLsizei * length,void ** params)1881 void Context::getPointervRobustANGLERobust(GLenum pname,
1882 GLsizei bufSize,
1883 GLsizei *length,
1884 void **params)
1885 {
1886 UNIMPLEMENTED();
1887 }
1888
getIntegeri_v(GLenum target,GLuint index,GLint * data)1889 void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
1890 {
1891 // Queries about context capabilities and maximums are answered by Context.
1892 // Queries about current GL state values are answered by State.
1893
1894 GLenum nativeType;
1895 unsigned int numParams;
1896 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1897 ASSERT(queryStatus);
1898
1899 if (nativeType == GL_INT)
1900 {
1901 switch (target)
1902 {
1903 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1904 ASSERT(index < 3u);
1905 *data = mState.mCaps.maxComputeWorkGroupCount[index];
1906 break;
1907 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1908 ASSERT(index < 3u);
1909 *data = mState.mCaps.maxComputeWorkGroupSize[index];
1910 break;
1911 default:
1912 mState.getIntegeri_v(target, index, data);
1913 }
1914 }
1915 else
1916 {
1917 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1918 }
1919 }
1920
getIntegeri_vRobust(GLenum target,GLuint index,GLsizei bufSize,GLsizei * length,GLint * data)1921 void Context::getIntegeri_vRobust(GLenum target,
1922 GLuint index,
1923 GLsizei bufSize,
1924 GLsizei *length,
1925 GLint *data)
1926 {
1927 getIntegeri_v(target, index, data);
1928 }
1929
getInteger64i_v(GLenum target,GLuint index,GLint64 * data)1930 void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
1931 {
1932 // Queries about context capabilities and maximums are answered by Context.
1933 // Queries about current GL state values are answered by State.
1934
1935 GLenum nativeType;
1936 unsigned int numParams;
1937 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1938 ASSERT(queryStatus);
1939
1940 if (nativeType == GL_INT_64_ANGLEX)
1941 {
1942 mState.getInteger64i_v(target, index, data);
1943 }
1944 else
1945 {
1946 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1947 }
1948 }
1949
getInteger64i_vRobust(GLenum target,GLuint index,GLsizei bufSize,GLsizei * length,GLint64 * data)1950 void Context::getInteger64i_vRobust(GLenum target,
1951 GLuint index,
1952 GLsizei bufSize,
1953 GLsizei *length,
1954 GLint64 *data)
1955 {
1956 getInteger64i_v(target, index, data);
1957 }
1958
getBooleani_v(GLenum target,GLuint index,GLboolean * data)1959 void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1960 {
1961 // Queries about context capabilities and maximums are answered by Context.
1962 // Queries about current GL state values are answered by State.
1963
1964 GLenum nativeType;
1965 unsigned int numParams;
1966 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1967 ASSERT(queryStatus);
1968
1969 if (nativeType == GL_BOOL)
1970 {
1971 mState.getBooleani_v(target, index, data);
1972 }
1973 else
1974 {
1975 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1976 }
1977 }
1978
getBooleani_vRobust(GLenum target,GLuint index,GLsizei bufSize,GLsizei * length,GLboolean * data)1979 void Context::getBooleani_vRobust(GLenum target,
1980 GLuint index,
1981 GLsizei bufSize,
1982 GLsizei *length,
1983 GLboolean *data)
1984 {
1985 getBooleani_v(target, index, data);
1986 }
1987
getBufferParameteriv(BufferBinding target,GLenum pname,GLint * params)1988 void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
1989 {
1990 Buffer *buffer = mState.getTargetBuffer(target);
1991 QueryBufferParameteriv(buffer, pname, params);
1992 }
1993
getBufferParameterivRobust(BufferBinding target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1994 void Context::getBufferParameterivRobust(BufferBinding target,
1995 GLenum pname,
1996 GLsizei bufSize,
1997 GLsizei *length,
1998 GLint *params)
1999 {
2000 getBufferParameteriv(target, pname, params);
2001 }
2002
getFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)2003 void Context::getFramebufferAttachmentParameteriv(GLenum target,
2004 GLenum attachment,
2005 GLenum pname,
2006 GLint *params)
2007 {
2008 const Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2009 QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
2010 }
2011
getFramebufferAttachmentParameterivRobust(GLenum target,GLenum attachment,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2012 void Context::getFramebufferAttachmentParameterivRobust(GLenum target,
2013 GLenum attachment,
2014 GLenum pname,
2015 GLsizei bufSize,
2016 GLsizei *length,
2017 GLint *params)
2018 {
2019 getFramebufferAttachmentParameteriv(target, attachment, pname, params);
2020 }
2021
getRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)2022 void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
2023 {
2024 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
2025 QueryRenderbufferiv(this, renderbuffer, pname, params);
2026 }
2027
getRenderbufferParameterivRobust(GLenum target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2028 void Context::getRenderbufferParameterivRobust(GLenum target,
2029 GLenum pname,
2030 GLsizei bufSize,
2031 GLsizei *length,
2032 GLint *params)
2033 {
2034 getRenderbufferParameteriv(target, pname, params);
2035 }
2036
texBuffer(GLenum target,GLenum internalformat,BufferID buffer)2037 void Context::texBuffer(GLenum target, GLenum internalformat, BufferID buffer)
2038 {
2039 UNIMPLEMENTED();
2040 }
2041
texBufferRange(GLenum target,GLenum internalformat,BufferID buffer,GLintptr offset,GLsizeiptr size)2042 void Context::texBufferRange(GLenum target,
2043 GLenum internalformat,
2044 BufferID buffer,
2045 GLintptr offset,
2046 GLsizeiptr size)
2047 {
2048 UNIMPLEMENTED();
2049 }
2050
getTexParameterfv(TextureType target,GLenum pname,GLfloat * params)2051 void Context::getTexParameterfv(TextureType target, GLenum pname, GLfloat *params)
2052 {
2053 const Texture *const texture = getTextureByType(target);
2054 QueryTexParameterfv(this, texture, pname, params);
2055 }
2056
getTexParameterfvRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)2057 void Context::getTexParameterfvRobust(TextureType target,
2058 GLenum pname,
2059 GLsizei bufSize,
2060 GLsizei *length,
2061 GLfloat *params)
2062 {
2063 getTexParameterfv(target, pname, params);
2064 }
2065
getTexParameteriv(TextureType target,GLenum pname,GLint * params)2066 void Context::getTexParameteriv(TextureType target, GLenum pname, GLint *params)
2067 {
2068 const Texture *const texture = getTextureByType(target);
2069 QueryTexParameteriv(this, texture, pname, params);
2070 }
2071
getTexParameterIiv(TextureType target,GLenum pname,GLint * params)2072 void Context::getTexParameterIiv(TextureType target, GLenum pname, GLint *params)
2073 {
2074 const Texture *const texture = getTextureByType(target);
2075 QueryTexParameterIiv(this, texture, pname, params);
2076 }
2077
getTexParameterIuiv(TextureType target,GLenum pname,GLuint * params)2078 void Context::getTexParameterIuiv(TextureType target, GLenum pname, GLuint *params)
2079 {
2080 const Texture *const texture = getTextureByType(target);
2081 QueryTexParameterIuiv(this, texture, pname, params);
2082 }
2083
getTexParameterivRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2084 void Context::getTexParameterivRobust(TextureType target,
2085 GLenum pname,
2086 GLsizei bufSize,
2087 GLsizei *length,
2088 GLint *params)
2089 {
2090 getTexParameteriv(target, pname, params);
2091 }
2092
getTexParameterIivRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2093 void Context::getTexParameterIivRobust(TextureType target,
2094 GLenum pname,
2095 GLsizei bufSize,
2096 GLsizei *length,
2097 GLint *params)
2098 {
2099 UNIMPLEMENTED();
2100 }
2101
getTexParameterIuivRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)2102 void Context::getTexParameterIuivRobust(TextureType target,
2103 GLenum pname,
2104 GLsizei bufSize,
2105 GLsizei *length,
2106 GLuint *params)
2107 {
2108 UNIMPLEMENTED();
2109 }
2110
getTexLevelParameteriv(TextureTarget target,GLint level,GLenum pname,GLint * params)2111 void Context::getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params)
2112 {
2113 Texture *texture = getTextureByTarget(target);
2114 QueryTexLevelParameteriv(texture, target, level, pname, params);
2115 }
2116
getTexLevelParameterivRobust(TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2117 void Context::getTexLevelParameterivRobust(TextureTarget target,
2118 GLint level,
2119 GLenum pname,
2120 GLsizei bufSize,
2121 GLsizei *length,
2122 GLint *params)
2123 {
2124 UNIMPLEMENTED();
2125 }
2126
getTexLevelParameterfv(TextureTarget target,GLint level,GLenum pname,GLfloat * params)2127 void Context::getTexLevelParameterfv(TextureTarget target,
2128 GLint level,
2129 GLenum pname,
2130 GLfloat *params)
2131 {
2132 Texture *texture = getTextureByTarget(target);
2133 QueryTexLevelParameterfv(texture, target, level, pname, params);
2134 }
2135
getTexLevelParameterfvRobust(TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)2136 void Context::getTexLevelParameterfvRobust(TextureTarget target,
2137 GLint level,
2138 GLenum pname,
2139 GLsizei bufSize,
2140 GLsizei *length,
2141 GLfloat *params)
2142 {
2143 UNIMPLEMENTED();
2144 }
2145
texParameterf(TextureType target,GLenum pname,GLfloat param)2146 void Context::texParameterf(TextureType target, GLenum pname, GLfloat param)
2147 {
2148 Texture *const texture = getTextureByType(target);
2149 SetTexParameterf(this, texture, pname, param);
2150 }
2151
texParameterfv(TextureType target,GLenum pname,const GLfloat * params)2152 void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params)
2153 {
2154 Texture *const texture = getTextureByType(target);
2155 SetTexParameterfv(this, texture, pname, params);
2156 }
2157
texParameterfvRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLfloat * params)2158 void Context::texParameterfvRobust(TextureType target,
2159 GLenum pname,
2160 GLsizei bufSize,
2161 const GLfloat *params)
2162 {
2163 texParameterfv(target, pname, params);
2164 }
2165
texParameteri(TextureType target,GLenum pname,GLint param)2166 void Context::texParameteri(TextureType target, GLenum pname, GLint param)
2167 {
2168 Texture *const texture = getTextureByType(target);
2169 SetTexParameteri(this, texture, pname, param);
2170 }
2171
texParameteriv(TextureType target,GLenum pname,const GLint * params)2172 void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params)
2173 {
2174 Texture *const texture = getTextureByType(target);
2175 SetTexParameteriv(this, texture, pname, params);
2176 }
2177
texParameterIiv(TextureType target,GLenum pname,const GLint * params)2178 void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params)
2179 {
2180 Texture *const texture = getTextureByType(target);
2181 SetTexParameterIiv(this, texture, pname, params);
2182 }
2183
texParameterIuiv(TextureType target,GLenum pname,const GLuint * params)2184 void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params)
2185 {
2186 Texture *const texture = getTextureByType(target);
2187 SetTexParameterIuiv(this, texture, pname, params);
2188 }
2189
texParameterivRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)2190 void Context::texParameterivRobust(TextureType target,
2191 GLenum pname,
2192 GLsizei bufSize,
2193 const GLint *params)
2194 {
2195 texParameteriv(target, pname, params);
2196 }
2197
texParameterIivRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)2198 void Context::texParameterIivRobust(TextureType target,
2199 GLenum pname,
2200 GLsizei bufSize,
2201 const GLint *params)
2202 {
2203 UNIMPLEMENTED();
2204 }
2205
texParameterIuivRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLuint * params)2206 void Context::texParameterIuivRobust(TextureType target,
2207 GLenum pname,
2208 GLsizei bufSize,
2209 const GLuint *params)
2210 {
2211 UNIMPLEMENTED();
2212 }
2213
drawArraysInstanced(PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)2214 void Context::drawArraysInstanced(PrimitiveMode mode,
2215 GLint first,
2216 GLsizei count,
2217 GLsizei instanceCount)
2218 {
2219 // No-op if count draws no primitives for given mode
2220 if (noopDrawInstanced(mode, count, instanceCount))
2221 {
2222 return;
2223 }
2224
2225 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2226 ANGLE_CONTEXT_TRY(
2227 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
2228 MarkTransformFeedbackBufferUsage(this, count, instanceCount);
2229 MarkShaderStorageBufferUsage(this);
2230 }
2231
drawElementsInstanced(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instances)2232 void Context::drawElementsInstanced(PrimitiveMode mode,
2233 GLsizei count,
2234 DrawElementsType type,
2235 const void *indices,
2236 GLsizei instances)
2237 {
2238 // No-op if count draws no primitives for given mode
2239 if (noopDrawInstanced(mode, count, instances))
2240 {
2241 return;
2242 }
2243
2244 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2245 ANGLE_CONTEXT_TRY(
2246 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
2247 MarkShaderStorageBufferUsage(this);
2248 }
2249
drawElementsBaseVertex(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)2250 void Context::drawElementsBaseVertex(PrimitiveMode mode,
2251 GLsizei count,
2252 DrawElementsType type,
2253 const void *indices,
2254 GLint basevertex)
2255 {
2256 // No-op if count draws no primitives for given mode
2257 if (noopDraw(mode, count))
2258 {
2259 return;
2260 }
2261
2262 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2263 ANGLE_CONTEXT_TRY(
2264 mImplementation->drawElementsBaseVertex(this, mode, count, type, indices, basevertex));
2265 MarkShaderStorageBufferUsage(this);
2266 }
2267
drawElementsInstancedBaseVertex(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)2268 void Context::drawElementsInstancedBaseVertex(PrimitiveMode mode,
2269 GLsizei count,
2270 DrawElementsType type,
2271 const void *indices,
2272 GLsizei instancecount,
2273 GLint basevertex)
2274 {
2275 // No-op if count draws no primitives for given mode
2276 if (noopDrawInstanced(mode, count, instancecount))
2277 {
2278 return;
2279 }
2280
2281 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2282 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertex(
2283 this, mode, count, type, indices, instancecount, basevertex));
2284 MarkShaderStorageBufferUsage(this);
2285 }
2286
drawRangeElements(PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices)2287 void Context::drawRangeElements(PrimitiveMode mode,
2288 GLuint start,
2289 GLuint end,
2290 GLsizei count,
2291 DrawElementsType type,
2292 const void *indices)
2293 {
2294 // No-op if count draws no primitives for given mode
2295 if (noopDraw(mode, count))
2296 {
2297 return;
2298 }
2299
2300 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2301 ANGLE_CONTEXT_TRY(
2302 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
2303 MarkShaderStorageBufferUsage(this);
2304 }
2305
drawRangeElementsBaseVertex(PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)2306 void Context::drawRangeElementsBaseVertex(PrimitiveMode mode,
2307 GLuint start,
2308 GLuint end,
2309 GLsizei count,
2310 DrawElementsType type,
2311 const void *indices,
2312 GLint basevertex)
2313 {
2314 // No-op if count draws no primitives for given mode
2315 if (noopDraw(mode, count))
2316 {
2317 return;
2318 }
2319
2320 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2321 ANGLE_CONTEXT_TRY(mImplementation->drawRangeElementsBaseVertex(this, mode, start, end, count,
2322 type, indices, basevertex));
2323 MarkShaderStorageBufferUsage(this);
2324 }
2325
drawArraysIndirect(PrimitiveMode mode,const void * indirect)2326 void Context::drawArraysIndirect(PrimitiveMode mode, const void *indirect)
2327 {
2328 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2329 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
2330 MarkShaderStorageBufferUsage(this);
2331 }
2332
drawElementsIndirect(PrimitiveMode mode,DrawElementsType type,const void * indirect)2333 void Context::drawElementsIndirect(PrimitiveMode mode, DrawElementsType type, const void *indirect)
2334 {
2335 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2336 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
2337 MarkShaderStorageBufferUsage(this);
2338 }
2339
flush()2340 void Context::flush()
2341 {
2342 ANGLE_CONTEXT_TRY(mImplementation->flush(this));
2343 }
2344
finish()2345 void Context::finish()
2346 {
2347 ANGLE_CONTEXT_TRY(mImplementation->finish(this));
2348 }
2349
insertEventMarker(GLsizei length,const char * marker)2350 void Context::insertEventMarker(GLsizei length, const char *marker)
2351 {
2352 ASSERT(mImplementation);
2353 ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(length, marker));
2354 }
2355
pushGroupMarker(GLsizei length,const char * marker)2356 void Context::pushGroupMarker(GLsizei length, const char *marker)
2357 {
2358 ASSERT(mImplementation);
2359
2360 if (marker == nullptr)
2361 {
2362 // From the EXT_debug_marker spec,
2363 // "If <marker> is null then an empty string is pushed on the stack."
2364 ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, ""));
2365 }
2366 else
2367 {
2368 ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, marker));
2369 }
2370 }
2371
popGroupMarker()2372 void Context::popGroupMarker()
2373 {
2374 ASSERT(mImplementation);
2375 ANGLE_CONTEXT_TRY(mImplementation->popGroupMarker());
2376 }
2377
bindUniformLocation(ShaderProgramID program,UniformLocation location,const GLchar * name)2378 void Context::bindUniformLocation(ShaderProgramID program,
2379 UniformLocation location,
2380 const GLchar *name)
2381 {
2382 Program *programObject = getProgramResolveLink(program);
2383 ASSERT(programObject);
2384
2385 programObject->bindUniformLocation(location, name);
2386 }
2387
coverageModulation(GLenum components)2388 void Context::coverageModulation(GLenum components)
2389 {
2390 mState.setCoverageModulation(components);
2391 }
2392
getProgramResourceIndex(ShaderProgramID program,GLenum programInterface,const GLchar * name)2393 GLuint Context::getProgramResourceIndex(ShaderProgramID program,
2394 GLenum programInterface,
2395 const GLchar *name)
2396 {
2397 const Program *programObject = getProgramResolveLink(program);
2398 return QueryProgramResourceIndex(programObject, programInterface, name);
2399 }
2400
getProgramResourceName(ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)2401 void Context::getProgramResourceName(ShaderProgramID program,
2402 GLenum programInterface,
2403 GLuint index,
2404 GLsizei bufSize,
2405 GLsizei *length,
2406 GLchar *name)
2407 {
2408 const Program *programObject = getProgramResolveLink(program);
2409 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2410 }
2411
getProgramResourceLocation(ShaderProgramID program,GLenum programInterface,const GLchar * name)2412 GLint Context::getProgramResourceLocation(ShaderProgramID program,
2413 GLenum programInterface,
2414 const GLchar *name)
2415 {
2416 const Program *programObject = getProgramResolveLink(program);
2417 return QueryProgramResourceLocation(programObject, programInterface, name);
2418 }
2419
getProgramResourceiv(ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)2420 void Context::getProgramResourceiv(ShaderProgramID program,
2421 GLenum programInterface,
2422 GLuint index,
2423 GLsizei propCount,
2424 const GLenum *props,
2425 GLsizei bufSize,
2426 GLsizei *length,
2427 GLint *params)
2428 {
2429 const Program *programObject = getProgramResolveLink(program);
2430 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2431 length, params);
2432 }
2433
getProgramInterfaceiv(ShaderProgramID program,GLenum programInterface,GLenum pname,GLint * params)2434 void Context::getProgramInterfaceiv(ShaderProgramID program,
2435 GLenum programInterface,
2436 GLenum pname,
2437 GLint *params)
2438 {
2439 const Program *programObject = getProgramResolveLink(program);
2440 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2441 }
2442
getProgramInterfaceivRobust(ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2443 void Context::getProgramInterfaceivRobust(ShaderProgramID program,
2444 GLenum programInterface,
2445 GLenum pname,
2446 GLsizei bufSize,
2447 GLsizei *length,
2448 GLint *params)
2449 {
2450 UNIMPLEMENTED();
2451 }
2452
handleError(GLenum errorCode,const char * message,const char * file,const char * function,unsigned int line)2453 void Context::handleError(GLenum errorCode,
2454 const char *message,
2455 const char *file,
2456 const char *function,
2457 unsigned int line)
2458 {
2459 mErrors.handleError(errorCode, message, file, function, line);
2460 }
2461
validationError(GLenum errorCode,const char * message) const2462 void Context::validationError(GLenum errorCode, const char *message) const
2463 {
2464 const_cast<Context *>(this)->mErrors.validationError(errorCode, message);
2465 }
2466
2467 // Get one of the recorded errors and clear its flag, if any.
2468 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()2469 GLenum Context::getError()
2470 {
2471 if (mErrors.empty())
2472 {
2473 return GL_NO_ERROR;
2474 }
2475 else
2476 {
2477 return mErrors.popError();
2478 }
2479 }
2480
2481 // NOTE: this function should not assume that this context is current!
markContextLost(GraphicsResetStatus status)2482 void Context::markContextLost(GraphicsResetStatus status)
2483 {
2484 ASSERT(status != GraphicsResetStatus::NoError);
2485 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
2486 {
2487 mResetStatus = status;
2488 mContextLostForced = true;
2489 }
2490 setContextLost();
2491 }
2492
setContextLost()2493 void Context::setContextLost()
2494 {
2495 mContextLost = true;
2496
2497 // Stop skipping validation, since many implementation entrypoint assume they can't
2498 // be called when lost, or with null object arguments, etc.
2499 mSkipValidation = false;
2500 }
2501
getGraphicsResetStatus()2502 GLenum Context::getGraphicsResetStatus()
2503 {
2504 // Even if the application doesn't want to know about resets, we want to know
2505 // as it will allow us to skip all the calls.
2506 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
2507 {
2508 if (!isContextLost() && mImplementation->getResetStatus() != GraphicsResetStatus::NoError)
2509 {
2510 setContextLost();
2511 }
2512
2513 // EXT_robustness, section 2.6: If the reset notification behavior is
2514 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2515 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2516 return GL_NO_ERROR;
2517 }
2518
2519 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2520 // status should be returned at least once, and GL_NO_ERROR should be returned
2521 // once the device has finished resetting.
2522 if (!isContextLost())
2523 {
2524 ASSERT(mResetStatus == GraphicsResetStatus::NoError);
2525 mResetStatus = mImplementation->getResetStatus();
2526
2527 if (mResetStatus != GraphicsResetStatus::NoError)
2528 {
2529 setContextLost();
2530 }
2531 }
2532 else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError)
2533 {
2534 // If markContextLost was used to mark the context lost then
2535 // assume that is not recoverable, and continue to report the
2536 // lost reset status for the lifetime of this context.
2537 mResetStatus = mImplementation->getResetStatus();
2538 }
2539
2540 return ToGLenum(mResetStatus);
2541 }
2542
isResetNotificationEnabled()2543 bool Context::isResetNotificationEnabled()
2544 {
2545 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2546 }
2547
getConfig() const2548 const egl::Config *Context::getConfig() const
2549 {
2550 return mConfig;
2551 }
2552
getClientType() const2553 EGLenum Context::getClientType() const
2554 {
2555 return mState.getClientType();
2556 }
2557
getRenderBuffer() const2558 EGLenum Context::getRenderBuffer() const
2559 {
2560 const Framebuffer *framebuffer =
2561 mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
2562 if (framebuffer == nullptr)
2563 {
2564 return EGL_NONE;
2565 }
2566
2567 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK);
2568 ASSERT(backAttachment != nullptr);
2569 return backAttachment->getSurface()->getRenderBuffer();
2570 }
2571
checkVertexArrayAllocation(VertexArrayID vertexArrayHandle)2572 VertexArray *Context::checkVertexArrayAllocation(VertexArrayID vertexArrayHandle)
2573 {
2574 // Only called after a prior call to Gen.
2575 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2576 if (!vertexArray)
2577 {
2578 vertexArray =
2579 new VertexArray(mImplementation.get(), vertexArrayHandle,
2580 mState.mCaps.maxVertexAttributes, mState.mCaps.maxVertexAttribBindings);
2581 vertexArray->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
2582
2583 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
2584 }
2585
2586 return vertexArray;
2587 }
2588
checkTransformFeedbackAllocation(TransformFeedbackID transformFeedbackHandle)2589 TransformFeedback *Context::checkTransformFeedbackAllocation(
2590 TransformFeedbackID transformFeedbackHandle)
2591 {
2592 // Only called after a prior call to Gen.
2593 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2594 if (!transformFeedback)
2595 {
2596 transformFeedback =
2597 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mState.mCaps);
2598 transformFeedback->addRef();
2599 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
2600 }
2601
2602 return transformFeedback;
2603 }
2604
isVertexArrayGenerated(VertexArrayID vertexArray) const2605 bool Context::isVertexArrayGenerated(VertexArrayID vertexArray) const
2606 {
2607 ASSERT(mVertexArrayMap.contains({0}));
2608 return mVertexArrayMap.contains(vertexArray);
2609 }
2610
isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const2611 bool Context::isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const
2612 {
2613 ASSERT(mTransformFeedbackMap.contains({0}));
2614 return mTransformFeedbackMap.contains(transformFeedback);
2615 }
2616
detachTexture(TextureID texture)2617 void Context::detachTexture(TextureID texture)
2618 {
2619 // The State cannot unbind image observers itself, they are owned by the Context
2620 Texture *tex = mState.mTextureManager->getTexture(texture);
2621 for (auto &imageBinding : mImageObserverBindings)
2622 {
2623 if (imageBinding.getSubject() == tex)
2624 {
2625 imageBinding.reset();
2626 }
2627 }
2628
2629 // Simple pass-through to State's detachTexture method, as textures do not require
2630 // allocation map management either here or in the resource manager at detach time.
2631 // Zero textures are held by the Context, and we don't attempt to request them from
2632 // the State.
2633 mState.detachTexture(this, mZeroTextures, texture);
2634 }
2635
detachBuffer(Buffer * buffer)2636 void Context::detachBuffer(Buffer *buffer)
2637 {
2638 // Simple pass-through to State's detachBuffer method, since
2639 // only buffer attachments to container objects that are bound to the current context
2640 // should be detached. And all those are available in State.
2641
2642 // [OpenGL ES 3.2] section 5.1.2 page 45:
2643 // Attachments to unbound container objects, such as
2644 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2645 // are not affected and continue to act as references on the deleted object
2646 ANGLE_CONTEXT_TRY(mState.detachBuffer(this, buffer));
2647 }
2648
detachFramebuffer(FramebufferID framebuffer)2649 void Context::detachFramebuffer(FramebufferID framebuffer)
2650 {
2651 // Framebuffer detachment is handled by Context, because 0 is a valid
2652 // Framebuffer object, and a pointer to it must be passed from Context
2653 // to State at binding time.
2654
2655 // [OpenGL ES 2.0.24] section 4.4 page 107:
2656 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2657 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2658 // zero.
2659
2660 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer.value != 0)
2661 {
2662 bindReadFramebuffer({0});
2663 }
2664
2665 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer.value != 0)
2666 {
2667 bindDrawFramebuffer({0});
2668 }
2669 }
2670
detachRenderbuffer(RenderbufferID renderbuffer)2671 void Context::detachRenderbuffer(RenderbufferID renderbuffer)
2672 {
2673 mState.detachRenderbuffer(this, renderbuffer);
2674 }
2675
detachVertexArray(VertexArrayID vertexArray)2676 void Context::detachVertexArray(VertexArrayID vertexArray)
2677 {
2678 // Vertex array detachment is handled by Context, because 0 is a valid
2679 // VAO, and a pointer to it must be passed from Context to State at
2680 // binding time.
2681
2682 // [OpenGL ES 3.0.2] section 2.10 page 43:
2683 // If a vertex array object that is currently bound is deleted, the binding
2684 // for that object reverts to zero and the default vertex array becomes current.
2685 if (mState.removeVertexArrayBinding(this, vertexArray))
2686 {
2687 bindVertexArray({0});
2688 }
2689 }
2690
detachTransformFeedback(TransformFeedbackID transformFeedback)2691 void Context::detachTransformFeedback(TransformFeedbackID transformFeedback)
2692 {
2693 // Transform feedback detachment is handled by Context, because 0 is a valid
2694 // transform feedback, and a pointer to it must be passed from Context to State at
2695 // binding time.
2696
2697 // The OpenGL specification doesn't mention what should happen when the currently bound
2698 // transform feedback object is deleted. Since it is a container object, we treat it like
2699 // VAOs and FBOs and set the current bound transform feedback back to 0.
2700 if (mState.removeTransformFeedbackBinding(this, transformFeedback))
2701 {
2702 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
2703 }
2704 }
2705
detachSampler(SamplerID sampler)2706 void Context::detachSampler(SamplerID sampler)
2707 {
2708 mState.detachSampler(this, sampler);
2709 }
2710
detachProgramPipeline(ProgramPipelineID pipeline)2711 void Context::detachProgramPipeline(ProgramPipelineID pipeline)
2712 {
2713 mState.detachProgramPipeline(this, pipeline);
2714 }
2715
vertexAttribDivisor(GLuint index,GLuint divisor)2716 void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
2717 {
2718 mState.setVertexAttribDivisor(this, index, divisor);
2719 mStateCache.onVertexArrayStateChange(this);
2720 }
2721
samplerParameteri(SamplerID sampler,GLenum pname,GLint param)2722 void Context::samplerParameteri(SamplerID sampler, GLenum pname, GLint param)
2723 {
2724 Sampler *const samplerObject =
2725 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2726 SetSamplerParameteri(this, samplerObject, pname, param);
2727 }
2728
samplerParameteriv(SamplerID sampler,GLenum pname,const GLint * param)2729 void Context::samplerParameteriv(SamplerID sampler, GLenum pname, const GLint *param)
2730 {
2731 Sampler *const samplerObject =
2732 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2733 SetSamplerParameteriv(this, samplerObject, pname, param);
2734 }
2735
samplerParameterIiv(SamplerID sampler,GLenum pname,const GLint * param)2736 void Context::samplerParameterIiv(SamplerID sampler, GLenum pname, const GLint *param)
2737 {
2738 Sampler *const samplerObject =
2739 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2740 SetSamplerParameterIiv(this, samplerObject, pname, param);
2741 }
2742
samplerParameterIuiv(SamplerID sampler,GLenum pname,const GLuint * param)2743 void Context::samplerParameterIuiv(SamplerID sampler, GLenum pname, const GLuint *param)
2744 {
2745 Sampler *const samplerObject =
2746 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2747 SetSamplerParameterIuiv(this, samplerObject, pname, param);
2748 }
2749
samplerParameterivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * param)2750 void Context::samplerParameterivRobust(SamplerID sampler,
2751 GLenum pname,
2752 GLsizei bufSize,
2753 const GLint *param)
2754 {
2755 samplerParameteriv(sampler, pname, param);
2756 }
2757
samplerParameterIivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * param)2758 void Context::samplerParameterIivRobust(SamplerID sampler,
2759 GLenum pname,
2760 GLsizei bufSize,
2761 const GLint *param)
2762 {
2763 UNIMPLEMENTED();
2764 }
2765
samplerParameterIuivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLuint * param)2766 void Context::samplerParameterIuivRobust(SamplerID sampler,
2767 GLenum pname,
2768 GLsizei bufSize,
2769 const GLuint *param)
2770 {
2771 UNIMPLEMENTED();
2772 }
2773
samplerParameterf(SamplerID sampler,GLenum pname,GLfloat param)2774 void Context::samplerParameterf(SamplerID sampler, GLenum pname, GLfloat param)
2775 {
2776 Sampler *const samplerObject =
2777 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2778 SetSamplerParameterf(this, samplerObject, pname, param);
2779 }
2780
samplerParameterfv(SamplerID sampler,GLenum pname,const GLfloat * param)2781 void Context::samplerParameterfv(SamplerID sampler, GLenum pname, const GLfloat *param)
2782 {
2783 Sampler *const samplerObject =
2784 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2785 SetSamplerParameterfv(this, samplerObject, pname, param);
2786 }
2787
samplerParameterfvRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLfloat * param)2788 void Context::samplerParameterfvRobust(SamplerID sampler,
2789 GLenum pname,
2790 GLsizei bufSize,
2791 const GLfloat *param)
2792 {
2793 samplerParameterfv(sampler, pname, param);
2794 }
2795
getSamplerParameteriv(SamplerID sampler,GLenum pname,GLint * params)2796 void Context::getSamplerParameteriv(SamplerID sampler, GLenum pname, GLint *params)
2797 {
2798 const Sampler *const samplerObject =
2799 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2800 QuerySamplerParameteriv(samplerObject, pname, params);
2801 }
2802
getSamplerParameterIiv(SamplerID sampler,GLenum pname,GLint * params)2803 void Context::getSamplerParameterIiv(SamplerID sampler, GLenum pname, GLint *params)
2804 {
2805 const Sampler *const samplerObject =
2806 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2807 QuerySamplerParameterIiv(samplerObject, pname, params);
2808 }
2809
getSamplerParameterIuiv(SamplerID sampler,GLenum pname,GLuint * params)2810 void Context::getSamplerParameterIuiv(SamplerID sampler, GLenum pname, GLuint *params)
2811 {
2812 const Sampler *const samplerObject =
2813 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2814 QuerySamplerParameterIuiv(samplerObject, pname, params);
2815 }
2816
getSamplerParameterivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2817 void Context::getSamplerParameterivRobust(SamplerID sampler,
2818 GLenum pname,
2819 GLsizei bufSize,
2820 GLsizei *length,
2821 GLint *params)
2822 {
2823 getSamplerParameteriv(sampler, pname, params);
2824 }
2825
getSamplerParameterIivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2826 void Context::getSamplerParameterIivRobust(SamplerID sampler,
2827 GLenum pname,
2828 GLsizei bufSize,
2829 GLsizei *length,
2830 GLint *params)
2831 {
2832 UNIMPLEMENTED();
2833 }
2834
getSamplerParameterIuivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)2835 void Context::getSamplerParameterIuivRobust(SamplerID sampler,
2836 GLenum pname,
2837 GLsizei bufSize,
2838 GLsizei *length,
2839 GLuint *params)
2840 {
2841 UNIMPLEMENTED();
2842 }
2843
getSamplerParameterfv(SamplerID sampler,GLenum pname,GLfloat * params)2844 void Context::getSamplerParameterfv(SamplerID sampler, GLenum pname, GLfloat *params)
2845 {
2846 const Sampler *const samplerObject =
2847 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2848 QuerySamplerParameterfv(samplerObject, pname, params);
2849 }
2850
getSamplerParameterfvRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)2851 void Context::getSamplerParameterfvRobust(SamplerID sampler,
2852 GLenum pname,
2853 GLsizei bufSize,
2854 GLsizei *length,
2855 GLfloat *params)
2856 {
2857 getSamplerParameterfv(sampler, pname, params);
2858 }
2859
programParameteri(ShaderProgramID program,GLenum pname,GLint value)2860 void Context::programParameteri(ShaderProgramID program, GLenum pname, GLint value)
2861 {
2862 gl::Program *programObject = getProgramResolveLink(program);
2863 SetProgramParameteri(programObject, pname, value);
2864 }
2865
initRendererString()2866 void Context::initRendererString()
2867 {
2868 std::ostringstream rendererString;
2869 rendererString << "ANGLE (";
2870 rendererString << mImplementation->getRendererDescription();
2871 rendererString << ")";
2872
2873 mRendererString = MakeStaticString(rendererString.str());
2874 }
2875
initVersionStrings()2876 void Context::initVersionStrings()
2877 {
2878 const Version &clientVersion = getClientVersion();
2879
2880 std::ostringstream versionString;
2881 if (getClientType() == EGL_OPENGL_ES_API)
2882 {
2883 versionString << "OpenGL ES ";
2884 }
2885 versionString << clientVersion.major << "." << clientVersion.minor << ".0 (ANGLE "
2886 << ANGLE_VERSION_STRING << ")";
2887 mVersionString = MakeStaticString(versionString.str());
2888
2889 std::ostringstream shadingLanguageVersionString;
2890 if (getClientType() == EGL_OPENGL_ES_API)
2891 {
2892 shadingLanguageVersionString << "OpenGL ES GLSL ES ";
2893 }
2894 else
2895 {
2896 ASSERT(getClientType() == EGL_OPENGL_API);
2897 shadingLanguageVersionString << "OpenGL GLSL ";
2898 }
2899 shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2900 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2901 << ")";
2902 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
2903 }
2904
initExtensionStrings()2905 void Context::initExtensionStrings()
2906 {
2907 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2908 std::ostringstream combinedStringStream;
2909 std::copy(strings.begin(), strings.end(),
2910 std::ostream_iterator<const char *>(combinedStringStream, " "));
2911 return MakeStaticString(combinedStringStream.str());
2912 };
2913
2914 mExtensionStrings.clear();
2915 for (const auto &extensionString : mState.mExtensions.getStrings())
2916 {
2917 mExtensionStrings.push_back(MakeStaticString(extensionString));
2918 }
2919 mExtensionString = mergeExtensionStrings(mExtensionStrings);
2920
2921 mRequestableExtensionStrings.clear();
2922 for (const auto &extensionInfo : GetExtensionInfoMap())
2923 {
2924 if (extensionInfo.second.Requestable &&
2925 !(mState.mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2926 mSupportedExtensions.*(extensionInfo.second.ExtensionsMember))
2927 {
2928 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2929 }
2930 }
2931 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
2932 }
2933
getString(GLenum name)2934 const GLubyte *Context::getString(GLenum name)
2935 {
2936 return static_cast<const Context *>(this)->getString(name);
2937 }
2938
getStringi(GLenum name,GLuint index)2939 const GLubyte *Context::getStringi(GLenum name, GLuint index)
2940 {
2941 return static_cast<const Context *>(this)->getStringi(name, index);
2942 }
2943
getString(GLenum name) const2944 const GLubyte *Context::getString(GLenum name) const
2945 {
2946 switch (name)
2947 {
2948 case GL_VENDOR:
2949 return reinterpret_cast<const GLubyte *>("Google Inc.");
2950
2951 case GL_RENDERER:
2952 return reinterpret_cast<const GLubyte *>(mRendererString);
2953
2954 case GL_VERSION:
2955 return reinterpret_cast<const GLubyte *>(mVersionString);
2956
2957 case GL_SHADING_LANGUAGE_VERSION:
2958 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2959
2960 case GL_EXTENSIONS:
2961 return reinterpret_cast<const GLubyte *>(mExtensionString);
2962
2963 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2964 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2965
2966 default:
2967 UNREACHABLE();
2968 return nullptr;
2969 }
2970 }
2971
getStringi(GLenum name,GLuint index) const2972 const GLubyte *Context::getStringi(GLenum name, GLuint index) const
2973 {
2974 switch (name)
2975 {
2976 case GL_EXTENSIONS:
2977 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2978
2979 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2980 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2981
2982 default:
2983 UNREACHABLE();
2984 return nullptr;
2985 }
2986 }
2987
getExtensionStringCount() const2988 size_t Context::getExtensionStringCount() const
2989 {
2990 return mExtensionStrings.size();
2991 }
2992
isExtensionRequestable(const char * name) const2993 bool Context::isExtensionRequestable(const char *name) const
2994 {
2995 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2996 auto extension = extensionInfos.find(name);
2997
2998 return extension != extensionInfos.end() && extension->second.Requestable &&
2999 mSupportedExtensions.*(extension->second.ExtensionsMember);
3000 }
3001
isExtensionDisablable(const char * name) const3002 bool Context::isExtensionDisablable(const char *name) const
3003 {
3004 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
3005 auto extension = extensionInfos.find(name);
3006
3007 return extension != extensionInfos.end() && extension->second.Disablable &&
3008 mSupportedExtensions.*(extension->second.ExtensionsMember);
3009 }
3010
requestExtension(const char * name)3011 void Context::requestExtension(const char *name)
3012 {
3013 setExtensionEnabled(name, true);
3014 }
disableExtension(const char * name)3015 void Context::disableExtension(const char *name)
3016 {
3017 setExtensionEnabled(name, false);
3018 }
3019
setExtensionEnabled(const char * name,bool enabled)3020 void Context::setExtensionEnabled(const char *name, bool enabled)
3021 {
3022 // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
3023 if (strcmp(name, "GL_OVR_multiview2") == 0)
3024 {
3025 setExtensionEnabled("GL_OVR_multiview", enabled);
3026 }
3027 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
3028 ASSERT(extensionInfos.find(name) != extensionInfos.end());
3029 const auto &extension = extensionInfos.at(name);
3030 ASSERT(extension.Requestable);
3031 ASSERT(isExtensionRequestable(name));
3032
3033 if (mState.mExtensions.*(extension.ExtensionsMember) == enabled)
3034 {
3035 // No change
3036 return;
3037 }
3038
3039 mState.mExtensions.*(extension.ExtensionsMember) = enabled;
3040
3041 reinitializeAfterExtensionsChanged();
3042 }
3043
reinitializeAfterExtensionsChanged()3044 void Context::reinitializeAfterExtensionsChanged()
3045 {
3046 updateCaps();
3047 initExtensionStrings();
3048
3049 // Release the shader compiler so it will be re-created with the requested extensions enabled.
3050 releaseShaderCompiler();
3051
3052 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
3053 // sampleable.
3054 mState.mTextureManager->signalAllTexturesDirty();
3055 for (auto &zeroTexture : mZeroTextures)
3056 {
3057 if (zeroTexture.get() != nullptr)
3058 {
3059 zeroTexture->signalDirtyStorage(InitState::Initialized);
3060 }
3061 }
3062
3063 mState.mFramebufferManager->invalidateFramebufferCompletenessCache();
3064 }
3065
getRequestableExtensionStringCount() const3066 size_t Context::getRequestableExtensionStringCount() const
3067 {
3068 return mRequestableExtensionStrings.size();
3069 }
3070
beginTransformFeedback(PrimitiveMode primitiveMode)3071 void Context::beginTransformFeedback(PrimitiveMode primitiveMode)
3072 {
3073 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
3074 ASSERT(transformFeedback != nullptr);
3075 ASSERT(!transformFeedback->isPaused());
3076
3077 // TODO: http://anglebug.com/3570: Handle PPOs
3078 ANGLE_CONTEXT_TRY(transformFeedback->begin(this, primitiveMode, mState.getProgram()));
3079 mStateCache.onActiveTransformFeedbackChange(this);
3080 }
3081
hasActiveTransformFeedback(ShaderProgramID program) const3082 bool Context::hasActiveTransformFeedback(ShaderProgramID program) const
3083 {
3084 for (auto pair : mTransformFeedbackMap)
3085 {
3086 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
3087 {
3088 return true;
3089 }
3090 }
3091 return false;
3092 }
3093
generateSupportedExtensions() const3094 Extensions Context::generateSupportedExtensions() const
3095 {
3096 Extensions supportedExtensions = mImplementation->getNativeExtensions();
3097
3098 // Explicitly enable GL_KHR_parallel_shader_compile
3099 supportedExtensions.parallelShaderCompile = true;
3100
3101 if (getClientVersion() < ES_2_0)
3102 {
3103 // Default extensions for GLES1
3104 supportedExtensions.pointSizeArrayOES = true;
3105 supportedExtensions.textureCubeMapOES = true;
3106 supportedExtensions.pointSpriteOES = true;
3107 supportedExtensions.drawTextureOES = true;
3108 supportedExtensions.parallelShaderCompile = false;
3109 supportedExtensions.texture3DOES = false;
3110 }
3111
3112 if (getClientVersion() < ES_3_0)
3113 {
3114 // Disable ES3+ extensions
3115 supportedExtensions.colorBufferFloat = false;
3116 supportedExtensions.eglImageExternalEssl3OES = false;
3117 supportedExtensions.textureNorm16 = false;
3118 supportedExtensions.multiview = false;
3119 supportedExtensions.multiview2 = false;
3120 supportedExtensions.maxViews = 1u;
3121 supportedExtensions.copyTexture3d = false;
3122 supportedExtensions.textureMultisample = false;
3123 supportedExtensions.drawBuffersIndexedEXT = false;
3124 supportedExtensions.drawBuffersIndexedOES = false;
3125 supportedExtensions.eglImageArray = false;
3126
3127 // Requires glCompressedTexImage3D
3128 supportedExtensions.textureCompressionASTCOES = false;
3129
3130 // Don't expose GL_EXT_texture_sRGB_decode without sRGB texture support
3131 if (!supportedExtensions.sRGB)
3132 {
3133 supportedExtensions.textureSRGBDecode = false;
3134 }
3135
3136 // Don't expose GL_OES_texture_float_linear without full legacy float texture support
3137 // The renderer may report OES_texture_float_linear without OES_texture_float
3138 // This is valid in a GLES 3.0 context, but not in a GLES 2.0 context
3139 if (!(supportedExtensions.textureFloatOES && supportedExtensions.textureHalfFloat))
3140 {
3141 supportedExtensions.textureFloatLinearOES = false;
3142 supportedExtensions.textureHalfFloatLinear = false;
3143 }
3144
3145 // Because of the difference in the SNORM to FLOAT conversion formula
3146 // between GLES 2.0 and 3.0, vertex type 10_10_10_2 is disabled
3147 // when the context version is lower than 3.0
3148 supportedExtensions.vertexAttribType1010102OES = false;
3149 }
3150
3151 if (getClientVersion() < ES_3_1)
3152 {
3153 // Disable ES3.1+ extensions
3154 supportedExtensions.geometryShader = false;
3155
3156 // TODO(http://anglebug.com/2775): Multisample arrays could be supported on ES 3.0 as well
3157 // once 2D multisample texture extension is exposed there.
3158 supportedExtensions.textureStorageMultisample2DArrayOES = false;
3159 }
3160
3161 if (getClientVersion() > ES_2_0)
3162 {
3163 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
3164 // supportedExtensions.sRGB = false;
3165
3166 // If colorBufferFloat is disabled but colorBufferHalfFloat is enabled, then we will expose
3167 // some floating-point formats as color buffer targets but reject blits between fixed-point
3168 // and floating-point formats (this behavior is only enabled in colorBufferFloat, and must
3169 // be rejected if only colorBufferHalfFloat is enabled).
3170 // dEQP does not check for this, and will assume that floating-point and fixed-point formats
3171 // can be blit onto each other if the format is available.
3172 // We require colorBufferFloat to be present in order to enable colorBufferHalfFloat, so
3173 // that blitting is always allowed if the requested formats are exposed and have the correct
3174 // feature capabilities
3175 if (!supportedExtensions.colorBufferFloat)
3176 {
3177 supportedExtensions.colorBufferHalfFloat = false;
3178 }
3179
3180 // Disable support for CHROMIUM_color_buffer_float_rgb[a] in ES 3.0+, these extensions are
3181 // non-conformant in ES 3.0 and superseded by EXT_color_buffer_float.
3182 supportedExtensions.colorBufferFloatRGB = false;
3183 supportedExtensions.colorBufferFloatRGBA = false;
3184 }
3185
3186 // Some extensions are always available because they are implemented in the GL layer.
3187 supportedExtensions.bindUniformLocation = true;
3188 supportedExtensions.vertexArrayObjectOES = true;
3189 supportedExtensions.bindGeneratesResource = true;
3190 supportedExtensions.clientArrays = true;
3191 supportedExtensions.requestExtension = true;
3192 supportedExtensions.multiDraw = true;
3193
3194 // Enable the no error extension if the context was created with the flag.
3195 supportedExtensions.noError = mSkipValidation;
3196
3197 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
3198 supportedExtensions.surfacelessContextOES = mSurfacelessSupported;
3199
3200 // Explicitly enable GL_KHR_debug
3201 supportedExtensions.debug = true;
3202 supportedExtensions.maxDebugMessageLength = 1024;
3203 supportedExtensions.maxDebugLoggedMessages = 1024;
3204 supportedExtensions.maxDebugGroupStackDepth = 1024;
3205 supportedExtensions.maxLabelLength = 1024;
3206
3207 // Explicitly enable GL_ANGLE_robust_client_memory if the context supports validation.
3208 supportedExtensions.robustClientMemory = !mSkipValidation;
3209
3210 // Determine robust resource init availability from EGL.
3211 supportedExtensions.robustResourceInitialization = mState.isRobustResourceInitEnabled();
3212
3213 // mState.mExtensions.robustBufferAccessBehavior is true only if robust access is true and the
3214 // backend supports it.
3215 supportedExtensions.robustBufferAccessBehavior =
3216 mRobustAccess && supportedExtensions.robustBufferAccessBehavior;
3217
3218 // Enable the cache control query unconditionally.
3219 supportedExtensions.programCacheControl = true;
3220
3221 // Enable EGL_ANGLE_explicit_context subextensions
3222 if (mExplicitContextAvailable)
3223 {
3224 // GL_ANGLE_explicit_context_gles1
3225 supportedExtensions.explicitContextGles1 = true;
3226 // GL_ANGLE_explicit_context
3227 supportedExtensions.explicitContext = true;
3228 }
3229
3230 // If EGL_KHR_fence_sync is not enabled, don't expose GL_OES_EGL_sync.
3231 ASSERT(mDisplay);
3232 if (!mDisplay->getExtensions().fenceSync)
3233 {
3234 supportedExtensions.eglSyncOES = false;
3235 }
3236
3237 supportedExtensions.memorySize = true;
3238
3239 // GL_CHROMIUM_lose_context is implemented in the frontend
3240 supportedExtensions.loseContextCHROMIUM = true;
3241
3242 // The ASTC texture extensions have dependency requirements.
3243 if (supportedExtensions.textureCompressionASTCHDRKHR ||
3244 supportedExtensions.textureCompressionSliced3dASTCKHR)
3245 {
3246 // GL_KHR_texture_compression_astc_hdr cannot be exposed without also exposing
3247 // GL_KHR_texture_compression_astc_ldr
3248 ASSERT(supportedExtensions.textureCompressionASTCLDRKHR);
3249 }
3250
3251 if (supportedExtensions.textureCompressionASTCOES)
3252 {
3253 // GL_OES_texture_compression_astc cannot be exposed without also exposing
3254 // GL_KHR_texture_compression_astc_ldr and GL_KHR_texture_compression_astc_hdr
3255 ASSERT(supportedExtensions.textureCompressionASTCLDRKHR);
3256 ASSERT(supportedExtensions.textureCompressionASTCHDRKHR);
3257 }
3258
3259 return supportedExtensions;
3260 }
3261
initCaps()3262 void Context::initCaps()
3263 {
3264 mState.mCaps = mImplementation->getNativeCaps();
3265
3266 mSupportedExtensions = generateSupportedExtensions();
3267 mState.mExtensions = mSupportedExtensions;
3268
3269 mState.mLimitations = mImplementation->getNativeLimitations();
3270
3271 // GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
3272 if (getClientType() == EGL_OPENGL_API || getClientVersion() < Version(2, 0))
3273 {
3274 mState.mCaps.maxMultitextureUnits = 4;
3275 mState.mCaps.maxClipPlanes = 6;
3276 mState.mCaps.maxLights = 8;
3277 mState.mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth;
3278 mState.mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
3279 mState.mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth;
3280 mState.mCaps.minSmoothPointSize = 1.0f;
3281 mState.mCaps.maxSmoothPointSize = 1.0f;
3282 mState.mCaps.minSmoothLineWidth = 1.0f;
3283 mState.mCaps.maxSmoothLineWidth = 1.0f;
3284 }
3285
3286 // If we're capturing application calls for replay, don't expose any binary formats to prevent
3287 // traces from trying to use cached results
3288 if (getFrameCapture()->enabled())
3289 {
3290 INFO() << "Limiting binary format support count to zero while FrameCapture enabled"
3291 << std::endl;
3292 mState.mCaps.shaderBinaryFormats.clear();
3293 mState.mCaps.programBinaryFormats.clear();
3294 }
3295
3296 #if 0
3297 // This logging can generate a lot of spam in test suites that create many contexts
3298 # define ANGLE_LOG_LIMITED_CAP(cap, limit) \
3299 INFO() << "Limiting " << #cap << " to implementation limit " << (limit) << " (was " \
3300 << (cap) << ")."
3301 #else
3302 # define ANGLE_LOG_LIMITED_CAP(cap, limit)
3303 #endif
3304
3305 #define ANGLE_LIMIT_CAP(cap, limit) \
3306 do \
3307 { \
3308 if ((cap) > (limit)) \
3309 { \
3310 ANGLE_LOG_LIMITED_CAP(cap, limit); \
3311 (cap) = (limit); \
3312 } \
3313 } while (0)
3314
3315 // Apply/Verify implementation limits
3316 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
3317 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribStride,
3318 static_cast<GLint>(limits::kMaxVertexAttribStride));
3319
3320 ASSERT(mState.mCaps.minAliasedPointSize >= 1.0f);
3321
3322 if (getClientVersion() < ES_3_1)
3323 {
3324 mState.mCaps.maxVertexAttribBindings = mState.mCaps.maxVertexAttributes;
3325 }
3326 else
3327 {
3328 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
3329 }
3330
3331 ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
3332 ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
3333 ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
3334 ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS);
3335 ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
3336
3337 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex],
3338 IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
3339 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry],
3340 IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS);
3341 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment],
3342 IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS);
3343 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute],
3344 IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS);
3345 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedUniformBlocks,
3346 IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
3347 ANGLE_LIMIT_CAP(mState.mCaps.maxUniformBufferBindings,
3348 IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
3349
3350 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
3351 ANGLE_LIMIT_CAP(mState.mCaps.maxFragmentInputComponents,
3352 IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
3353
3354 ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackInterleavedComponents,
3355 IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
3356 ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateAttributes,
3357 IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
3358 ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateComponents,
3359 IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
3360
3361 // Limit textures as well, so we can use fast bitsets with texture bindings.
3362 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
3363 for (ShaderType shaderType : AllShaderTypes())
3364 {
3365 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderTextureImageUnits[shaderType],
3366 IMPLEMENTATION_MAX_SHADER_TEXTURES);
3367 }
3368
3369 ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS);
3370 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedImageUniforms, IMPLEMENTATION_MAX_IMAGE_UNITS);
3371 for (ShaderType shaderType : AllShaderTypes())
3372 {
3373 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType],
3374 IMPLEMENTATION_MAX_IMAGE_UNITS);
3375 }
3376
3377 for (ShaderType shaderType : AllShaderTypes())
3378 {
3379 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType],
3380 IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS);
3381 }
3382 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedAtomicCounterBuffers,
3383 IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS);
3384
3385 for (ShaderType shaderType : AllShaderTypes())
3386 {
3387 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType],
3388 IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
3389 }
3390 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings,
3391 IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
3392 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedShaderStorageBlocks,
3393 IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
3394
3395 ANGLE_LIMIT_CAP(mState.mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
3396
3397 #undef ANGLE_LIMIT_CAP
3398 #undef ANGLE_LOG_CAP_LIMIT
3399
3400 // WebGL compatibility
3401 mState.mExtensions.webglCompatibility = mWebGLContext;
3402 for (const auto &extensionInfo : GetExtensionInfoMap())
3403 {
3404 // If the user has requested that extensions start disabled and they are requestable,
3405 // disable them.
3406 if (!mExtensionsEnabled && extensionInfo.second.Requestable)
3407 {
3408 mState.mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
3409 }
3410 }
3411
3412 // Generate texture caps
3413 updateCaps();
3414 }
3415
updateCaps()3416 void Context::updateCaps()
3417 {
3418 mState.mCaps.compressedTextureFormats.clear();
3419 mState.mTextureCaps.clear();
3420
3421 for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
3422 {
3423 TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
3424 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
3425
3426 // Update the format caps based on the client version and extensions.
3427 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
3428 // ES3.
3429 formatCaps.texturable = formatCaps.texturable &&
3430 formatInfo.textureSupport(getClientVersion(), mState.mExtensions);
3431 formatCaps.filterable = formatCaps.filterable &&
3432 formatInfo.filterSupport(getClientVersion(), mState.mExtensions);
3433 formatCaps.textureAttachment =
3434 formatCaps.textureAttachment &&
3435 formatInfo.textureAttachmentSupport(getClientVersion(), mState.mExtensions);
3436 formatCaps.renderbuffer =
3437 formatCaps.renderbuffer &&
3438 formatInfo.renderbufferSupport(getClientVersion(), mState.mExtensions);
3439 formatCaps.blendable =
3440 formatCaps.blendable && formatInfo.blendSupport(getClientVersion(), mState.mExtensions);
3441
3442 // OpenGL ES does not support multisampling with non-rendererable formats
3443 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
3444 if (!formatCaps.renderbuffer ||
3445 (getClientVersion() < ES_3_1 && !mSupportedExtensions.textureMultisample &&
3446 formatInfo.isInt()))
3447 {
3448 formatCaps.sampleCounts.clear();
3449 }
3450 else
3451 {
3452 // We may have limited the max samples for some required renderbuffer formats due to
3453 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
3454 GLuint formatMaxSamples = formatCaps.getMaxSamples();
3455
3456 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
3457 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
3458 // exception of signed and unsigned integer formats."
3459 if (!formatInfo.isInt() && formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
3460 {
3461 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
3462 mState.mCaps.maxSamples =
3463 std::min(static_cast<GLuint>(mState.mCaps.maxSamples), formatMaxSamples);
3464 }
3465
3466 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
3467 if (getClientVersion() >= ES_3_1 || mSupportedExtensions.textureMultisample)
3468 {
3469 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
3470 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
3471 // the exception that the signed and unsigned integer formats are required only to
3472 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
3473 // multisamples, which must be at least one."
3474 if (formatInfo.isInt())
3475 {
3476 mState.mCaps.maxIntegerSamples = std::min(
3477 static_cast<GLuint>(mState.mCaps.maxIntegerSamples), formatMaxSamples);
3478 }
3479
3480 // GLES 3.1 section 19.3.1.
3481 if (formatCaps.texturable)
3482 {
3483 if (formatInfo.depthBits > 0)
3484 {
3485 mState.mCaps.maxDepthTextureSamples =
3486 std::min(static_cast<GLuint>(mState.mCaps.maxDepthTextureSamples),
3487 formatMaxSamples);
3488 }
3489 else if (formatInfo.redBits > 0)
3490 {
3491 mState.mCaps.maxColorTextureSamples =
3492 std::min(static_cast<GLuint>(mState.mCaps.maxColorTextureSamples),
3493 formatMaxSamples);
3494 }
3495 }
3496 }
3497 }
3498
3499 if (formatCaps.texturable && formatInfo.compressed)
3500 {
3501 mState.mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
3502 }
3503
3504 mState.mTextureCaps.insert(sizedInternalFormat, formatCaps);
3505 }
3506
3507 // If program binary is disabled, blank out the memory cache pointer.
3508 if (!mSupportedExtensions.getProgramBinaryOES)
3509 {
3510 mMemoryProgramCache = nullptr;
3511 }
3512
3513 // Compute which buffer types are allowed
3514 mValidBufferBindings.reset();
3515 mValidBufferBindings.set(BufferBinding::ElementArray);
3516 mValidBufferBindings.set(BufferBinding::Array);
3517
3518 if (mState.mExtensions.pixelBufferObjectNV || getClientVersion() >= ES_3_0)
3519 {
3520 mValidBufferBindings.set(BufferBinding::PixelPack);
3521 mValidBufferBindings.set(BufferBinding::PixelUnpack);
3522 }
3523
3524 if (getClientVersion() >= ES_3_0)
3525 {
3526 mValidBufferBindings.set(BufferBinding::CopyRead);
3527 mValidBufferBindings.set(BufferBinding::CopyWrite);
3528 mValidBufferBindings.set(BufferBinding::TransformFeedback);
3529 mValidBufferBindings.set(BufferBinding::Uniform);
3530 }
3531
3532 if (getClientVersion() >= ES_3_1)
3533 {
3534 mValidBufferBindings.set(BufferBinding::AtomicCounter);
3535 mValidBufferBindings.set(BufferBinding::ShaderStorage);
3536 mValidBufferBindings.set(BufferBinding::DrawIndirect);
3537 mValidBufferBindings.set(BufferBinding::DispatchIndirect);
3538 }
3539
3540 mThreadPool = angle::WorkerThreadPool::Create(mState.mExtensions.parallelShaderCompile);
3541
3542 // Reinitialize some dirty bits that depend on extensions.
3543 if (mState.isRobustResourceInitEnabled())
3544 {
3545 mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
3546 mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
3547 mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
3548 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
3549 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
3550 mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
3551 mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
3552 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
3553 mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
3554 mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
3555 }
3556
3557 // We need to validate buffer bounds if we are in a WebGL or robust access context and the
3558 // back-end does not support robust buffer access behaviour.
3559 mBufferAccessValidationEnabled =
3560 (!mSupportedExtensions.robustBufferAccessBehavior && (mState.isWebGL() || mRobustAccess));
3561
3562 // Cache this in the VertexArrays. They need to check it in state change notifications.
3563 for (auto vaoIter : mVertexArrayMap)
3564 {
3565 VertexArray *vao = vaoIter.second;
3566 vao->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
3567 }
3568
3569 // Reinitialize state cache after extension changes.
3570 mStateCache.initialize(this);
3571 }
3572
noopDrawInstanced(PrimitiveMode mode,GLsizei count,GLsizei instanceCount)3573 bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount)
3574 {
3575 return (instanceCount == 0) || noopDraw(mode, count);
3576 }
3577
prepareForClear(GLbitfield mask)3578 angle::Result Context::prepareForClear(GLbitfield mask)
3579 {
3580 // Sync the draw framebuffer manually after the clear attachments.
3581 ASSERT(mClearDirtyObjects.none());
3582 ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask));
3583 ANGLE_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
3584 ANGLE_TRY(syncDirtyBits(mClearDirtyBits));
3585 return angle::Result::Continue;
3586 }
3587
prepareForClearBuffer(GLenum buffer,GLint drawbuffer)3588 angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
3589 {
3590 // Sync the draw framebuffer manually after the clear attachments.
3591 ASSERT(mClearDirtyObjects.none());
3592 ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer,
3593 drawbuffer));
3594 ANGLE_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
3595 ANGLE_TRY(syncDirtyBits(mClearDirtyBits));
3596 return angle::Result::Continue;
3597 }
3598
prepareForCopyImage()3599 ANGLE_INLINE angle::Result Context::prepareForCopyImage()
3600 {
3601 ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects));
3602 return syncDirtyBits(mCopyImageDirtyBits);
3603 }
3604
prepareForDispatch()3605 ANGLE_INLINE angle::Result Context::prepareForDispatch()
3606 {
3607 // We always assume PPOs are used for draws, until they aren't. If we are executing a dispatch
3608 // with a PPO, we need to convert it from a "draw"-type to "dispatch"-type.
3609 convertPpoToComputeOrDraw(true);
3610
3611 ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects));
3612 return syncDirtyBits(mComputeDirtyBits);
3613 }
3614
syncState(const State::DirtyBits & bitMask,const State::DirtyObjects & objectMask)3615 angle::Result Context::syncState(const State::DirtyBits &bitMask,
3616 const State::DirtyObjects &objectMask)
3617 {
3618 ANGLE_TRY(syncDirtyObjects(objectMask));
3619 ANGLE_TRY(syncDirtyBits(bitMask));
3620 return angle::Result::Continue;
3621 }
3622
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)3623 void Context::blitFramebuffer(GLint srcX0,
3624 GLint srcY0,
3625 GLint srcX1,
3626 GLint srcY1,
3627 GLint dstX0,
3628 GLint dstY0,
3629 GLint dstX1,
3630 GLint dstY1,
3631 GLbitfield mask,
3632 GLenum filter)
3633 {
3634 if (mask == 0)
3635 {
3636 // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no
3637 // buffers are copied.
3638 return;
3639 }
3640
3641 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
3642 ASSERT(drawFramebuffer);
3643
3644 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
3645 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
3646
3647 if (dstArea.width == 0 || dstArea.height == 0)
3648 {
3649 return;
3650 }
3651
3652 ANGLE_CONTEXT_TRY(syncStateForBlit());
3653
3654 ANGLE_CONTEXT_TRY(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
3655 }
3656
clear(GLbitfield mask)3657 void Context::clear(GLbitfield mask)
3658 {
3659 ANGLE_CONTEXT_TRY(prepareForClear(mask));
3660 ANGLE_CONTEXT_TRY(mState.getDrawFramebuffer()->clear(this, mask));
3661 }
3662
clearBufferfv(GLenum buffer,GLint drawbuffer,const GLfloat * values)3663 void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
3664 {
3665 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3666 const FramebufferAttachment *attachment = nullptr;
3667 if (buffer == GL_DEPTH)
3668 {
3669 attachment = framebufferObject->getDepthAttachment();
3670 }
3671 if (buffer == GL_COLOR &&
3672 static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
3673 {
3674 attachment = framebufferObject->getColorAttachment(drawbuffer);
3675 }
3676 // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
3677 // that the backend doesn't need to take this case into account.
3678 if (!attachment)
3679 {
3680 return;
3681 }
3682 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3683 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values));
3684 }
3685
clearBufferuiv(GLenum buffer,GLint drawbuffer,const GLuint * values)3686 void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
3687 {
3688 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3689 const FramebufferAttachment *attachment = nullptr;
3690 if (buffer == GL_COLOR &&
3691 static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
3692 {
3693 attachment = framebufferObject->getColorAttachment(drawbuffer);
3694 }
3695 // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
3696 // that the backend doesn't need to take this case into account.
3697 if (!attachment)
3698 {
3699 return;
3700 }
3701 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3702 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values));
3703 }
3704
clearBufferiv(GLenum buffer,GLint drawbuffer,const GLint * values)3705 void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
3706 {
3707 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3708 const FramebufferAttachment *attachment = nullptr;
3709 if (buffer == GL_STENCIL)
3710 {
3711 attachment = framebufferObject->getStencilAttachment();
3712 }
3713 if (buffer == GL_COLOR &&
3714 static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
3715 {
3716 attachment = framebufferObject->getColorAttachment(drawbuffer);
3717 }
3718 // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
3719 // that the backend doesn't need to take this case into account.
3720 if (!attachment)
3721 {
3722 return;
3723 }
3724 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3725 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values));
3726 }
3727
clearBufferfi(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)3728 void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
3729 {
3730 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3731 ASSERT(framebufferObject);
3732
3733 // If a buffer is not present, the clear has no effect
3734 if (framebufferObject->getDepthAttachment() == nullptr &&
3735 framebufferObject->getStencilAttachment() == nullptr)
3736 {
3737 return;
3738 }
3739
3740 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3741 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
3742 }
3743
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,void * pixels)3744 void Context::readPixels(GLint x,
3745 GLint y,
3746 GLsizei width,
3747 GLsizei height,
3748 GLenum format,
3749 GLenum type,
3750 void *pixels)
3751 {
3752 if (width == 0 || height == 0)
3753 {
3754 return;
3755 }
3756
3757 ANGLE_CONTEXT_TRY(syncStateForReadPixels());
3758
3759 Framebuffer *readFBO = mState.getReadFramebuffer();
3760 ASSERT(readFBO);
3761
3762 Rectangle area(x, y, width, height);
3763 ANGLE_CONTEXT_TRY(readFBO->readPixels(this, area, format, type, pixels));
3764 }
3765
readPixelsRobust(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLsizei * length,GLsizei * columns,GLsizei * rows,void * pixels)3766 void Context::readPixelsRobust(GLint x,
3767 GLint y,
3768 GLsizei width,
3769 GLsizei height,
3770 GLenum format,
3771 GLenum type,
3772 GLsizei bufSize,
3773 GLsizei *length,
3774 GLsizei *columns,
3775 GLsizei *rows,
3776 void *pixels)
3777 {
3778 readPixels(x, y, width, height, format, type, pixels);
3779 }
3780
readnPixelsRobust(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLsizei * length,GLsizei * columns,GLsizei * rows,void * data)3781 void Context::readnPixelsRobust(GLint x,
3782 GLint y,
3783 GLsizei width,
3784 GLsizei height,
3785 GLenum format,
3786 GLenum type,
3787 GLsizei bufSize,
3788 GLsizei *length,
3789 GLsizei *columns,
3790 GLsizei *rows,
3791 void *data)
3792 {
3793 readPixels(x, y, width, height, format, type, data);
3794 }
3795
copyTexImage2D(TextureTarget target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)3796 void Context::copyTexImage2D(TextureTarget target,
3797 GLint level,
3798 GLenum internalformat,
3799 GLint x,
3800 GLint y,
3801 GLsizei width,
3802 GLsizei height,
3803 GLint border)
3804 {
3805 ANGLE_CONTEXT_TRY(prepareForCopyImage());
3806
3807 Rectangle sourceArea(x, y, width, height);
3808
3809 Framebuffer *framebuffer = mState.getReadFramebuffer();
3810 Texture *texture = getTextureByTarget(target);
3811 ANGLE_CONTEXT_TRY(
3812 texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
3813 }
3814
copyTexSubImage2D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)3815 void Context::copyTexSubImage2D(TextureTarget target,
3816 GLint level,
3817 GLint xoffset,
3818 GLint yoffset,
3819 GLint x,
3820 GLint y,
3821 GLsizei width,
3822 GLsizei height)
3823 {
3824 if (width == 0 || height == 0)
3825 {
3826 return;
3827 }
3828
3829 ANGLE_CONTEXT_TRY(prepareForCopyImage());
3830
3831 Offset destOffset(xoffset, yoffset, 0);
3832 Rectangle sourceArea(x, y, width, height);
3833
3834 ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1);
3835
3836 Framebuffer *framebuffer = mState.getReadFramebuffer();
3837 Texture *texture = getTextureByTarget(target);
3838 ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
3839 }
3840
copyTexSubImage3D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)3841 void Context::copyTexSubImage3D(TextureTarget target,
3842 GLint level,
3843 GLint xoffset,
3844 GLint yoffset,
3845 GLint zoffset,
3846 GLint x,
3847 GLint y,
3848 GLsizei width,
3849 GLsizei height)
3850 {
3851 if (width == 0 || height == 0)
3852 {
3853 return;
3854 }
3855
3856 ANGLE_CONTEXT_TRY(prepareForCopyImage());
3857
3858 Offset destOffset(xoffset, yoffset, zoffset);
3859 Rectangle sourceArea(x, y, width, height);
3860
3861 ImageIndex index = ImageIndex::MakeFromType(TextureTargetToType(target), level, zoffset);
3862
3863 Framebuffer *framebuffer = mState.getReadFramebuffer();
3864 Texture *texture = getTextureByTarget(target);
3865 ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
3866 }
3867
copyImageSubData(GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)3868 void Context::copyImageSubData(GLuint srcName,
3869 GLenum srcTarget,
3870 GLint srcLevel,
3871 GLint srcX,
3872 GLint srcY,
3873 GLint srcZ,
3874 GLuint dstName,
3875 GLenum dstTarget,
3876 GLint dstLevel,
3877 GLint dstX,
3878 GLint dstY,
3879 GLint dstZ,
3880 GLsizei srcWidth,
3881 GLsizei srcHeight,
3882 GLsizei srcDepth)
3883 {
3884 UNIMPLEMENTED();
3885 }
3886
framebufferTexture2D(GLenum target,GLenum attachment,TextureTarget textarget,TextureID texture,GLint level)3887 void Context::framebufferTexture2D(GLenum target,
3888 GLenum attachment,
3889 TextureTarget textarget,
3890 TextureID texture,
3891 GLint level)
3892 {
3893 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3894 ASSERT(framebuffer);
3895
3896 if (texture.value != 0)
3897 {
3898 Texture *textureObj = getTexture(texture);
3899 ImageIndex index = ImageIndex::MakeFromTarget(textarget, level, 1);
3900 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
3901 }
3902 else
3903 {
3904 framebuffer->resetAttachment(this, attachment);
3905 }
3906
3907 mState.setObjectDirty(target);
3908 }
3909
framebufferTexture3D(GLenum target,GLenum attachment,TextureTarget textargetPacked,TextureID texture,GLint level,GLint zoffset)3910 void Context::framebufferTexture3D(GLenum target,
3911 GLenum attachment,
3912 TextureTarget textargetPacked,
3913 TextureID texture,
3914 GLint level,
3915 GLint zoffset)
3916 {
3917 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3918 ASSERT(framebuffer);
3919
3920 if (texture.value != 0)
3921 {
3922 Texture *textureObj = getTexture(texture);
3923 ImageIndex index = ImageIndex::Make3D(level, zoffset);
3924 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
3925 }
3926 else
3927 {
3928 framebuffer->resetAttachment(this, attachment);
3929 }
3930
3931 mState.setObjectDirty(target);
3932 }
3933
framebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,RenderbufferID renderbuffer)3934 void Context::framebufferRenderbuffer(GLenum target,
3935 GLenum attachment,
3936 GLenum renderbuffertarget,
3937 RenderbufferID renderbuffer)
3938 {
3939 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3940 ASSERT(framebuffer);
3941
3942 if (renderbuffer.value != 0)
3943 {
3944 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
3945 GLsizei rbSamples = renderbufferObject->getSamples();
3946
3947 framebuffer->setAttachmentMultisample(this, GL_RENDERBUFFER, attachment, gl::ImageIndex(),
3948 renderbufferObject, rbSamples);
3949 }
3950 else
3951 {
3952 framebuffer->resetAttachment(this, attachment);
3953 }
3954
3955 mState.setObjectDirty(target);
3956 }
3957
framebufferTextureLayer(GLenum target,GLenum attachment,TextureID texture,GLint level,GLint layer)3958 void Context::framebufferTextureLayer(GLenum target,
3959 GLenum attachment,
3960 TextureID texture,
3961 GLint level,
3962 GLint layer)
3963 {
3964 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3965 ASSERT(framebuffer);
3966
3967 if (texture.value != 0)
3968 {
3969 Texture *textureObject = getTexture(texture);
3970 ImageIndex index = ImageIndex::MakeFromType(textureObject->getType(), level, layer);
3971 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
3972 }
3973 else
3974 {
3975 framebuffer->resetAttachment(this, attachment);
3976 }
3977
3978 mState.setObjectDirty(target);
3979 }
3980
framebufferTextureMultiview(GLenum target,GLenum attachment,TextureID texture,GLint level,GLint baseViewIndex,GLsizei numViews)3981 void Context::framebufferTextureMultiview(GLenum target,
3982 GLenum attachment,
3983 TextureID texture,
3984 GLint level,
3985 GLint baseViewIndex,
3986 GLsizei numViews)
3987 {
3988 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3989 ASSERT(framebuffer);
3990
3991 if (texture.value != 0)
3992 {
3993 Texture *textureObj = getTexture(texture);
3994
3995 ImageIndex index;
3996 if (textureObj->getType() == TextureType::_2DArray)
3997 {
3998 index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
3999 }
4000 else
4001 {
4002 ASSERT(textureObj->getType() == TextureType::_2DMultisampleArray);
4003 ASSERT(level == 0);
4004 index = ImageIndex::Make2DMultisampleArrayRange(baseViewIndex, numViews);
4005 }
4006 framebuffer->setAttachmentMultiview(this, GL_TEXTURE, attachment, index, textureObj,
4007 numViews, baseViewIndex);
4008 }
4009 else
4010 {
4011 framebuffer->resetAttachment(this, attachment);
4012 }
4013
4014 mState.setObjectDirty(target);
4015 }
4016
framebufferTexture(GLenum target,GLenum attachment,TextureID texture,GLint level)4017 void Context::framebufferTexture(GLenum target, GLenum attachment, TextureID texture, GLint level)
4018 {
4019 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4020 ASSERT(framebuffer);
4021
4022 if (texture.value != 0)
4023 {
4024 Texture *textureObj = getTexture(texture);
4025
4026 ImageIndex index = ImageIndex::MakeFromType(
4027 textureObj->getType(), level, ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
4028 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
4029 }
4030 else
4031 {
4032 framebuffer->resetAttachment(this, attachment);
4033 }
4034
4035 mState.setObjectDirty(target);
4036 }
4037
drawBuffers(GLsizei n,const GLenum * bufs)4038 void Context::drawBuffers(GLsizei n, const GLenum *bufs)
4039 {
4040 Framebuffer *framebuffer = mState.getDrawFramebuffer();
4041 ASSERT(framebuffer);
4042 framebuffer->setDrawBuffers(n, bufs);
4043 mState.setDrawFramebufferDirty();
4044 mStateCache.onDrawFramebufferChange(this);
4045 }
4046
readBuffer(GLenum mode)4047 void Context::readBuffer(GLenum mode)
4048 {
4049 Framebuffer *readFBO = mState.getReadFramebuffer();
4050 readFBO->setReadBuffer(mode);
4051 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
4052 }
4053
discardFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments)4054 void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
4055 {
4056 // Only sync the FBO
4057 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, target));
4058
4059 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4060 ASSERT(framebuffer);
4061
4062 // The specification isn't clear what should be done when the framebuffer isn't complete.
4063 // We leave it up to the framebuffer implementation to decide what to do.
4064 ANGLE_CONTEXT_TRY(framebuffer->discard(this, numAttachments, attachments));
4065 }
4066
invalidateFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments)4067 void Context::invalidateFramebuffer(GLenum target,
4068 GLsizei numAttachments,
4069 const GLenum *attachments)
4070 {
4071 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4072 ASSERT(framebuffer);
4073
4074 // No-op incomplete FBOs.
4075 if (!framebuffer->isComplete(this))
4076 {
4077 return;
4078 }
4079
4080 // Only sync the FBO
4081 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, target));
4082 ANGLE_CONTEXT_TRY(framebuffer->invalidate(this, numAttachments, attachments));
4083 }
4084
invalidateSubFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)4085 void Context::invalidateSubFramebuffer(GLenum target,
4086 GLsizei numAttachments,
4087 const GLenum *attachments,
4088 GLint x,
4089 GLint y,
4090 GLsizei width,
4091 GLsizei height)
4092 {
4093 // Only sync the FBO
4094 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, target));
4095
4096 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4097 ASSERT(framebuffer);
4098
4099 if (!framebuffer->isComplete(this))
4100 {
4101 return;
4102 }
4103
4104 Rectangle area(x, y, width, height);
4105 ANGLE_CONTEXT_TRY(framebuffer->invalidateSub(this, numAttachments, attachments, area));
4106 }
4107
texImage2D(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const void * pixels)4108 void Context::texImage2D(TextureTarget target,
4109 GLint level,
4110 GLint internalformat,
4111 GLsizei width,
4112 GLsizei height,
4113 GLint border,
4114 GLenum format,
4115 GLenum type,
4116 const void *pixels)
4117 {
4118 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4119
4120 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4121
4122 Extents size(width, height, 1);
4123 Texture *texture = getTextureByTarget(target);
4124 ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
4125 internalformat, size, format, type,
4126 static_cast<const uint8_t *>(pixels)));
4127 }
4128
texImage2DRobust(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4129 void Context::texImage2DRobust(TextureTarget target,
4130 GLint level,
4131 GLint internalformat,
4132 GLsizei width,
4133 GLsizei height,
4134 GLint border,
4135 GLenum format,
4136 GLenum type,
4137 GLsizei bufSize,
4138 const void *pixels)
4139 {
4140 texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
4141 }
4142
texImage3D(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const void * pixels)4143 void Context::texImage3D(TextureTarget target,
4144 GLint level,
4145 GLint internalformat,
4146 GLsizei width,
4147 GLsizei height,
4148 GLsizei depth,
4149 GLint border,
4150 GLenum format,
4151 GLenum type,
4152 const void *pixels)
4153 {
4154 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4155
4156 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4157
4158 Extents size(width, height, depth);
4159 Texture *texture = getTextureByTarget(target);
4160 ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
4161 internalformat, size, format, type,
4162 static_cast<const uint8_t *>(pixels)));
4163 }
4164
texImage3DRobust(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4165 void Context::texImage3DRobust(TextureTarget target,
4166 GLint level,
4167 GLint internalformat,
4168 GLsizei width,
4169 GLsizei height,
4170 GLsizei depth,
4171 GLint border,
4172 GLenum format,
4173 GLenum type,
4174 GLsizei bufSize,
4175 const void *pixels)
4176 {
4177 texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
4178 }
4179
texSubImage2D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * pixels)4180 void Context::texSubImage2D(TextureTarget target,
4181 GLint level,
4182 GLint xoffset,
4183 GLint yoffset,
4184 GLsizei width,
4185 GLsizei height,
4186 GLenum format,
4187 GLenum type,
4188 const void *pixels)
4189 {
4190 // Zero sized uploads are valid but no-ops
4191 if (width == 0 || height == 0)
4192 {
4193 return;
4194 }
4195
4196 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4197
4198 Box area(xoffset, yoffset, 0, width, height, 1);
4199 Texture *texture = getTextureByTarget(target);
4200
4201 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4202
4203 ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
4204 level, area, format, type,
4205 static_cast<const uint8_t *>(pixels)));
4206 }
4207
texSubImage2DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4208 void Context::texSubImage2DRobust(TextureTarget target,
4209 GLint level,
4210 GLint xoffset,
4211 GLint yoffset,
4212 GLsizei width,
4213 GLsizei height,
4214 GLenum format,
4215 GLenum type,
4216 GLsizei bufSize,
4217 const void *pixels)
4218 {
4219 texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
4220 }
4221
texSubImage3D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels)4222 void Context::texSubImage3D(TextureTarget target,
4223 GLint level,
4224 GLint xoffset,
4225 GLint yoffset,
4226 GLint zoffset,
4227 GLsizei width,
4228 GLsizei height,
4229 GLsizei depth,
4230 GLenum format,
4231 GLenum type,
4232 const void *pixels)
4233 {
4234 // Zero sized uploads are valid but no-ops
4235 if (width == 0 || height == 0 || depth == 0)
4236 {
4237 return;
4238 }
4239
4240 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4241
4242 Box area(xoffset, yoffset, zoffset, width, height, depth);
4243 Texture *texture = getTextureByTarget(target);
4244
4245 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4246
4247 ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
4248 level, area, format, type,
4249 static_cast<const uint8_t *>(pixels)));
4250 }
4251
texSubImage3DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4252 void Context::texSubImage3DRobust(TextureTarget target,
4253 GLint level,
4254 GLint xoffset,
4255 GLint yoffset,
4256 GLint zoffset,
4257 GLsizei width,
4258 GLsizei height,
4259 GLsizei depth,
4260 GLenum format,
4261 GLenum type,
4262 GLsizei bufSize,
4263 const void *pixels)
4264 {
4265 texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type,
4266 pixels);
4267 }
4268
compressedTexImage2D(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const void * data)4269 void Context::compressedTexImage2D(TextureTarget target,
4270 GLint level,
4271 GLenum internalformat,
4272 GLsizei width,
4273 GLsizei height,
4274 GLint border,
4275 GLsizei imageSize,
4276 const void *data)
4277 {
4278 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4279
4280 Extents size(width, height, 1);
4281 Texture *texture = getTextureByTarget(target);
4282 ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, mState.getUnpackState(), target, level,
4283 internalformat, size, imageSize,
4284 static_cast<const uint8_t *>(data)));
4285 }
4286
compressedTexImage2DRobust(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4287 void Context::compressedTexImage2DRobust(TextureTarget target,
4288 GLint level,
4289 GLenum internalformat,
4290 GLsizei width,
4291 GLsizei height,
4292 GLint border,
4293 GLsizei imageSize,
4294 GLsizei dataSize,
4295 const GLvoid *data)
4296 {
4297 compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
4298 }
4299
compressedTexImage3D(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const void * data)4300 void Context::compressedTexImage3D(TextureTarget target,
4301 GLint level,
4302 GLenum internalformat,
4303 GLsizei width,
4304 GLsizei height,
4305 GLsizei depth,
4306 GLint border,
4307 GLsizei imageSize,
4308 const void *data)
4309 {
4310 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4311
4312 Extents size(width, height, depth);
4313 Texture *texture = getTextureByTarget(target);
4314 ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, mState.getUnpackState(), target, level,
4315 internalformat, size, imageSize,
4316 static_cast<const uint8_t *>(data)));
4317 }
4318
compressedTexImage3DRobust(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4319 void Context::compressedTexImage3DRobust(TextureTarget target,
4320 GLint level,
4321 GLenum internalformat,
4322 GLsizei width,
4323 GLsizei height,
4324 GLsizei depth,
4325 GLint border,
4326 GLsizei imageSize,
4327 GLsizei dataSize,
4328 const GLvoid *data)
4329 {
4330 compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize,
4331 data);
4332 }
4333
compressedTexSubImage2D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const void * data)4334 void Context::compressedTexSubImage2D(TextureTarget target,
4335 GLint level,
4336 GLint xoffset,
4337 GLint yoffset,
4338 GLsizei width,
4339 GLsizei height,
4340 GLenum format,
4341 GLsizei imageSize,
4342 const void *data)
4343 {
4344 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4345
4346 Box area(xoffset, yoffset, 0, width, height, 1);
4347 Texture *texture = getTextureByTarget(target);
4348 ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, mState.getUnpackState(), target, level,
4349 area, format, imageSize,
4350 static_cast<const uint8_t *>(data)));
4351 }
4352
compressedTexSubImage2DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4353 void Context::compressedTexSubImage2DRobust(TextureTarget target,
4354 GLint level,
4355 GLint xoffset,
4356 GLint yoffset,
4357 GLsizei width,
4358 GLsizei height,
4359 GLenum format,
4360 GLsizei imageSize,
4361 GLsizei dataSize,
4362 const GLvoid *data)
4363 {
4364 compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize,
4365 data);
4366 }
4367
compressedTexSubImage3D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const void * data)4368 void Context::compressedTexSubImage3D(TextureTarget target,
4369 GLint level,
4370 GLint xoffset,
4371 GLint yoffset,
4372 GLint zoffset,
4373 GLsizei width,
4374 GLsizei height,
4375 GLsizei depth,
4376 GLenum format,
4377 GLsizei imageSize,
4378 const void *data)
4379 {
4380 // Zero sized uploads are valid but no-ops
4381 if (width == 0 || height == 0)
4382 {
4383 return;
4384 }
4385
4386 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4387
4388 Box area(xoffset, yoffset, zoffset, width, height, depth);
4389 Texture *texture = getTextureByTarget(target);
4390 ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, mState.getUnpackState(), target, level,
4391 area, format, imageSize,
4392 static_cast<const uint8_t *>(data)));
4393 }
4394
compressedTexSubImage3DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4395 void Context::compressedTexSubImage3DRobust(TextureTarget target,
4396 GLint level,
4397 GLint xoffset,
4398 GLint yoffset,
4399 GLint zoffset,
4400 GLsizei width,
4401 GLsizei height,
4402 GLsizei depth,
4403 GLenum format,
4404 GLsizei imageSize,
4405 GLsizei dataSize,
4406 const GLvoid *data)
4407 {
4408 compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
4409 imageSize, data);
4410 }
4411
generateMipmap(TextureType target)4412 void Context::generateMipmap(TextureType target)
4413 {
4414 Texture *texture = getTextureByType(target);
4415 ANGLE_CONTEXT_TRY(texture->generateMipmap(this));
4416 }
4417
copyTexture(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint internalFormat,GLenum destType,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4418 void Context::copyTexture(TextureID sourceId,
4419 GLint sourceLevel,
4420 TextureTarget destTarget,
4421 TextureID destId,
4422 GLint destLevel,
4423 GLint internalFormat,
4424 GLenum destType,
4425 GLboolean unpackFlipY,
4426 GLboolean unpackPremultiplyAlpha,
4427 GLboolean unpackUnmultiplyAlpha)
4428 {
4429 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4430
4431 gl::Texture *sourceTexture = getTexture(sourceId);
4432 gl::Texture *destTexture = getTexture(destId);
4433 ANGLE_CONTEXT_TRY(
4434 destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
4435 ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
4436 ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
4437 }
4438
copySubTexture(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4439 void Context::copySubTexture(TextureID sourceId,
4440 GLint sourceLevel,
4441 TextureTarget destTarget,
4442 TextureID destId,
4443 GLint destLevel,
4444 GLint xoffset,
4445 GLint yoffset,
4446 GLint x,
4447 GLint y,
4448 GLsizei width,
4449 GLsizei height,
4450 GLboolean unpackFlipY,
4451 GLboolean unpackPremultiplyAlpha,
4452 GLboolean unpackUnmultiplyAlpha)
4453 {
4454 // Zero sized copies are valid but no-ops
4455 if (width == 0 || height == 0)
4456 {
4457 return;
4458 }
4459
4460 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4461
4462 gl::Texture *sourceTexture = getTexture(sourceId);
4463 gl::Texture *destTexture = getTexture(destId);
4464 Offset offset(xoffset, yoffset, 0);
4465 Box box(x, y, 0, width, height, 1);
4466 ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
4467 this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
4468 ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
4469 sourceTexture));
4470 }
4471
copyTexture3D(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint internalFormat,GLenum destType,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4472 void Context::copyTexture3D(TextureID sourceId,
4473 GLint sourceLevel,
4474 TextureTarget destTarget,
4475 TextureID destId,
4476 GLint destLevel,
4477 GLint internalFormat,
4478 GLenum destType,
4479 GLboolean unpackFlipY,
4480 GLboolean unpackPremultiplyAlpha,
4481 GLboolean unpackUnmultiplyAlpha)
4482 {
4483 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4484
4485 Texture *sourceTexture = getTexture(sourceId);
4486 Texture *destTexture = getTexture(destId);
4487 ANGLE_CONTEXT_TRY(
4488 destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
4489 ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
4490 ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
4491 }
4492
copySubTexture3D(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLint z,GLsizei width,GLsizei height,GLsizei depth,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4493 void Context::copySubTexture3D(TextureID sourceId,
4494 GLint sourceLevel,
4495 TextureTarget destTarget,
4496 TextureID destId,
4497 GLint destLevel,
4498 GLint xoffset,
4499 GLint yoffset,
4500 GLint zoffset,
4501 GLint x,
4502 GLint y,
4503 GLint z,
4504 GLsizei width,
4505 GLsizei height,
4506 GLsizei depth,
4507 GLboolean unpackFlipY,
4508 GLboolean unpackPremultiplyAlpha,
4509 GLboolean unpackUnmultiplyAlpha)
4510 {
4511 // Zero sized copies are valid but no-ops
4512 if (width == 0 || height == 0 || depth == 0)
4513 {
4514 return;
4515 }
4516
4517 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4518
4519 Texture *sourceTexture = getTexture(sourceId);
4520 Texture *destTexture = getTexture(destId);
4521 Offset offset(xoffset, yoffset, zoffset);
4522 Box box(x, y, z, width, height, depth);
4523 ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
4524 this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
4525 ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
4526 sourceTexture));
4527 }
4528
compressedCopyTexture(TextureID sourceId,TextureID destId)4529 void Context::compressedCopyTexture(TextureID sourceId, TextureID destId)
4530 {
4531 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4532
4533 gl::Texture *sourceTexture = getTexture(sourceId);
4534 gl::Texture *destTexture = getTexture(destId);
4535 ANGLE_CONTEXT_TRY(destTexture->copyCompressedTexture(this, sourceTexture));
4536 }
4537
getBufferPointerv(BufferBinding target,GLenum pname,void ** params)4538 void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
4539 {
4540 Buffer *buffer = mState.getTargetBuffer(target);
4541 ASSERT(buffer);
4542
4543 QueryBufferPointerv(buffer, pname, params);
4544 }
4545
getBufferPointervRobust(BufferBinding target,GLenum pname,GLsizei bufSize,GLsizei * length,void ** params)4546 void Context::getBufferPointervRobust(BufferBinding target,
4547 GLenum pname,
4548 GLsizei bufSize,
4549 GLsizei *length,
4550 void **params)
4551 {
4552 getBufferPointerv(target, pname, params);
4553 }
4554
mapBuffer(BufferBinding target,GLenum access)4555 void *Context::mapBuffer(BufferBinding target, GLenum access)
4556 {
4557 Buffer *buffer = mState.getTargetBuffer(target);
4558 ASSERT(buffer);
4559
4560 if (buffer->map(this, access) == angle::Result::Stop)
4561 {
4562 return nullptr;
4563 }
4564
4565 return buffer->getMapPointer();
4566 }
4567
unmapBuffer(BufferBinding target)4568 GLboolean Context::unmapBuffer(BufferBinding target)
4569 {
4570 Buffer *buffer = mState.getTargetBuffer(target);
4571 ASSERT(buffer);
4572
4573 GLboolean result;
4574 if (buffer->unmap(this, &result) == angle::Result::Stop)
4575 {
4576 return GL_FALSE;
4577 }
4578
4579 return result;
4580 }
4581
mapBufferRange(BufferBinding target,GLintptr offset,GLsizeiptr length,GLbitfield access)4582 void *Context::mapBufferRange(BufferBinding target,
4583 GLintptr offset,
4584 GLsizeiptr length,
4585 GLbitfield access)
4586 {
4587 Buffer *buffer = mState.getTargetBuffer(target);
4588 ASSERT(buffer);
4589
4590 if (buffer->mapRange(this, offset, length, access) == angle::Result::Stop)
4591 {
4592 return nullptr;
4593 }
4594
4595 return buffer->getMapPointer();
4596 }
4597
flushMappedBufferRange(BufferBinding,GLintptr,GLsizeiptr)4598 void Context::flushMappedBufferRange(BufferBinding /*target*/,
4599 GLintptr /*offset*/,
4600 GLsizeiptr /*length*/)
4601 {
4602 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
4603 }
4604
syncStateForReadPixels()4605 angle::Result Context::syncStateForReadPixels()
4606 {
4607 return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
4608 }
4609
syncStateForTexImage()4610 angle::Result Context::syncStateForTexImage()
4611 {
4612 return syncState(mTexImageDirtyBits, mTexImageDirtyObjects);
4613 }
4614
syncStateForBlit()4615 angle::Result Context::syncStateForBlit()
4616 {
4617 return syncState(mBlitDirtyBits, mBlitDirtyObjects);
4618 }
4619
activeShaderProgram(ProgramPipelineID pipeline,ShaderProgramID program)4620 void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program)
4621 {
4622 Program *shaderProgram = getProgramNoResolveLink(program);
4623 ProgramPipeline *programPipeline =
4624 mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
4625 pipeline);
4626 ASSERT(programPipeline);
4627
4628 programPipeline->activeShaderProgram(shaderProgram);
4629 }
4630
activeTexture(GLenum texture)4631 void Context::activeTexture(GLenum texture)
4632 {
4633 mState.setActiveSampler(texture - GL_TEXTURE0);
4634 }
4635
blendBarrier()4636 void Context::blendBarrier()
4637 {
4638 UNIMPLEMENTED();
4639 }
4640
blendColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)4641 void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
4642 {
4643 mState.setBlendColor(red, green, blue, alpha);
4644 }
4645
blendEquation(GLenum mode)4646 void Context::blendEquation(GLenum mode)
4647 {
4648 mState.setBlendEquation(mode, mode);
4649 }
4650
blendEquationi(GLuint buf,GLenum mode)4651 void Context::blendEquationi(GLuint buf, GLenum mode)
4652 {
4653 mState.setBlendEquationIndexed(mode, mode, buf);
4654 }
4655
blendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)4656 void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
4657 {
4658 mState.setBlendEquation(modeRGB, modeAlpha);
4659 }
4660
blendEquationSeparatei(GLuint buf,GLenum modeRGB,GLenum modeAlpha)4661 void Context::blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
4662 {
4663 mState.setBlendEquationIndexed(modeRGB, modeAlpha, buf);
4664 }
4665
blendFunc(GLenum sfactor,GLenum dfactor)4666 void Context::blendFunc(GLenum sfactor, GLenum dfactor)
4667 {
4668 mState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
4669 }
4670
blendFunci(GLuint buf,GLenum src,GLenum dst)4671 void Context::blendFunci(GLuint buf, GLenum src, GLenum dst)
4672 {
4673 mState.setBlendFactorsIndexed(src, dst, src, dst, buf);
4674
4675 if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
4676 {
4677 mStateCache.onBlendFuncIndexedChange(this);
4678 }
4679 }
4680
blendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)4681 void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
4682 {
4683 mState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
4684 }
4685
blendFuncSeparatei(GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)4686 void Context::blendFuncSeparatei(GLuint buf,
4687 GLenum srcRGB,
4688 GLenum dstRGB,
4689 GLenum srcAlpha,
4690 GLenum dstAlpha)
4691 {
4692 mState.setBlendFactorsIndexed(srcRGB, dstRGB, srcAlpha, dstAlpha, buf);
4693
4694 if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
4695 {
4696 mStateCache.onBlendFuncIndexedChange(this);
4697 }
4698 }
4699
clearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)4700 void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
4701 {
4702 mState.setColorClearValue(red, green, blue, alpha);
4703 }
4704
clearDepthf(GLfloat depth)4705 void Context::clearDepthf(GLfloat depth)
4706 {
4707 mState.setDepthClearValue(clamp01(depth));
4708 }
4709
clearStencil(GLint s)4710 void Context::clearStencil(GLint s)
4711 {
4712 mState.setStencilClearValue(s);
4713 }
4714
colorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)4715 void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
4716 {
4717 mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
4718 ConvertToBool(alpha));
4719 mStateCache.onColorMaskChange(this);
4720 }
4721
colorMaski(GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)4722 void Context::colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
4723 {
4724 mState.setColorMaskIndexed(ConvertToBool(r), ConvertToBool(g), ConvertToBool(b),
4725 ConvertToBool(a), index);
4726 mStateCache.onColorMaskChange(this);
4727 }
4728
cullFace(CullFaceMode mode)4729 void Context::cullFace(CullFaceMode mode)
4730 {
4731 mState.setCullMode(mode);
4732 }
4733
depthFunc(GLenum func)4734 void Context::depthFunc(GLenum func)
4735 {
4736 mState.setDepthFunc(func);
4737 }
4738
depthMask(GLboolean flag)4739 void Context::depthMask(GLboolean flag)
4740 {
4741 mState.setDepthMask(ConvertToBool(flag));
4742 }
4743
depthRangef(GLfloat zNear,GLfloat zFar)4744 void Context::depthRangef(GLfloat zNear, GLfloat zFar)
4745 {
4746 mState.setDepthRange(clamp01(zNear), clamp01(zFar));
4747 }
4748
disable(GLenum cap)4749 void Context::disable(GLenum cap)
4750 {
4751 mState.setEnableFeature(cap, false);
4752 mStateCache.onContextCapChange(this);
4753 }
4754
disablei(GLenum target,GLuint index)4755 void Context::disablei(GLenum target, GLuint index)
4756 {
4757 mState.setEnableFeatureIndexed(target, false, index);
4758 mStateCache.onContextCapChange(this);
4759 }
4760
disableVertexAttribArray(GLuint index)4761 void Context::disableVertexAttribArray(GLuint index)
4762 {
4763 mState.setEnableVertexAttribArray(index, false);
4764 mStateCache.onVertexArrayStateChange(this);
4765 }
4766
enable(GLenum cap)4767 void Context::enable(GLenum cap)
4768 {
4769 mState.setEnableFeature(cap, true);
4770 mStateCache.onContextCapChange(this);
4771 }
4772
enablei(GLenum target,GLuint index)4773 void Context::enablei(GLenum target, GLuint index)
4774 {
4775 mState.setEnableFeatureIndexed(target, true, index);
4776 mStateCache.onContextCapChange(this);
4777 }
4778
enableVertexAttribArray(GLuint index)4779 void Context::enableVertexAttribArray(GLuint index)
4780 {
4781 mState.setEnableVertexAttribArray(index, true);
4782 mStateCache.onVertexArrayStateChange(this);
4783 }
4784
frontFace(GLenum mode)4785 void Context::frontFace(GLenum mode)
4786 {
4787 mState.setFrontFace(mode);
4788 }
4789
hint(GLenum target,GLenum mode)4790 void Context::hint(GLenum target, GLenum mode)
4791 {
4792 switch (target)
4793 {
4794 case GL_GENERATE_MIPMAP_HINT:
4795 mState.setGenerateMipmapHint(mode);
4796 break;
4797
4798 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4799 mState.setFragmentShaderDerivativeHint(mode);
4800 break;
4801
4802 case GL_PERSPECTIVE_CORRECTION_HINT:
4803 case GL_POINT_SMOOTH_HINT:
4804 case GL_LINE_SMOOTH_HINT:
4805 case GL_FOG_HINT:
4806 mState.gles1().setHint(target, mode);
4807 break;
4808 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
4809 mState.setTextureFilteringHint(mode);
4810 break;
4811 default:
4812 UNREACHABLE();
4813 return;
4814 }
4815 }
4816
lineWidth(GLfloat width)4817 void Context::lineWidth(GLfloat width)
4818 {
4819 mState.setLineWidth(width);
4820 }
4821
pixelStorei(GLenum pname,GLint param)4822 void Context::pixelStorei(GLenum pname, GLint param)
4823 {
4824 switch (pname)
4825 {
4826 case GL_UNPACK_ALIGNMENT:
4827 mState.setUnpackAlignment(param);
4828 break;
4829
4830 case GL_PACK_ALIGNMENT:
4831 mState.setPackAlignment(param);
4832 break;
4833
4834 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4835 mState.setPackReverseRowOrder(param != 0);
4836 break;
4837
4838 case GL_UNPACK_ROW_LENGTH:
4839 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
4840 mState.setUnpackRowLength(param);
4841 break;
4842
4843 case GL_UNPACK_IMAGE_HEIGHT:
4844 ASSERT(getClientMajorVersion() >= 3);
4845 mState.setUnpackImageHeight(param);
4846 break;
4847
4848 case GL_UNPACK_SKIP_IMAGES:
4849 ASSERT(getClientMajorVersion() >= 3);
4850 mState.setUnpackSkipImages(param);
4851 break;
4852
4853 case GL_UNPACK_SKIP_ROWS:
4854 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
4855 mState.setUnpackSkipRows(param);
4856 break;
4857
4858 case GL_UNPACK_SKIP_PIXELS:
4859 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
4860 mState.setUnpackSkipPixels(param);
4861 break;
4862
4863 case GL_PACK_ROW_LENGTH:
4864 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
4865 mState.setPackRowLength(param);
4866 break;
4867
4868 case GL_PACK_SKIP_ROWS:
4869 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
4870 mState.setPackSkipRows(param);
4871 break;
4872
4873 case GL_PACK_SKIP_PIXELS:
4874 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
4875 mState.setPackSkipPixels(param);
4876 break;
4877
4878 default:
4879 UNREACHABLE();
4880 return;
4881 }
4882 }
4883
polygonOffset(GLfloat factor,GLfloat units)4884 void Context::polygonOffset(GLfloat factor, GLfloat units)
4885 {
4886 mState.setPolygonOffsetParams(factor, units);
4887 }
4888
sampleCoverage(GLfloat value,GLboolean invert)4889 void Context::sampleCoverage(GLfloat value, GLboolean invert)
4890 {
4891 mState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert));
4892 }
4893
sampleMaski(GLuint maskNumber,GLbitfield mask)4894 void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
4895 {
4896 mState.setSampleMaskParams(maskNumber, mask);
4897 }
4898
scissor(GLint x,GLint y,GLsizei width,GLsizei height)4899 void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4900 {
4901 mState.setScissorParams(x, y, width, height);
4902 }
4903
stencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)4904 void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4905 {
4906 GLint clampedRef = gl::clamp(ref, 0, std::numeric_limits<uint8_t>::max());
4907 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4908 {
4909 mState.setStencilParams(func, clampedRef, mask);
4910 }
4911
4912 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4913 {
4914 mState.setStencilBackParams(func, clampedRef, mask);
4915 }
4916
4917 mStateCache.onStencilStateChange(this);
4918 }
4919
stencilMaskSeparate(GLenum face,GLuint mask)4920 void Context::stencilMaskSeparate(GLenum face, GLuint mask)
4921 {
4922 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4923 {
4924 mState.setStencilWritemask(mask);
4925 }
4926
4927 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4928 {
4929 mState.setStencilBackWritemask(mask);
4930 }
4931
4932 mStateCache.onStencilStateChange(this);
4933 }
4934
stencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)4935 void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4936 {
4937 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4938 {
4939 mState.setStencilOperations(fail, zfail, zpass);
4940 }
4941
4942 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4943 {
4944 mState.setStencilBackOperations(fail, zfail, zpass);
4945 }
4946 }
4947
vertexAttrib1f(GLuint index,GLfloat x)4948 void Context::vertexAttrib1f(GLuint index, GLfloat x)
4949 {
4950 GLfloat vals[4] = {x, 0, 0, 1};
4951 mState.setVertexAttribf(index, vals);
4952 mStateCache.onDefaultVertexAttributeChange(this);
4953 }
4954
vertexAttrib1fv(GLuint index,const GLfloat * values)4955 void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
4956 {
4957 GLfloat vals[4] = {values[0], 0, 0, 1};
4958 mState.setVertexAttribf(index, vals);
4959 mStateCache.onDefaultVertexAttributeChange(this);
4960 }
4961
vertexAttrib2f(GLuint index,GLfloat x,GLfloat y)4962 void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4963 {
4964 GLfloat vals[4] = {x, y, 0, 1};
4965 mState.setVertexAttribf(index, vals);
4966 mStateCache.onDefaultVertexAttributeChange(this);
4967 }
4968
vertexAttrib2fv(GLuint index,const GLfloat * values)4969 void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
4970 {
4971 GLfloat vals[4] = {values[0], values[1], 0, 1};
4972 mState.setVertexAttribf(index, vals);
4973 mStateCache.onDefaultVertexAttributeChange(this);
4974 }
4975
vertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)4976 void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4977 {
4978 GLfloat vals[4] = {x, y, z, 1};
4979 mState.setVertexAttribf(index, vals);
4980 mStateCache.onDefaultVertexAttributeChange(this);
4981 }
4982
vertexAttrib3fv(GLuint index,const GLfloat * values)4983 void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
4984 {
4985 GLfloat vals[4] = {values[0], values[1], values[2], 1};
4986 mState.setVertexAttribf(index, vals);
4987 mStateCache.onDefaultVertexAttributeChange(this);
4988 }
4989
vertexAttrib4f(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)4990 void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4991 {
4992 GLfloat vals[4] = {x, y, z, w};
4993 mState.setVertexAttribf(index, vals);
4994 mStateCache.onDefaultVertexAttributeChange(this);
4995 }
4996
vertexAttrib4fv(GLuint index,const GLfloat * values)4997 void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
4998 {
4999 mState.setVertexAttribf(index, values);
5000 mStateCache.onDefaultVertexAttributeChange(this);
5001 }
5002
vertexAttribPointer(GLuint index,GLint size,VertexAttribType type,GLboolean normalized,GLsizei stride,const void * ptr)5003 void Context::vertexAttribPointer(GLuint index,
5004 GLint size,
5005 VertexAttribType type,
5006 GLboolean normalized,
5007 GLsizei stride,
5008 const void *ptr)
5009 {
5010 mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
5011 type, ConvertToBool(normalized), stride, ptr);
5012 mStateCache.onVertexArrayStateChange(this);
5013 }
5014
vertexAttribFormat(GLuint attribIndex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeOffset)5015 void Context::vertexAttribFormat(GLuint attribIndex,
5016 GLint size,
5017 VertexAttribType type,
5018 GLboolean normalized,
5019 GLuint relativeOffset)
5020 {
5021 mState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false,
5022 relativeOffset);
5023 mStateCache.onVertexArrayFormatChange(this);
5024 }
5025
vertexAttribIFormat(GLuint attribIndex,GLint size,VertexAttribType type,GLuint relativeOffset)5026 void Context::vertexAttribIFormat(GLuint attribIndex,
5027 GLint size,
5028 VertexAttribType type,
5029 GLuint relativeOffset)
5030 {
5031 mState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
5032 mStateCache.onVertexArrayFormatChange(this);
5033 }
5034
vertexAttribBinding(GLuint attribIndex,GLuint bindingIndex)5035 void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
5036 {
5037 mState.setVertexAttribBinding(this, attribIndex, bindingIndex);
5038 mStateCache.onVertexArrayStateChange(this);
5039 }
5040
vertexBindingDivisor(GLuint bindingIndex,GLuint divisor)5041 void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
5042 {
5043 mState.setVertexBindingDivisor(bindingIndex, divisor);
5044 mStateCache.onVertexArrayFormatChange(this);
5045 }
5046
viewport(GLint x,GLint y,GLsizei width,GLsizei height)5047 void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
5048 {
5049 mState.setViewportParams(x, y, width, height);
5050 }
5051
vertexAttribIPointer(GLuint index,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)5052 void Context::vertexAttribIPointer(GLuint index,
5053 GLint size,
5054 VertexAttribType type,
5055 GLsizei stride,
5056 const void *pointer)
5057 {
5058 mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
5059 type, stride, pointer);
5060 mStateCache.onVertexArrayStateChange(this);
5061 }
5062
vertexAttribI4i(GLuint index,GLint x,GLint y,GLint z,GLint w)5063 void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
5064 {
5065 GLint vals[4] = {x, y, z, w};
5066 mState.setVertexAttribi(index, vals);
5067 mStateCache.onDefaultVertexAttributeChange(this);
5068 }
5069
vertexAttribI4ui(GLuint index,GLuint x,GLuint y,GLuint z,GLuint w)5070 void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
5071 {
5072 GLuint vals[4] = {x, y, z, w};
5073 mState.setVertexAttribu(index, vals);
5074 mStateCache.onDefaultVertexAttributeChange(this);
5075 }
5076
vertexAttribI4iv(GLuint index,const GLint * v)5077 void Context::vertexAttribI4iv(GLuint index, const GLint *v)
5078 {
5079 mState.setVertexAttribi(index, v);
5080 mStateCache.onDefaultVertexAttributeChange(this);
5081 }
5082
vertexAttribI4uiv(GLuint index,const GLuint * v)5083 void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
5084 {
5085 mState.setVertexAttribu(index, v);
5086 mStateCache.onDefaultVertexAttributeChange(this);
5087 }
5088
getVertexAttribivImpl(GLuint index,GLenum pname,GLint * params) const5089 void Context::getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const
5090 {
5091 const VertexAttribCurrentValueData ¤tValues =
5092 getState().getVertexAttribCurrentValue(index);
5093 const VertexArray *vao = getState().getVertexArray();
5094 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5095 currentValues, pname, params);
5096 }
5097
getVertexAttribiv(GLuint index,GLenum pname,GLint * params)5098 void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
5099 {
5100 return getVertexAttribivImpl(index, pname, params);
5101 }
5102
getVertexAttribivRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)5103 void Context::getVertexAttribivRobust(GLuint index,
5104 GLenum pname,
5105 GLsizei bufSize,
5106 GLsizei *length,
5107 GLint *params)
5108 {
5109 getVertexAttribiv(index, pname, params);
5110 }
5111
getVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)5112 void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
5113 {
5114 const VertexAttribCurrentValueData ¤tValues =
5115 getState().getVertexAttribCurrentValue(index);
5116 const VertexArray *vao = getState().getVertexArray();
5117 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5118 currentValues, pname, params);
5119 }
5120
getVertexAttribfvRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)5121 void Context::getVertexAttribfvRobust(GLuint index,
5122 GLenum pname,
5123 GLsizei bufSize,
5124 GLsizei *length,
5125 GLfloat *params)
5126 {
5127 getVertexAttribfv(index, pname, params);
5128 }
5129
getVertexAttribIiv(GLuint index,GLenum pname,GLint * params)5130 void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
5131 {
5132 const VertexAttribCurrentValueData ¤tValues =
5133 getState().getVertexAttribCurrentValue(index);
5134 const VertexArray *vao = getState().getVertexArray();
5135 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5136 currentValues, pname, params);
5137 }
5138
getVertexAttribIivRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)5139 void Context::getVertexAttribIivRobust(GLuint index,
5140 GLenum pname,
5141 GLsizei bufSize,
5142 GLsizei *length,
5143 GLint *params)
5144 {
5145 getVertexAttribIiv(index, pname, params);
5146 }
5147
getVertexAttribIuiv(GLuint index,GLenum pname,GLuint * params)5148 void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
5149 {
5150 const VertexAttribCurrentValueData ¤tValues =
5151 getState().getVertexAttribCurrentValue(index);
5152 const VertexArray *vao = getState().getVertexArray();
5153 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5154 currentValues, pname, params);
5155 }
5156
getVertexAttribIuivRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)5157 void Context::getVertexAttribIuivRobust(GLuint index,
5158 GLenum pname,
5159 GLsizei bufSize,
5160 GLsizei *length,
5161 GLuint *params)
5162 {
5163 getVertexAttribIuiv(index, pname, params);
5164 }
5165
getVertexAttribPointerv(GLuint index,GLenum pname,void ** pointer)5166 void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
5167 {
5168 const VertexAttribute &attrib = getState().getVertexArray()->getVertexAttribute(index);
5169 QueryVertexAttribPointerv(attrib, pname, pointer);
5170 }
5171
getVertexAttribPointervRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,void ** pointer)5172 void Context::getVertexAttribPointervRobust(GLuint index,
5173 GLenum pname,
5174 GLsizei bufSize,
5175 GLsizei *length,
5176 void **pointer)
5177 {
5178 getVertexAttribPointerv(index, pname, pointer);
5179 }
5180
debugMessageControl(GLenum source,GLenum type,GLenum severity,GLsizei count,const GLuint * ids,GLboolean enabled)5181 void Context::debugMessageControl(GLenum source,
5182 GLenum type,
5183 GLenum severity,
5184 GLsizei count,
5185 const GLuint *ids,
5186 GLboolean enabled)
5187 {
5188 std::vector<GLuint> idVector(ids, ids + count);
5189 mState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
5190 ConvertToBool(enabled));
5191 }
5192
debugMessageInsert(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * buf)5193 void Context::debugMessageInsert(GLenum source,
5194 GLenum type,
5195 GLuint id,
5196 GLenum severity,
5197 GLsizei length,
5198 const GLchar *buf)
5199 {
5200 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
5201 mState.getDebug().insertMessage(source, type, id, severity, std::move(msg), gl::LOG_INFO);
5202 }
5203
debugMessageCallback(GLDEBUGPROCKHR callback,const void * userParam)5204 void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
5205 {
5206 mState.getDebug().setCallback(callback, userParam);
5207 }
5208
getDebugMessageLog(GLuint count,GLsizei bufSize,GLenum * sources,GLenum * types,GLuint * ids,GLenum * severities,GLsizei * lengths,GLchar * messageLog)5209 GLuint Context::getDebugMessageLog(GLuint count,
5210 GLsizei bufSize,
5211 GLenum *sources,
5212 GLenum *types,
5213 GLuint *ids,
5214 GLenum *severities,
5215 GLsizei *lengths,
5216 GLchar *messageLog)
5217 {
5218 return static_cast<GLuint>(mState.getDebug().getMessages(count, bufSize, sources, types, ids,
5219 severities, lengths, messageLog));
5220 }
5221
pushDebugGroup(GLenum source,GLuint id,GLsizei length,const GLchar * message)5222 void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
5223 {
5224 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
5225 ANGLE_CONTEXT_TRY(mImplementation->pushDebugGroup(this, source, id, msg));
5226 mState.getDebug().pushGroup(source, id, std::move(msg));
5227 }
5228
popDebugGroup()5229 void Context::popDebugGroup()
5230 {
5231 mState.getDebug().popGroup();
5232 ANGLE_CONTEXT_TRY(mImplementation->popDebugGroup(this));
5233 }
5234
primitiveBoundingBox(GLfloat minX,GLfloat minY,GLfloat minZ,GLfloat minW,GLfloat maxX,GLfloat maxY,GLfloat maxZ,GLfloat maxW)5235 void Context::primitiveBoundingBox(GLfloat minX,
5236 GLfloat minY,
5237 GLfloat minZ,
5238 GLfloat minW,
5239 GLfloat maxX,
5240 GLfloat maxY,
5241 GLfloat maxZ,
5242 GLfloat maxW)
5243 {
5244 UNIMPLEMENTED();
5245 }
5246
bufferData(BufferBinding target,GLsizeiptr size,const void * data,BufferUsage usage)5247 void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
5248 {
5249 Buffer *buffer = mState.getTargetBuffer(target);
5250 ASSERT(buffer);
5251 ANGLE_CONTEXT_TRY(buffer->bufferData(this, target, data, size, usage));
5252 }
5253
bufferSubData(BufferBinding target,GLintptr offset,GLsizeiptr size,const void * data)5254 void Context::bufferSubData(BufferBinding target,
5255 GLintptr offset,
5256 GLsizeiptr size,
5257 const void *data)
5258 {
5259 if (data == nullptr || size == 0)
5260 {
5261 return;
5262 }
5263
5264 Buffer *buffer = mState.getTargetBuffer(target);
5265 ASSERT(buffer);
5266 ANGLE_CONTEXT_TRY(buffer->bufferSubData(this, target, data, size, offset));
5267 }
5268
attachShader(ShaderProgramID program,ShaderProgramID shader)5269 void Context::attachShader(ShaderProgramID program, ShaderProgramID shader)
5270 {
5271 Program *programObject = mState.mShaderProgramManager->getProgram(program);
5272 Shader *shaderObject = mState.mShaderProgramManager->getShader(shader);
5273 ASSERT(programObject && shaderObject);
5274 programObject->attachShader(this, shaderObject);
5275 }
5276
copyBufferSubData(BufferBinding readTarget,BufferBinding writeTarget,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)5277 void Context::copyBufferSubData(BufferBinding readTarget,
5278 BufferBinding writeTarget,
5279 GLintptr readOffset,
5280 GLintptr writeOffset,
5281 GLsizeiptr size)
5282 {
5283 // if size is zero, the copy is a successful no-op
5284 if (size == 0)
5285 {
5286 return;
5287 }
5288
5289 // TODO(jmadill): cache these.
5290 Buffer *readBuffer = mState.getTargetBuffer(readTarget);
5291 Buffer *writeBuffer = mState.getTargetBuffer(writeTarget);
5292
5293 ANGLE_CONTEXT_TRY(
5294 writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
5295 }
5296
bindAttribLocation(ShaderProgramID program,GLuint index,const GLchar * name)5297 void Context::bindAttribLocation(ShaderProgramID program, GLuint index, const GLchar *name)
5298 {
5299 // Ideally we could share the program query with the validation layer if possible.
5300 Program *programObject = getProgramResolveLink(program);
5301 ASSERT(programObject);
5302 programObject->bindAttributeLocation(index, name);
5303 }
5304
bindBufferBase(BufferBinding target,GLuint index,BufferID buffer)5305 void Context::bindBufferBase(BufferBinding target, GLuint index, BufferID buffer)
5306 {
5307 bindBufferRange(target, index, buffer, 0, 0);
5308 }
5309
bindBufferRange(BufferBinding target,GLuint index,BufferID buffer,GLintptr offset,GLsizeiptr size)5310 void Context::bindBufferRange(BufferBinding target,
5311 GLuint index,
5312 BufferID buffer,
5313 GLintptr offset,
5314 GLsizeiptr size)
5315 {
5316 Buffer *object = mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
5317 ANGLE_CONTEXT_TRY(mState.setIndexedBufferBinding(this, target, index, object, offset, size));
5318 if (target == BufferBinding::Uniform)
5319 {
5320 mUniformBufferObserverBindings[index].bind(object);
5321 mStateCache.onUniformBufferStateChange(this);
5322 }
5323 else
5324 {
5325 mStateCache.onBufferBindingChange(this);
5326 }
5327 }
5328
bindFramebuffer(GLenum target,FramebufferID framebuffer)5329 void Context::bindFramebuffer(GLenum target, FramebufferID framebuffer)
5330 {
5331 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
5332 {
5333 bindReadFramebuffer(framebuffer);
5334 }
5335
5336 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
5337 {
5338 bindDrawFramebuffer(framebuffer);
5339 }
5340 }
5341
bindRenderbuffer(GLenum target,RenderbufferID renderbuffer)5342 void Context::bindRenderbuffer(GLenum target, RenderbufferID renderbuffer)
5343 {
5344 ASSERT(target == GL_RENDERBUFFER);
5345 Renderbuffer *object = mState.mRenderbufferManager->checkRenderbufferAllocation(
5346 mImplementation.get(), renderbuffer);
5347 mState.setRenderbufferBinding(this, object);
5348 }
5349
texStorage2DMultisample(TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)5350 void Context::texStorage2DMultisample(TextureType target,
5351 GLsizei samples,
5352 GLenum internalformat,
5353 GLsizei width,
5354 GLsizei height,
5355 GLboolean fixedsamplelocations)
5356 {
5357 Extents size(width, height, 1);
5358 Texture *texture = getTextureByType(target);
5359 ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
5360 ConvertToBool(fixedsamplelocations)));
5361 }
5362
texStorage3DMultisample(TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)5363 void Context::texStorage3DMultisample(TextureType target,
5364 GLsizei samples,
5365 GLenum internalformat,
5366 GLsizei width,
5367 GLsizei height,
5368 GLsizei depth,
5369 GLboolean fixedsamplelocations)
5370 {
5371 Extents size(width, height, depth);
5372 Texture *texture = getTextureByType(target);
5373 ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
5374 ConvertToBool(fixedsamplelocations)));
5375 }
5376
texImage2DExternal(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type)5377 void Context::texImage2DExternal(TextureTarget target,
5378 GLint level,
5379 GLint internalformat,
5380 GLsizei width,
5381 GLsizei height,
5382 GLint border,
5383 GLenum format,
5384 GLenum type)
5385 {
5386 Extents size(width, height, 1);
5387 Texture *texture = getTextureByTarget(target);
5388 ANGLE_CONTEXT_TRY(
5389 texture->setImageExternal(this, target, level, internalformat, size, format, type));
5390 }
5391
invalidateTexture(TextureType target)5392 void Context::invalidateTexture(TextureType target)
5393 {
5394 mImplementation->invalidateTexture(target);
5395 mState.invalidateTexture(target);
5396 }
5397
getMultisamplefv(GLenum pname,GLuint index,GLfloat * val)5398 void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
5399 {
5400 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
5401 // the sample position should be queried by DRAW_FRAMEBUFFER.
5402 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
5403 const Framebuffer *framebuffer = mState.getDrawFramebuffer();
5404
5405 switch (pname)
5406 {
5407 case GL_SAMPLE_POSITION:
5408 ANGLE_CONTEXT_TRY(framebuffer->getSamplePosition(this, index, val));
5409 break;
5410 default:
5411 UNREACHABLE();
5412 }
5413 }
5414
getMultisamplefvRobust(GLenum pname,GLuint index,GLsizei bufSize,GLsizei * length,GLfloat * val)5415 void Context::getMultisamplefvRobust(GLenum pname,
5416 GLuint index,
5417 GLsizei bufSize,
5418 GLsizei *length,
5419 GLfloat *val)
5420 {
5421 UNIMPLEMENTED();
5422 }
5423
renderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)5424 void Context::renderbufferStorage(GLenum target,
5425 GLenum internalformat,
5426 GLsizei width,
5427 GLsizei height)
5428 {
5429 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
5430 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
5431
5432 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
5433 ANGLE_CONTEXT_TRY(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
5434 }
5435
renderbufferStorageMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)5436 void Context::renderbufferStorageMultisample(GLenum target,
5437 GLsizei samples,
5438 GLenum internalformat,
5439 GLsizei width,
5440 GLsizei height)
5441 {
5442 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
5443 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
5444
5445 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
5446 ANGLE_CONTEXT_TRY(
5447 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
5448 }
5449
framebufferTexture2DMultisample(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLsizei samples)5450 void Context::framebufferTexture2DMultisample(GLenum target,
5451 GLenum attachment,
5452 GLenum textarget,
5453 GLuint texture,
5454 GLint level,
5455 GLsizei samples)
5456 {
5457 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5458 ASSERT(framebuffer);
5459
5460 if (texture != 0)
5461 {
5462 TextureTarget textargetPacked = FromGLenum<TextureTarget>(textarget);
5463 TextureID texturePacked = FromGL<TextureID>(texture);
5464 Texture *textureObj = getTexture(texturePacked);
5465 ImageIndex index = ImageIndex::MakeFromTarget(textargetPacked, level, 1);
5466 framebuffer->setAttachmentMultisample(this, GL_TEXTURE, attachment, index, textureObj,
5467 samples);
5468 }
5469 else
5470 {
5471 framebuffer->resetAttachment(this, attachment);
5472 }
5473
5474 mState.setObjectDirty(target);
5475 }
5476
getSynciv(GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)5477 void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
5478 {
5479 const Sync *syncObject = nullptr;
5480 if (!isContextLost())
5481 {
5482 syncObject = getSync(sync);
5483 }
5484 ANGLE_CONTEXT_TRY(QuerySynciv(this, syncObject, pname, bufSize, length, values));
5485 }
5486
getFramebufferParameteriv(GLenum target,GLenum pname,GLint * params)5487 void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
5488 {
5489 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5490 QueryFramebufferParameteriv(framebuffer, pname, params);
5491 }
5492
getFramebufferParameterivRobust(GLenum target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)5493 void Context::getFramebufferParameterivRobust(GLenum target,
5494 GLenum pname,
5495 GLsizei bufSize,
5496 GLsizei *length,
5497 GLint *params)
5498 {
5499 UNIMPLEMENTED();
5500 }
5501
framebufferParameteri(GLenum target,GLenum pname,GLint param)5502 void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param)
5503 {
5504 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5505 SetFramebufferParameteri(this, framebuffer, pname, param);
5506 }
5507
getScratchBuffer(size_t requstedSizeBytes,angle::MemoryBuffer ** scratchBufferOut) const5508 bool Context::getScratchBuffer(size_t requstedSizeBytes,
5509 angle::MemoryBuffer **scratchBufferOut) const
5510 {
5511 if (!mScratchBuffer.valid())
5512 {
5513 mScratchBuffer = mDisplay->requestScratchBuffer();
5514 }
5515
5516 ASSERT(mScratchBuffer.valid());
5517 return mScratchBuffer.value().get(requstedSizeBytes, scratchBufferOut);
5518 }
5519
getScratchBuffer() const5520 angle::ScratchBuffer *Context::getScratchBuffer() const
5521 {
5522 if (!mScratchBuffer.valid())
5523 {
5524 mScratchBuffer = mDisplay->requestScratchBuffer();
5525 }
5526
5527 ASSERT(mScratchBuffer.valid());
5528 return &mScratchBuffer.value();
5529 }
5530
getZeroFilledBuffer(size_t requstedSizeBytes,angle::MemoryBuffer ** zeroBufferOut) const5531 bool Context::getZeroFilledBuffer(size_t requstedSizeBytes,
5532 angle::MemoryBuffer **zeroBufferOut) const
5533 {
5534 if (!mZeroFilledBuffer.valid())
5535 {
5536 mZeroFilledBuffer = mDisplay->requestZeroFilledBuffer();
5537 }
5538
5539 ASSERT(mZeroFilledBuffer.valid());
5540 return mZeroFilledBuffer.value().getInitialized(requstedSizeBytes, zeroBufferOut, 0);
5541 }
5542
dispatchCompute(GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)5543 void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
5544 {
5545 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
5546 {
5547 return;
5548 }
5549
5550 ANGLE_CONTEXT_TRY(prepareForDispatch());
5551
5552 angle::Result result =
5553 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
5554
5555 // We always assume PPOs are used for draws, until they aren't. If we just executed a dispatch
5556 // with a PPO, we need to convert it back to a "draw"-type.
5557 convertPpoToComputeOrDraw(false);
5558
5559 if (ANGLE_UNLIKELY(IsError(result)))
5560 {
5561 return;
5562 }
5563
5564 MarkShaderStorageBufferUsage(this);
5565 }
5566
convertPpoToComputeOrDraw(bool isCompute)5567 void Context::convertPpoToComputeOrDraw(bool isCompute)
5568 {
5569 Program *program = mState.getProgram();
5570 ProgramPipeline *pipeline = mState.getProgramPipeline();
5571 if (!program && pipeline)
5572 {
5573 pipeline->getExecutable().setIsCompute(isCompute);
5574 pipeline->setDirtyBit(ProgramPipeline::DirtyBitType::DIRTY_BIT_DRAW_DISPATCH_CHANGE);
5575 mState.mDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
5576 mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_PROGRAM_EXECUTABLE);
5577 }
5578 }
5579
dispatchComputeIndirect(GLintptr indirect)5580 void Context::dispatchComputeIndirect(GLintptr indirect)
5581 {
5582 ANGLE_CONTEXT_TRY(prepareForDispatch());
5583 ANGLE_CONTEXT_TRY(mImplementation->dispatchComputeIndirect(this, indirect));
5584
5585 MarkShaderStorageBufferUsage(this);
5586 }
5587
texStorage2D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height)5588 void Context::texStorage2D(TextureType target,
5589 GLsizei levels,
5590 GLenum internalFormat,
5591 GLsizei width,
5592 GLsizei height)
5593 {
5594 Extents size(width, height, 1);
5595 Texture *texture = getTextureByType(target);
5596 ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
5597 }
5598
texStorage3D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth)5599 void Context::texStorage3D(TextureType target,
5600 GLsizei levels,
5601 GLenum internalFormat,
5602 GLsizei width,
5603 GLsizei height,
5604 GLsizei depth)
5605 {
5606 Extents size(width, height, depth);
5607 Texture *texture = getTextureByType(target);
5608 ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
5609 }
5610
memoryBarrier(GLbitfield barriers)5611 void Context::memoryBarrier(GLbitfield barriers)
5612 {
5613 ANGLE_CONTEXT_TRY(mImplementation->memoryBarrier(this, barriers));
5614 }
5615
memoryBarrierByRegion(GLbitfield barriers)5616 void Context::memoryBarrierByRegion(GLbitfield barriers)
5617 {
5618 ANGLE_CONTEXT_TRY(mImplementation->memoryBarrierByRegion(this, barriers));
5619 }
5620
multiDrawArrays(PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)5621 void Context::multiDrawArrays(PrimitiveMode mode,
5622 const GLint *firsts,
5623 const GLsizei *counts,
5624 GLsizei drawcount)
5625 {
5626 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5627 Program *programObject = mState.getLinkedProgram(this);
5628 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5629 if (hasDrawID)
5630 {
5631 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5632 {
5633 if (noopDraw(mode, counts[drawID]))
5634 {
5635 continue;
5636 }
5637 programObject->setDrawIDUniform(drawID);
5638 ANGLE_CONTEXT_TRY(
5639 mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
5640 MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
5641 MarkShaderStorageBufferUsage(this);
5642 }
5643 }
5644 else
5645 {
5646 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5647 {
5648 if (noopDraw(mode, counts[drawID]))
5649 {
5650 continue;
5651 }
5652 ANGLE_CONTEXT_TRY(
5653 mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
5654 MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
5655 MarkShaderStorageBufferUsage(this);
5656 }
5657 }
5658 }
5659
multiDrawArraysInstanced(PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)5660 void Context::multiDrawArraysInstanced(PrimitiveMode mode,
5661 const GLint *firsts,
5662 const GLsizei *counts,
5663 const GLsizei *instanceCounts,
5664 GLsizei drawcount)
5665 {
5666 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5667 Program *programObject = mState.getLinkedProgram(this);
5668 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5669 if (hasDrawID)
5670 {
5671 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5672 {
5673 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5674 {
5675 continue;
5676 }
5677 programObject->setDrawIDUniform(drawID);
5678 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
5679 this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
5680 MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
5681 MarkShaderStorageBufferUsage(this);
5682 }
5683 }
5684 else
5685 {
5686 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5687 {
5688 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5689 {
5690 continue;
5691 }
5692 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
5693 this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
5694 MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
5695 MarkShaderStorageBufferUsage(this);
5696 }
5697 }
5698 }
5699
multiDrawElements(PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)5700 void Context::multiDrawElements(PrimitiveMode mode,
5701 const GLsizei *counts,
5702 DrawElementsType type,
5703 const GLvoid *const *indices,
5704 GLsizei drawcount)
5705 {
5706 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5707 Program *programObject = mState.getLinkedProgram(this);
5708 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5709 if (hasDrawID)
5710 {
5711 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5712 {
5713 if (noopDraw(mode, counts[drawID]))
5714 {
5715 continue;
5716 }
5717 programObject->setDrawIDUniform(drawID);
5718 ANGLE_CONTEXT_TRY(
5719 mImplementation->drawElements(this, mode, counts[drawID], type, indices[drawID]));
5720 MarkShaderStorageBufferUsage(this);
5721 }
5722 }
5723 else
5724 {
5725 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5726 {
5727 if (noopDraw(mode, counts[drawID]))
5728 {
5729 continue;
5730 }
5731 ANGLE_CONTEXT_TRY(
5732 mImplementation->drawElements(this, mode, counts[drawID], type, indices[drawID]));
5733 MarkShaderStorageBufferUsage(this);
5734 }
5735 }
5736 }
5737
multiDrawElementsInstanced(PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)5738 void Context::multiDrawElementsInstanced(PrimitiveMode mode,
5739 const GLsizei *counts,
5740 DrawElementsType type,
5741 const GLvoid *const *indices,
5742 const GLsizei *instanceCounts,
5743 GLsizei drawcount)
5744 {
5745 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5746 Program *programObject = mState.getLinkedProgram(this);
5747 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5748 if (hasDrawID)
5749 {
5750 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5751 {
5752 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5753 {
5754 continue;
5755 }
5756 programObject->setDrawIDUniform(drawID);
5757 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstanced(
5758 this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID]));
5759 MarkShaderStorageBufferUsage(this);
5760 }
5761 }
5762 else
5763 {
5764 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5765 {
5766 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5767 {
5768 continue;
5769 }
5770 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstanced(
5771 this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID]));
5772 MarkShaderStorageBufferUsage(this);
5773 }
5774 }
5775 }
5776
5777 namespace
5778 {
5779
5780 // RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
5781 class ResetBaseVertexBaseInstance : angle::NonCopyable
5782 {
5783 public:
ResetBaseVertexBaseInstance(Program * programObject,bool resetBaseVertex,bool resetBaseInstance)5784 ResetBaseVertexBaseInstance(Program *programObject,
5785 bool resetBaseVertex,
5786 bool resetBaseInstance)
5787 : mProgramObject(programObject),
5788 mResetBaseVertex(resetBaseVertex),
5789 mResetBaseInstance(resetBaseInstance)
5790 {}
5791
~ResetBaseVertexBaseInstance()5792 ~ResetBaseVertexBaseInstance()
5793 {
5794 if (mProgramObject)
5795 {
5796 // Reset emulated uniforms to zero to avoid affecting other draw calls
5797 if (mResetBaseVertex)
5798 {
5799 mProgramObject->setBaseVertexUniform(0);
5800 }
5801
5802 if (mResetBaseInstance)
5803 {
5804 mProgramObject->setBaseInstanceUniform(0);
5805 }
5806 }
5807 }
5808
5809 private:
5810 Program *mProgramObject;
5811 bool mResetBaseVertex;
5812 bool mResetBaseInstance;
5813 };
5814
5815 } // anonymous namespace
5816
drawArraysInstancedBaseInstance(PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)5817 void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode,
5818 GLint first,
5819 GLsizei count,
5820 GLsizei instanceCount,
5821 GLuint baseInstance)
5822 {
5823 if (noopDraw(mode, count))
5824 {
5825 return;
5826 }
5827
5828 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5829 Program *programObject = mState.getLinkedProgram(this);
5830
5831 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5832 if (hasBaseInstance)
5833 {
5834 programObject->setBaseInstanceUniform(baseInstance);
5835 }
5836
5837 ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
5838
5839 // The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on
5840 // the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan.
5841
5842 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance(
5843 this, mode, first, count, instanceCount, baseInstance));
5844 MarkTransformFeedbackBufferUsage(this, count, 1);
5845 }
5846
drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,GLsizei count,DrawElementsType type,const GLvoid * indices,GLsizei instanceCounts,GLint baseVertex,GLuint baseInstance)5847 void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
5848 GLsizei count,
5849 DrawElementsType type,
5850 const GLvoid *indices,
5851 GLsizei instanceCounts,
5852 GLint baseVertex,
5853 GLuint baseInstance)
5854 {
5855 if (noopDraw(mode, count))
5856 {
5857 return;
5858 }
5859
5860 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5861 Program *programObject = mState.getLinkedProgram(this);
5862
5863 const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
5864 if (hasBaseVertex)
5865 {
5866 programObject->setBaseVertexUniform(baseVertex);
5867 }
5868
5869 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5870 if (hasBaseInstance)
5871 {
5872 programObject->setBaseInstanceUniform(baseInstance);
5873 }
5874
5875 ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
5876
5877 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance(
5878 this, mode, count, type, indices, instanceCounts, baseVertex, baseInstance));
5879 }
5880
5881 #define SET_DRAW_ID_UNIFORM_0(drawID) \
5882 {}
5883 #define SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID);
5884 #define SET_DRAW_ID_UNIFORM(cond) SET_DRAW_ID_UNIFORM_##cond
5885
5886 #define SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
5887 {}
5888 #define SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex);
5889 #define SET_BASE_VERTEX_UNIFORM(cond) SET_BASE_VERTEX_UNIFORM_##cond
5890
5891 #define SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
5892 {}
5893 #define SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
5894 programObject->setBaseInstanceUniform(baseInstance);
5895 #define SET_BASE_INSTANCE_UNIFORM(cond) SET_BASE_INSTANCE_UNIFORM_##cond
5896
5897 #define MULTI_DRAW_ARRAYS_BLOCK(hasDrawID, hasBaseInstance) \
5898 for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
5899 { \
5900 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])) \
5901 { \
5902 continue; \
5903 } \
5904 SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
5905 SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
5906 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance( \
5907 this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID], \
5908 baseInstances[drawID])); \
5909 MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]); \
5910 }
5911
5912 #define MULTI_DRAW_ELEMENTS_BLOCK(hasDrawID, hasBaseVertex, hasBaseInstance) \
5913 for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
5914 { \
5915 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])) \
5916 { \
5917 continue; \
5918 } \
5919 SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
5920 SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
5921 SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
5922 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance( \
5923 this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \
5924 baseVertices[drawID], baseInstances[drawID])); \
5925 }
5926
multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)5927 void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,
5928 const GLint *firsts,
5929 const GLsizei *counts,
5930 const GLsizei *instanceCounts,
5931 const GLuint *baseInstances,
5932 GLsizei drawcount)
5933 {
5934 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5935 Program *programObject = mState.getLinkedProgram(this);
5936 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5937 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5938
5939 ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
5940
5941 if (hasDrawID && hasBaseInstance)
5942 {
5943 MULTI_DRAW_ARRAYS_BLOCK(1, 1)
5944 }
5945 else if (hasDrawID)
5946 {
5947 MULTI_DRAW_ARRAYS_BLOCK(1, 0)
5948 }
5949 else if (hasBaseInstance)
5950 {
5951 MULTI_DRAW_ARRAYS_BLOCK(0, 1)
5952 }
5953 else
5954 {
5955 MULTI_DRAW_ARRAYS_BLOCK(0, 0)
5956 }
5957 }
5958
multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,const GLint * baseVertices,const GLuint * baseInstances,GLsizei drawcount)5959 void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
5960 const GLsizei *counts,
5961 DrawElementsType type,
5962 const GLvoid *const *indices,
5963 const GLsizei *instanceCounts,
5964 const GLint *baseVertices,
5965 const GLuint *baseInstances,
5966 GLsizei drawcount)
5967 {
5968 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5969 Program *programObject = mState.getLinkedProgram(this);
5970 const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
5971 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5972 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5973
5974 ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
5975
5976 if (hasDrawID)
5977 {
5978 if (hasBaseVertex)
5979 {
5980 if (hasBaseInstance)
5981 {
5982 MULTI_DRAW_ELEMENTS_BLOCK(1, 1, 1)
5983 }
5984 else
5985 {
5986 MULTI_DRAW_ELEMENTS_BLOCK(1, 1, 0)
5987 }
5988 }
5989 else
5990 {
5991 if (hasBaseInstance)
5992 {
5993 MULTI_DRAW_ELEMENTS_BLOCK(1, 0, 1)
5994 }
5995 else
5996 {
5997 MULTI_DRAW_ELEMENTS_BLOCK(1, 0, 0)
5998 }
5999 }
6000 }
6001 else
6002 {
6003 if (hasBaseVertex)
6004 {
6005 if (hasBaseInstance)
6006 {
6007 MULTI_DRAW_ELEMENTS_BLOCK(0, 1, 1)
6008 }
6009 else
6010 {
6011 MULTI_DRAW_ELEMENTS_BLOCK(0, 1, 0)
6012 }
6013 }
6014 else
6015 {
6016 if (hasBaseInstance)
6017 {
6018 MULTI_DRAW_ELEMENTS_BLOCK(0, 0, 1)
6019 }
6020 else
6021 {
6022 MULTI_DRAW_ELEMENTS_BLOCK(0, 0, 0)
6023 }
6024 }
6025 }
6026 }
6027
provokingVertex(ProvokingVertexConvention provokeMode)6028 void Context::provokingVertex(ProvokingVertexConvention provokeMode)
6029 {
6030 mState.setProvokingVertex(provokeMode);
6031 }
6032
checkFramebufferStatus(GLenum target)6033 GLenum Context::checkFramebufferStatus(GLenum target)
6034 {
6035 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
6036 ASSERT(framebuffer);
6037 return framebuffer->checkStatus(this);
6038 }
6039
compileShader(ShaderProgramID shader)6040 void Context::compileShader(ShaderProgramID shader)
6041 {
6042 Shader *shaderObject = GetValidShader(this, shader);
6043 if (!shaderObject)
6044 {
6045 return;
6046 }
6047 shaderObject->compile(this);
6048 }
6049
deleteBuffers(GLsizei n,const BufferID * buffers)6050 void Context::deleteBuffers(GLsizei n, const BufferID *buffers)
6051 {
6052 for (int i = 0; i < n; i++)
6053 {
6054 deleteBuffer(buffers[i]);
6055 }
6056 }
6057
deleteFramebuffers(GLsizei n,const FramebufferID * framebuffers)6058 void Context::deleteFramebuffers(GLsizei n, const FramebufferID *framebuffers)
6059 {
6060 for (int i = 0; i < n; i++)
6061 {
6062 if (framebuffers[i].value != 0)
6063 {
6064 deleteFramebuffer(framebuffers[i]);
6065 }
6066 }
6067 }
6068
deleteRenderbuffers(GLsizei n,const RenderbufferID * renderbuffers)6069 void Context::deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffers)
6070 {
6071 for (int i = 0; i < n; i++)
6072 {
6073 deleteRenderbuffer(renderbuffers[i]);
6074 }
6075 }
6076
deleteTextures(GLsizei n,const TextureID * textures)6077 void Context::deleteTextures(GLsizei n, const TextureID *textures)
6078 {
6079 for (int i = 0; i < n; i++)
6080 {
6081 if (textures[i].value != 0)
6082 {
6083 deleteTexture(textures[i]);
6084 }
6085 }
6086 }
6087
detachShader(ShaderProgramID program,ShaderProgramID shader)6088 void Context::detachShader(ShaderProgramID program, ShaderProgramID shader)
6089 {
6090 Program *programObject = getProgramNoResolveLink(program);
6091 ASSERT(programObject);
6092
6093 Shader *shaderObject = getShader(shader);
6094 ASSERT(shaderObject);
6095
6096 programObject->detachShader(this, shaderObject);
6097 }
6098
genBuffers(GLsizei n,BufferID * buffers)6099 void Context::genBuffers(GLsizei n, BufferID *buffers)
6100 {
6101 for (int i = 0; i < n; i++)
6102 {
6103 buffers[i] = createBuffer();
6104 }
6105 }
6106
genFramebuffers(GLsizei n,FramebufferID * framebuffers)6107 void Context::genFramebuffers(GLsizei n, FramebufferID *framebuffers)
6108 {
6109 for (int i = 0; i < n; i++)
6110 {
6111 framebuffers[i] = createFramebuffer();
6112 }
6113 }
6114
genRenderbuffers(GLsizei n,RenderbufferID * renderbuffers)6115 void Context::genRenderbuffers(GLsizei n, RenderbufferID *renderbuffers)
6116 {
6117 for (int i = 0; i < n; i++)
6118 {
6119 renderbuffers[i] = createRenderbuffer();
6120 }
6121 }
6122
genTextures(GLsizei n,TextureID * textures)6123 void Context::genTextures(GLsizei n, TextureID *textures)
6124 {
6125 for (int i = 0; i < n; i++)
6126 {
6127 textures[i] = createTexture();
6128 }
6129 }
6130
getActiveAttrib(ShaderProgramID program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6131 void Context::getActiveAttrib(ShaderProgramID program,
6132 GLuint index,
6133 GLsizei bufsize,
6134 GLsizei *length,
6135 GLint *size,
6136 GLenum *type,
6137 GLchar *name)
6138 {
6139 Program *programObject = getProgramResolveLink(program);
6140 ASSERT(programObject);
6141 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
6142 }
6143
getActiveUniform(ShaderProgramID program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6144 void Context::getActiveUniform(ShaderProgramID program,
6145 GLuint index,
6146 GLsizei bufsize,
6147 GLsizei *length,
6148 GLint *size,
6149 GLenum *type,
6150 GLchar *name)
6151 {
6152 Program *programObject = getProgramResolveLink(program);
6153 ASSERT(programObject);
6154 programObject->getActiveUniform(index, bufsize, length, size, type, name);
6155 }
6156
getAttachedShaders(ShaderProgramID program,GLsizei maxcount,GLsizei * count,ShaderProgramID * shaders)6157 void Context::getAttachedShaders(ShaderProgramID program,
6158 GLsizei maxcount,
6159 GLsizei *count,
6160 ShaderProgramID *shaders)
6161 {
6162 Program *programObject = getProgramNoResolveLink(program);
6163 ASSERT(programObject);
6164 programObject->getAttachedShaders(maxcount, count, shaders);
6165 }
6166
getAttribLocation(ShaderProgramID program,const GLchar * name)6167 GLint Context::getAttribLocation(ShaderProgramID program, const GLchar *name)
6168 {
6169 Program *programObject = getProgramResolveLink(program);
6170 ASSERT(programObject);
6171 return programObject->getAttributeLocation(name);
6172 }
6173
getBooleanv(GLenum pname,GLboolean * params)6174 void Context::getBooleanv(GLenum pname, GLboolean *params)
6175 {
6176 GLenum nativeType;
6177 unsigned int numParams = 0;
6178 getQueryParameterInfo(pname, &nativeType, &numParams);
6179
6180 if (nativeType == GL_BOOL)
6181 {
6182 getBooleanvImpl(pname, params);
6183 }
6184 else
6185 {
6186 CastStateValues(this, nativeType, pname, numParams, params);
6187 }
6188 }
6189
getBooleanvRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLboolean * params)6190 void Context::getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params)
6191 {
6192 getBooleanv(pname, params);
6193 }
6194
getFloatv(GLenum pname,GLfloat * params)6195 void Context::getFloatv(GLenum pname, GLfloat *params)
6196 {
6197 GLenum nativeType;
6198 unsigned int numParams = 0;
6199 getQueryParameterInfo(pname, &nativeType, &numParams);
6200
6201 if (nativeType == GL_FLOAT)
6202 {
6203 getFloatvImpl(pname, params);
6204 }
6205 else
6206 {
6207 CastStateValues(this, nativeType, pname, numParams, params);
6208 }
6209 }
6210
getFloatvRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)6211 void Context::getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params)
6212 {
6213 getFloatv(pname, params);
6214 }
6215
getIntegerv(GLenum pname,GLint * params)6216 void Context::getIntegerv(GLenum pname, GLint *params)
6217 {
6218 GLenum nativeType;
6219 unsigned int numParams = 0;
6220 getQueryParameterInfo(pname, &nativeType, &numParams);
6221
6222 if (nativeType == GL_INT)
6223 {
6224 getIntegervImpl(pname, params);
6225 }
6226 else
6227 {
6228 CastStateValues(this, nativeType, pname, numParams, params);
6229 }
6230 }
6231
getIntegervRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLint * data)6232 void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data)
6233 {
6234 getIntegerv(pname, data);
6235 }
6236
getProgramiv(ShaderProgramID program,GLenum pname,GLint * params)6237 void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params)
6238 {
6239 // Don't resolve link if checking the link completion status.
6240 Program *programObject = getProgramNoResolveLink(program);
6241 if (!isContextLost() && pname != GL_COMPLETION_STATUS_KHR)
6242 {
6243 programObject = getProgramResolveLink(program);
6244 }
6245 ASSERT(programObject);
6246 QueryProgramiv(this, programObject, pname, params);
6247 }
6248
getProgramivRobust(ShaderProgramID program,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)6249 void Context::getProgramivRobust(ShaderProgramID program,
6250 GLenum pname,
6251 GLsizei bufSize,
6252 GLsizei *length,
6253 GLint *params)
6254 {
6255 getProgramiv(program, pname, params);
6256 }
6257
getProgramPipelineiv(ProgramPipelineID pipeline,GLenum pname,GLint * params)6258 void Context::getProgramPipelineiv(ProgramPipelineID pipeline, GLenum pname, GLint *params)
6259 {
6260 ProgramPipeline *programPipeline = nullptr;
6261 if (!mContextLost)
6262 {
6263 programPipeline = getProgramPipeline(pipeline);
6264 }
6265 QueryProgramPipelineiv(this, programPipeline, pname, params);
6266 }
6267
getMemoryObject(MemoryObjectID handle) const6268 MemoryObject *Context::getMemoryObject(MemoryObjectID handle) const
6269 {
6270 return mState.mMemoryObjectManager->getMemoryObject(handle);
6271 }
6272
getSemaphore(SemaphoreID handle) const6273 Semaphore *Context::getSemaphore(SemaphoreID handle) const
6274 {
6275 return mState.mSemaphoreManager->getSemaphore(handle);
6276 }
6277
getProgramInfoLog(ShaderProgramID program,GLsizei bufsize,GLsizei * length,GLchar * infolog)6278 void Context::getProgramInfoLog(ShaderProgramID program,
6279 GLsizei bufsize,
6280 GLsizei *length,
6281 GLchar *infolog)
6282 {
6283 Program *programObject = getProgramResolveLink(program);
6284 ASSERT(programObject);
6285 programObject->getExecutable().getInfoLog(bufsize, length, infolog);
6286 }
6287
getProgramPipelineInfoLog(ProgramPipelineID pipeline,GLsizei bufSize,GLsizei * length,GLchar * infoLog)6288 void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline,
6289 GLsizei bufSize,
6290 GLsizei *length,
6291 GLchar *infoLog)
6292 {
6293 ProgramPipeline *programPipeline = getProgramPipeline(pipeline);
6294 if (programPipeline)
6295 {
6296 programPipeline->getExecutable().getInfoLog(bufSize, length, infoLog);
6297 }
6298 else
6299 {
6300 *length = 0;
6301 *infoLog = '\0';
6302 }
6303 }
6304
getShaderiv(ShaderProgramID shader,GLenum pname,GLint * params)6305 void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params)
6306 {
6307 Shader *shaderObject = nullptr;
6308 if (!isContextLost())
6309 {
6310 shaderObject = getShader(shader);
6311 ASSERT(shaderObject);
6312 }
6313 QueryShaderiv(this, shaderObject, pname, params);
6314 }
6315
getShaderivRobust(ShaderProgramID shader,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)6316 void Context::getShaderivRobust(ShaderProgramID shader,
6317 GLenum pname,
6318 GLsizei bufSize,
6319 GLsizei *length,
6320 GLint *params)
6321 {
6322 getShaderiv(shader, pname, params);
6323 }
6324
getShaderInfoLog(ShaderProgramID shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)6325 void Context::getShaderInfoLog(ShaderProgramID shader,
6326 GLsizei bufsize,
6327 GLsizei *length,
6328 GLchar *infolog)
6329 {
6330 Shader *shaderObject = getShader(shader);
6331 ASSERT(shaderObject);
6332 shaderObject->getInfoLog(bufsize, length, infolog);
6333 }
6334
getShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)6335 void Context::getShaderPrecisionFormat(GLenum shadertype,
6336 GLenum precisiontype,
6337 GLint *range,
6338 GLint *precision)
6339 {
6340 // TODO(jmadill): Compute shaders.
6341
6342 switch (shadertype)
6343 {
6344 case GL_VERTEX_SHADER:
6345 switch (precisiontype)
6346 {
6347 case GL_LOW_FLOAT:
6348 mState.mCaps.vertexLowpFloat.get(range, precision);
6349 break;
6350 case GL_MEDIUM_FLOAT:
6351 mState.mCaps.vertexMediumpFloat.get(range, precision);
6352 break;
6353 case GL_HIGH_FLOAT:
6354 mState.mCaps.vertexHighpFloat.get(range, precision);
6355 break;
6356
6357 case GL_LOW_INT:
6358 mState.mCaps.vertexLowpInt.get(range, precision);
6359 break;
6360 case GL_MEDIUM_INT:
6361 mState.mCaps.vertexMediumpInt.get(range, precision);
6362 break;
6363 case GL_HIGH_INT:
6364 mState.mCaps.vertexHighpInt.get(range, precision);
6365 break;
6366
6367 default:
6368 UNREACHABLE();
6369 return;
6370 }
6371 break;
6372
6373 case GL_FRAGMENT_SHADER:
6374 switch (precisiontype)
6375 {
6376 case GL_LOW_FLOAT:
6377 mState.mCaps.fragmentLowpFloat.get(range, precision);
6378 break;
6379 case GL_MEDIUM_FLOAT:
6380 mState.mCaps.fragmentMediumpFloat.get(range, precision);
6381 break;
6382 case GL_HIGH_FLOAT:
6383 mState.mCaps.fragmentHighpFloat.get(range, precision);
6384 break;
6385
6386 case GL_LOW_INT:
6387 mState.mCaps.fragmentLowpInt.get(range, precision);
6388 break;
6389 case GL_MEDIUM_INT:
6390 mState.mCaps.fragmentMediumpInt.get(range, precision);
6391 break;
6392 case GL_HIGH_INT:
6393 mState.mCaps.fragmentHighpInt.get(range, precision);
6394 break;
6395
6396 default:
6397 UNREACHABLE();
6398 return;
6399 }
6400 break;
6401
6402 default:
6403 UNREACHABLE();
6404 return;
6405 }
6406 }
6407
getShaderSource(ShaderProgramID shader,GLsizei bufsize,GLsizei * length,GLchar * source)6408 void Context::getShaderSource(ShaderProgramID shader,
6409 GLsizei bufsize,
6410 GLsizei *length,
6411 GLchar *source)
6412 {
6413 Shader *shaderObject = getShader(shader);
6414 ASSERT(shaderObject);
6415 shaderObject->getSource(bufsize, length, source);
6416 }
6417
getUniformfv(ShaderProgramID program,UniformLocation location,GLfloat * params)6418 void Context::getUniformfv(ShaderProgramID program, UniformLocation location, GLfloat *params)
6419 {
6420 Program *programObject = getProgramResolveLink(program);
6421 ASSERT(programObject);
6422 programObject->getUniformfv(this, location, params);
6423 }
6424
getUniformfvRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLfloat * params)6425 void Context::getUniformfvRobust(ShaderProgramID program,
6426 UniformLocation location,
6427 GLsizei bufSize,
6428 GLsizei *length,
6429 GLfloat *params)
6430 {
6431 getUniformfv(program, location, params);
6432 }
6433
getUniformiv(ShaderProgramID program,UniformLocation location,GLint * params)6434 void Context::getUniformiv(ShaderProgramID program, UniformLocation location, GLint *params)
6435 {
6436 Program *programObject = getProgramResolveLink(program);
6437 ASSERT(programObject);
6438 programObject->getUniformiv(this, location, params);
6439 }
6440
getUniformivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLint * params)6441 void Context::getUniformivRobust(ShaderProgramID program,
6442 UniformLocation location,
6443 GLsizei bufSize,
6444 GLsizei *length,
6445 GLint *params)
6446 {
6447 getUniformiv(program, location, params);
6448 }
6449
getUniformLocation(ShaderProgramID program,const GLchar * name)6450 GLint Context::getUniformLocation(ShaderProgramID program, const GLchar *name)
6451 {
6452 Program *programObject = getProgramResolveLink(program);
6453 ASSERT(programObject);
6454 return programObject->getUniformLocation(name).value;
6455 }
6456
isBuffer(BufferID buffer) const6457 GLboolean Context::isBuffer(BufferID buffer) const
6458 {
6459 if (buffer.value == 0)
6460 {
6461 return GL_FALSE;
6462 }
6463
6464 return ConvertToGLBoolean(getBuffer(buffer));
6465 }
6466
isEnabled(GLenum cap) const6467 GLboolean Context::isEnabled(GLenum cap) const
6468 {
6469 return mState.getEnableFeature(cap);
6470 }
6471
isEnabledi(GLenum target,GLuint index) const6472 GLboolean Context::isEnabledi(GLenum target, GLuint index) const
6473 {
6474 return mState.getEnableFeatureIndexed(target, index);
6475 }
6476
isFramebuffer(FramebufferID framebuffer) const6477 GLboolean Context::isFramebuffer(FramebufferID framebuffer) const
6478 {
6479 if (framebuffer.value == 0)
6480 {
6481 return GL_FALSE;
6482 }
6483
6484 return ConvertToGLBoolean(getFramebuffer(framebuffer));
6485 }
6486
isProgram(ShaderProgramID program) const6487 GLboolean Context::isProgram(ShaderProgramID program) const
6488 {
6489 if (program.value == 0)
6490 {
6491 return GL_FALSE;
6492 }
6493
6494 return ConvertToGLBoolean(getProgramNoResolveLink(program));
6495 }
6496
isRenderbuffer(RenderbufferID renderbuffer) const6497 GLboolean Context::isRenderbuffer(RenderbufferID renderbuffer) const
6498 {
6499 if (renderbuffer.value == 0)
6500 {
6501 return GL_FALSE;
6502 }
6503
6504 return ConvertToGLBoolean(getRenderbuffer(renderbuffer));
6505 }
6506
isShader(ShaderProgramID shader) const6507 GLboolean Context::isShader(ShaderProgramID shader) const
6508 {
6509 if (shader.value == 0)
6510 {
6511 return GL_FALSE;
6512 }
6513
6514 return ConvertToGLBoolean(getShader(shader));
6515 }
6516
isTexture(TextureID texture) const6517 GLboolean Context::isTexture(TextureID texture) const
6518 {
6519 if (texture.value == 0)
6520 {
6521 return GL_FALSE;
6522 }
6523
6524 return ConvertToGLBoolean(getTexture(texture));
6525 }
6526
linkProgram(ShaderProgramID program)6527 void Context::linkProgram(ShaderProgramID program)
6528 {
6529 Program *programObject = getProgramNoResolveLink(program);
6530 ASSERT(programObject);
6531 ANGLE_CONTEXT_TRY(programObject->link(this));
6532 ANGLE_CONTEXT_TRY(onProgramLink(programObject));
6533 }
6534
releaseShaderCompiler()6535 void Context::releaseShaderCompiler()
6536 {
6537 mCompiler.set(this, nullptr);
6538 }
6539
shaderBinary(GLsizei n,const ShaderProgramID * shaders,GLenum binaryformat,const void * binary,GLsizei length)6540 void Context::shaderBinary(GLsizei n,
6541 const ShaderProgramID *shaders,
6542 GLenum binaryformat,
6543 const void *binary,
6544 GLsizei length)
6545 {
6546 // No binary shader formats are supported.
6547 UNIMPLEMENTED();
6548 }
6549
bindFragDataLocationIndexed(ShaderProgramID program,GLuint colorNumber,GLuint index,const char * name)6550 void Context::bindFragDataLocationIndexed(ShaderProgramID program,
6551 GLuint colorNumber,
6552 GLuint index,
6553 const char *name)
6554 {
6555 Program *programObject = getProgramNoResolveLink(program);
6556 programObject->bindFragmentOutputLocation(colorNumber, name);
6557 programObject->bindFragmentOutputIndex(index, name);
6558 }
6559
bindFragDataLocation(ShaderProgramID program,GLuint colorNumber,const char * name)6560 void Context::bindFragDataLocation(ShaderProgramID program, GLuint colorNumber, const char *name)
6561 {
6562 bindFragDataLocationIndexed(program, colorNumber, 0u, name);
6563 }
6564
getFragDataIndex(ShaderProgramID program,const char * name)6565 int Context::getFragDataIndex(ShaderProgramID program, const char *name)
6566 {
6567 Program *programObject = getProgramResolveLink(program);
6568 return programObject->getFragDataIndex(name);
6569 }
6570
getProgramResourceLocationIndex(ShaderProgramID program,GLenum programInterface,const char * name)6571 int Context::getProgramResourceLocationIndex(ShaderProgramID program,
6572 GLenum programInterface,
6573 const char *name)
6574 {
6575 Program *programObject = getProgramResolveLink(program);
6576 ASSERT(programInterface == GL_PROGRAM_OUTPUT);
6577 return programObject->getFragDataIndex(name);
6578 }
6579
shaderSource(ShaderProgramID shader,GLsizei count,const GLchar * const * string,const GLint * length)6580 void Context::shaderSource(ShaderProgramID shader,
6581 GLsizei count,
6582 const GLchar *const *string,
6583 const GLint *length)
6584 {
6585 Shader *shaderObject = getShader(shader);
6586 ASSERT(shaderObject);
6587 shaderObject->setSource(count, string, length);
6588 }
6589
stencilFunc(GLenum func,GLint ref,GLuint mask)6590 void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
6591 {
6592 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
6593 }
6594
stencilMask(GLuint mask)6595 void Context::stencilMask(GLuint mask)
6596 {
6597 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
6598 }
6599
stencilOp(GLenum fail,GLenum zfail,GLenum zpass)6600 void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
6601 {
6602 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
6603 }
6604
patchParameteri(GLenum pname,GLint value)6605 void Context::patchParameteri(GLenum pname, GLint value)
6606 {
6607 UNIMPLEMENTED();
6608 }
6609
getActiveLinkedProgram() const6610 Program *Context::getActiveLinkedProgram() const
6611 {
6612 Program *program = mState.getLinkedProgram(this);
6613 if (!program)
6614 {
6615 ProgramPipeline *programPipelineObject = mState.getProgramPipeline();
6616 if (programPipelineObject)
6617 {
6618 program = programPipelineObject->getLinkedActiveShaderProgram(this);
6619 }
6620 }
6621
6622 return program;
6623 }
6624
uniform1f(UniformLocation location,GLfloat x)6625 void Context::uniform1f(UniformLocation location, GLfloat x)
6626 {
6627 Program *program = getActiveLinkedProgram();
6628 program->setUniform1fv(location, 1, &x);
6629 }
6630
uniform1fv(UniformLocation location,GLsizei count,const GLfloat * v)6631 void Context::uniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
6632 {
6633 Program *program = getActiveLinkedProgram();
6634 program->setUniform1fv(location, count, v);
6635 }
6636
setUniform1iImpl(Program * program,UniformLocation location,GLsizei count,const GLint * v)6637 void Context::setUniform1iImpl(Program *program,
6638 UniformLocation location,
6639 GLsizei count,
6640 const GLint *v)
6641 {
6642 program->setUniform1iv(this, location, count, v);
6643 }
6644
onSamplerUniformChange(size_t textureUnitIndex)6645 void Context::onSamplerUniformChange(size_t textureUnitIndex)
6646 {
6647 mState.onActiveTextureChange(this, textureUnitIndex);
6648 mStateCache.onActiveTextureChange(this);
6649 }
6650
uniform1i(UniformLocation location,GLint x)6651 void Context::uniform1i(UniformLocation location, GLint x)
6652 {
6653 Program *program = getActiveLinkedProgram();
6654 setUniform1iImpl(program, location, 1, &x);
6655 }
6656
uniform1iv(UniformLocation location,GLsizei count,const GLint * v)6657 void Context::uniform1iv(UniformLocation location, GLsizei count, const GLint *v)
6658 {
6659 Program *program = getActiveLinkedProgram();
6660 setUniform1iImpl(program, location, count, v);
6661 }
6662
uniform2f(UniformLocation location,GLfloat x,GLfloat y)6663 void Context::uniform2f(UniformLocation location, GLfloat x, GLfloat y)
6664 {
6665 GLfloat xy[2] = {x, y};
6666 Program *program = getActiveLinkedProgram();
6667 program->setUniform2fv(location, 1, xy);
6668 }
6669
uniform2fv(UniformLocation location,GLsizei count,const GLfloat * v)6670 void Context::uniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
6671 {
6672 Program *program = getActiveLinkedProgram();
6673 program->setUniform2fv(location, count, v);
6674 }
6675
uniform2i(UniformLocation location,GLint x,GLint y)6676 void Context::uniform2i(UniformLocation location, GLint x, GLint y)
6677 {
6678 GLint xy[2] = {x, y};
6679 Program *program = getActiveLinkedProgram();
6680 program->setUniform2iv(location, 1, xy);
6681 }
6682
uniform2iv(UniformLocation location,GLsizei count,const GLint * v)6683 void Context::uniform2iv(UniformLocation location, GLsizei count, const GLint *v)
6684 {
6685 Program *program = getActiveLinkedProgram();
6686 program->setUniform2iv(location, count, v);
6687 }
6688
uniform3f(UniformLocation location,GLfloat x,GLfloat y,GLfloat z)6689 void Context::uniform3f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z)
6690 {
6691 GLfloat xyz[3] = {x, y, z};
6692 Program *program = getActiveLinkedProgram();
6693 program->setUniform3fv(location, 1, xyz);
6694 }
6695
uniform3fv(UniformLocation location,GLsizei count,const GLfloat * v)6696 void Context::uniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
6697 {
6698 Program *program = getActiveLinkedProgram();
6699 program->setUniform3fv(location, count, v);
6700 }
6701
uniform3i(UniformLocation location,GLint x,GLint y,GLint z)6702 void Context::uniform3i(UniformLocation location, GLint x, GLint y, GLint z)
6703 {
6704 GLint xyz[3] = {x, y, z};
6705 Program *program = getActiveLinkedProgram();
6706 program->setUniform3iv(location, 1, xyz);
6707 }
6708
uniform3iv(UniformLocation location,GLsizei count,const GLint * v)6709 void Context::uniform3iv(UniformLocation location, GLsizei count, const GLint *v)
6710 {
6711 Program *program = getActiveLinkedProgram();
6712 program->setUniform3iv(location, count, v);
6713 }
6714
uniform4f(UniformLocation location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)6715 void Context::uniform4f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6716 {
6717 GLfloat xyzw[4] = {x, y, z, w};
6718 Program *program = getActiveLinkedProgram();
6719 program->setUniform4fv(location, 1, xyzw);
6720 }
6721
uniform4fv(UniformLocation location,GLsizei count,const GLfloat * v)6722 void Context::uniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
6723 {
6724 Program *program = getActiveLinkedProgram();
6725 program->setUniform4fv(location, count, v);
6726 }
6727
uniform4i(UniformLocation location,GLint x,GLint y,GLint z,GLint w)6728 void Context::uniform4i(UniformLocation location, GLint x, GLint y, GLint z, GLint w)
6729 {
6730 GLint xyzw[4] = {x, y, z, w};
6731 Program *program = getActiveLinkedProgram();
6732 program->setUniform4iv(location, 1, xyzw);
6733 }
6734
uniform4iv(UniformLocation location,GLsizei count,const GLint * v)6735 void Context::uniform4iv(UniformLocation location, GLsizei count, const GLint *v)
6736 {
6737 Program *program = getActiveLinkedProgram();
6738 program->setUniform4iv(location, count, v);
6739 }
6740
uniformMatrix2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6741 void Context::uniformMatrix2fv(UniformLocation location,
6742 GLsizei count,
6743 GLboolean transpose,
6744 const GLfloat *value)
6745 {
6746 Program *program = getActiveLinkedProgram();
6747 program->setUniformMatrix2fv(location, count, transpose, value);
6748 }
6749
uniformMatrix3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6750 void Context::uniformMatrix3fv(UniformLocation location,
6751 GLsizei count,
6752 GLboolean transpose,
6753 const GLfloat *value)
6754 {
6755 Program *program = getActiveLinkedProgram();
6756 program->setUniformMatrix3fv(location, count, transpose, value);
6757 }
6758
uniformMatrix4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6759 void Context::uniformMatrix4fv(UniformLocation location,
6760 GLsizei count,
6761 GLboolean transpose,
6762 const GLfloat *value)
6763 {
6764 Program *program = getActiveLinkedProgram();
6765 program->setUniformMatrix4fv(location, count, transpose, value);
6766 }
6767
validateProgram(ShaderProgramID program)6768 void Context::validateProgram(ShaderProgramID program)
6769 {
6770 Program *programObject = getProgramResolveLink(program);
6771 ASSERT(programObject);
6772 programObject->validate(mState.mCaps);
6773 }
6774
validateProgramPipeline(ProgramPipelineID pipeline)6775 void Context::validateProgramPipeline(ProgramPipelineID pipeline)
6776 {
6777 ProgramPipeline *programPipeline =
6778 mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
6779 pipeline);
6780 ASSERT(programPipeline);
6781
6782 programPipeline->validate(this);
6783 }
6784
getProgramBinary(ShaderProgramID program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,void * binary)6785 void Context::getProgramBinary(ShaderProgramID program,
6786 GLsizei bufSize,
6787 GLsizei *length,
6788 GLenum *binaryFormat,
6789 void *binary)
6790 {
6791 Program *programObject = getProgramResolveLink(program);
6792 ASSERT(programObject != nullptr);
6793
6794 ANGLE_CONTEXT_TRY(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
6795 }
6796
programBinary(ShaderProgramID program,GLenum binaryFormat,const void * binary,GLsizei length)6797 void Context::programBinary(ShaderProgramID program,
6798 GLenum binaryFormat,
6799 const void *binary,
6800 GLsizei length)
6801 {
6802 Program *programObject = getProgramResolveLink(program);
6803 ASSERT(programObject != nullptr);
6804
6805 ANGLE_CONTEXT_TRY(programObject->loadBinary(this, binaryFormat, binary, length));
6806 ANGLE_CONTEXT_TRY(onProgramLink(programObject));
6807 }
6808
uniform1ui(UniformLocation location,GLuint v0)6809 void Context::uniform1ui(UniformLocation location, GLuint v0)
6810 {
6811 Program *program = getActiveLinkedProgram();
6812 program->setUniform1uiv(location, 1, &v0);
6813 }
6814
uniform2ui(UniformLocation location,GLuint v0,GLuint v1)6815 void Context::uniform2ui(UniformLocation location, GLuint v0, GLuint v1)
6816 {
6817 Program *program = getActiveLinkedProgram();
6818 const GLuint xy[] = {v0, v1};
6819 program->setUniform2uiv(location, 1, xy);
6820 }
6821
uniform3ui(UniformLocation location,GLuint v0,GLuint v1,GLuint v2)6822 void Context::uniform3ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2)
6823 {
6824 Program *program = getActiveLinkedProgram();
6825 const GLuint xyz[] = {v0, v1, v2};
6826 program->setUniform3uiv(location, 1, xyz);
6827 }
6828
uniform4ui(UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)6829 void Context::uniform4ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
6830 {
6831 Program *program = getActiveLinkedProgram();
6832 const GLuint xyzw[] = {v0, v1, v2, v3};
6833 program->setUniform4uiv(location, 1, xyzw);
6834 }
6835
uniform1uiv(UniformLocation location,GLsizei count,const GLuint * value)6836 void Context::uniform1uiv(UniformLocation location, GLsizei count, const GLuint *value)
6837 {
6838 Program *program = getActiveLinkedProgram();
6839 program->setUniform1uiv(location, count, value);
6840 }
uniform2uiv(UniformLocation location,GLsizei count,const GLuint * value)6841 void Context::uniform2uiv(UniformLocation location, GLsizei count, const GLuint *value)
6842 {
6843 Program *program = getActiveLinkedProgram();
6844 program->setUniform2uiv(location, count, value);
6845 }
6846
uniform3uiv(UniformLocation location,GLsizei count,const GLuint * value)6847 void Context::uniform3uiv(UniformLocation location, GLsizei count, const GLuint *value)
6848 {
6849 Program *program = getActiveLinkedProgram();
6850 program->setUniform3uiv(location, count, value);
6851 }
6852
uniform4uiv(UniformLocation location,GLsizei count,const GLuint * value)6853 void Context::uniform4uiv(UniformLocation location, GLsizei count, const GLuint *value)
6854 {
6855 Program *program = getActiveLinkedProgram();
6856 program->setUniform4uiv(location, count, value);
6857 }
6858
genQueries(GLsizei n,QueryID * ids)6859 void Context::genQueries(GLsizei n, QueryID *ids)
6860 {
6861 for (GLsizei i = 0; i < n; i++)
6862 {
6863 QueryID handle = QueryID{mQueryHandleAllocator.allocate()};
6864 mQueryMap.assign(handle, nullptr);
6865 ids[i] = handle;
6866 }
6867 }
6868
deleteQueries(GLsizei n,const QueryID * ids)6869 void Context::deleteQueries(GLsizei n, const QueryID *ids)
6870 {
6871 for (int i = 0; i < n; i++)
6872 {
6873 QueryID query = ids[i];
6874
6875 Query *queryObject = nullptr;
6876 if (mQueryMap.erase(query, &queryObject))
6877 {
6878 mQueryHandleAllocator.release(query.value);
6879 if (queryObject)
6880 {
6881 queryObject->release(this);
6882 }
6883 }
6884 }
6885 }
6886
isQueryGenerated(QueryID query) const6887 bool Context::isQueryGenerated(QueryID query) const
6888 {
6889 return mQueryMap.contains(query);
6890 }
6891
isQuery(QueryID id) const6892 GLboolean Context::isQuery(QueryID id) const
6893 {
6894 return ConvertToGLBoolean(getQuery(id) != nullptr);
6895 }
6896
uniformMatrix2x3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6897 void Context::uniformMatrix2x3fv(UniformLocation location,
6898 GLsizei count,
6899 GLboolean transpose,
6900 const GLfloat *value)
6901 {
6902 Program *program = getActiveLinkedProgram();
6903 program->setUniformMatrix2x3fv(location, count, transpose, value);
6904 }
6905
uniformMatrix3x2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6906 void Context::uniformMatrix3x2fv(UniformLocation location,
6907 GLsizei count,
6908 GLboolean transpose,
6909 const GLfloat *value)
6910 {
6911 Program *program = getActiveLinkedProgram();
6912 program->setUniformMatrix3x2fv(location, count, transpose, value);
6913 }
6914
uniformMatrix2x4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6915 void Context::uniformMatrix2x4fv(UniformLocation location,
6916 GLsizei count,
6917 GLboolean transpose,
6918 const GLfloat *value)
6919 {
6920 Program *program = getActiveLinkedProgram();
6921 program->setUniformMatrix2x4fv(location, count, transpose, value);
6922 }
6923
uniformMatrix4x2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6924 void Context::uniformMatrix4x2fv(UniformLocation location,
6925 GLsizei count,
6926 GLboolean transpose,
6927 const GLfloat *value)
6928 {
6929 Program *program = getActiveLinkedProgram();
6930 program->setUniformMatrix4x2fv(location, count, transpose, value);
6931 }
6932
uniformMatrix3x4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6933 void Context::uniformMatrix3x4fv(UniformLocation location,
6934 GLsizei count,
6935 GLboolean transpose,
6936 const GLfloat *value)
6937 {
6938 Program *program = getActiveLinkedProgram();
6939 program->setUniformMatrix3x4fv(location, count, transpose, value);
6940 }
6941
uniformMatrix4x3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6942 void Context::uniformMatrix4x3fv(UniformLocation location,
6943 GLsizei count,
6944 GLboolean transpose,
6945 const GLfloat *value)
6946 {
6947 Program *program = getActiveLinkedProgram();
6948 program->setUniformMatrix4x3fv(location, count, transpose, value);
6949 }
6950
deleteVertexArrays(GLsizei n,const VertexArrayID * arrays)6951 void Context::deleteVertexArrays(GLsizei n, const VertexArrayID *arrays)
6952 {
6953 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
6954 {
6955 VertexArrayID vertexArray = arrays[arrayIndex];
6956
6957 if (arrays[arrayIndex].value != 0)
6958 {
6959 VertexArray *vertexArrayObject = nullptr;
6960 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
6961 {
6962 if (vertexArrayObject != nullptr)
6963 {
6964 detachVertexArray(vertexArray);
6965 vertexArrayObject->onDestroy(this);
6966 }
6967
6968 mVertexArrayHandleAllocator.release(vertexArray.value);
6969 }
6970 }
6971 }
6972 }
6973
genVertexArrays(GLsizei n,VertexArrayID * arrays)6974 void Context::genVertexArrays(GLsizei n, VertexArrayID *arrays)
6975 {
6976 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
6977 {
6978 VertexArrayID vertexArray = {mVertexArrayHandleAllocator.allocate()};
6979 mVertexArrayMap.assign(vertexArray, nullptr);
6980 arrays[arrayIndex] = vertexArray;
6981 }
6982 }
6983
isVertexArray(VertexArrayID array) const6984 GLboolean Context::isVertexArray(VertexArrayID array) const
6985 {
6986 if (array.value == 0)
6987 {
6988 return GL_FALSE;
6989 }
6990
6991 VertexArray *vao = getVertexArray(array);
6992 return ConvertToGLBoolean(vao != nullptr);
6993 }
6994
endTransformFeedback()6995 void Context::endTransformFeedback()
6996 {
6997 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
6998 ANGLE_CONTEXT_TRY(transformFeedback->end(this));
6999 mStateCache.onActiveTransformFeedbackChange(this);
7000 }
7001
transformFeedbackVaryings(ShaderProgramID program,GLsizei count,const GLchar * const * varyings,GLenum bufferMode)7002 void Context::transformFeedbackVaryings(ShaderProgramID program,
7003 GLsizei count,
7004 const GLchar *const *varyings,
7005 GLenum bufferMode)
7006 {
7007 Program *programObject = getProgramResolveLink(program);
7008 ASSERT(programObject);
7009 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
7010 }
7011
getTransformFeedbackVarying(ShaderProgramID program,GLuint index,GLsizei bufSize,GLsizei * length,GLsizei * size,GLenum * type,GLchar * name)7012 void Context::getTransformFeedbackVarying(ShaderProgramID program,
7013 GLuint index,
7014 GLsizei bufSize,
7015 GLsizei *length,
7016 GLsizei *size,
7017 GLenum *type,
7018 GLchar *name)
7019 {
7020 Program *programObject = getProgramResolveLink(program);
7021 ASSERT(programObject);
7022 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
7023 }
7024
deleteTransformFeedbacks(GLsizei n,const TransformFeedbackID * ids)7025 void Context::deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *ids)
7026 {
7027 for (int i = 0; i < n; i++)
7028 {
7029 TransformFeedbackID transformFeedback = ids[i];
7030 if (transformFeedback.value == 0)
7031 {
7032 continue;
7033 }
7034
7035 TransformFeedback *transformFeedbackObject = nullptr;
7036 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
7037 {
7038 if (transformFeedbackObject != nullptr)
7039 {
7040 detachTransformFeedback(transformFeedback);
7041 transformFeedbackObject->release(this);
7042 }
7043
7044 mTransformFeedbackHandleAllocator.release(transformFeedback.value);
7045 }
7046 }
7047 }
7048
genTransformFeedbacks(GLsizei n,TransformFeedbackID * ids)7049 void Context::genTransformFeedbacks(GLsizei n, TransformFeedbackID *ids)
7050 {
7051 for (int i = 0; i < n; i++)
7052 {
7053 TransformFeedbackID transformFeedback = {mTransformFeedbackHandleAllocator.allocate()};
7054 mTransformFeedbackMap.assign(transformFeedback, nullptr);
7055 ids[i] = transformFeedback;
7056 }
7057 }
7058
isTransformFeedback(TransformFeedbackID id) const7059 GLboolean Context::isTransformFeedback(TransformFeedbackID id) const
7060 {
7061 if (id.value == 0)
7062 {
7063 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
7064 // returns FALSE
7065 return GL_FALSE;
7066 }
7067
7068 const TransformFeedback *transformFeedback = getTransformFeedback(id);
7069 return ConvertToGLBoolean(transformFeedback != nullptr);
7070 }
7071
pauseTransformFeedback()7072 void Context::pauseTransformFeedback()
7073 {
7074 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
7075 ANGLE_CONTEXT_TRY(transformFeedback->pause(this));
7076 mStateCache.onActiveTransformFeedbackChange(this);
7077 }
7078
resumeTransformFeedback()7079 void Context::resumeTransformFeedback()
7080 {
7081 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
7082 ANGLE_CONTEXT_TRY(transformFeedback->resume(this));
7083 mStateCache.onActiveTransformFeedbackChange(this);
7084 }
7085
getUniformuiv(ShaderProgramID program,UniformLocation location,GLuint * params)7086 void Context::getUniformuiv(ShaderProgramID program, UniformLocation location, GLuint *params)
7087 {
7088 const Program *programObject = getProgramResolveLink(program);
7089 programObject->getUniformuiv(this, location, params);
7090 }
7091
getUniformuivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLuint * params)7092 void Context::getUniformuivRobust(ShaderProgramID program,
7093 UniformLocation location,
7094 GLsizei bufSize,
7095 GLsizei *length,
7096 GLuint *params)
7097 {
7098 getUniformuiv(program, location, params);
7099 }
7100
getFragDataLocation(ShaderProgramID program,const GLchar * name)7101 GLint Context::getFragDataLocation(ShaderProgramID program, const GLchar *name)
7102 {
7103 const Program *programObject = getProgramResolveLink(program);
7104 return programObject->getFragDataLocation(name);
7105 }
7106
getUniformIndices(ShaderProgramID program,GLsizei uniformCount,const GLchar * const * uniformNames,GLuint * uniformIndices)7107 void Context::getUniformIndices(ShaderProgramID program,
7108 GLsizei uniformCount,
7109 const GLchar *const *uniformNames,
7110 GLuint *uniformIndices)
7111 {
7112 const Program *programObject = getProgramResolveLink(program);
7113 if (!programObject->isLinked())
7114 {
7115 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
7116 {
7117 uniformIndices[uniformId] = GL_INVALID_INDEX;
7118 }
7119 }
7120 else
7121 {
7122 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
7123 {
7124 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
7125 }
7126 }
7127 }
7128
getActiveUniformsiv(ShaderProgramID program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)7129 void Context::getActiveUniformsiv(ShaderProgramID program,
7130 GLsizei uniformCount,
7131 const GLuint *uniformIndices,
7132 GLenum pname,
7133 GLint *params)
7134 {
7135 const Program *programObject = getProgramResolveLink(program);
7136 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
7137 {
7138 const GLuint index = uniformIndices[uniformId];
7139 params[uniformId] = GetUniformResourceProperty(programObject, index, pname);
7140 }
7141 }
7142
getUniformBlockIndex(ShaderProgramID program,const GLchar * uniformBlockName)7143 GLuint Context::getUniformBlockIndex(ShaderProgramID program, const GLchar *uniformBlockName)
7144 {
7145 const Program *programObject = getProgramResolveLink(program);
7146 return programObject->getUniformBlockIndex(uniformBlockName);
7147 }
7148
getActiveUniformBlockiv(ShaderProgramID program,GLuint uniformBlockIndex,GLenum pname,GLint * params)7149 void Context::getActiveUniformBlockiv(ShaderProgramID program,
7150 GLuint uniformBlockIndex,
7151 GLenum pname,
7152 GLint *params)
7153 {
7154 const Program *programObject = getProgramResolveLink(program);
7155 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
7156 }
7157
getActiveUniformBlockivRobust(ShaderProgramID program,GLuint uniformBlockIndex,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)7158 void Context::getActiveUniformBlockivRobust(ShaderProgramID program,
7159 GLuint uniformBlockIndex,
7160 GLenum pname,
7161 GLsizei bufSize,
7162 GLsizei *length,
7163 GLint *params)
7164 {
7165 getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
7166 }
7167
getActiveUniformBlockName(ShaderProgramID program,GLuint uniformBlockIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformBlockName)7168 void Context::getActiveUniformBlockName(ShaderProgramID program,
7169 GLuint uniformBlockIndex,
7170 GLsizei bufSize,
7171 GLsizei *length,
7172 GLchar *uniformBlockName)
7173 {
7174 const Program *programObject = getProgramResolveLink(program);
7175 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
7176 }
7177
uniformBlockBinding(ShaderProgramID program,GLuint uniformBlockIndex,GLuint uniformBlockBinding)7178 void Context::uniformBlockBinding(ShaderProgramID program,
7179 GLuint uniformBlockIndex,
7180 GLuint uniformBlockBinding)
7181 {
7182 Program *programObject = getProgramResolveLink(program);
7183 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
7184
7185 // Note: If the Program is shared between Contexts we would be better using Observer/Subject.
7186 if (programObject->isInUse())
7187 {
7188 mState.setObjectDirty(GL_PROGRAM);
7189 mStateCache.onUniformBufferStateChange(this);
7190 }
7191 }
7192
fenceSync(GLenum condition,GLbitfield flags)7193 GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
7194 {
7195 GLuint handle = mState.mSyncManager->createSync(mImplementation.get());
7196 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
7197
7198 Sync *syncObject = getSync(syncHandle);
7199 if (syncObject->set(this, condition, flags) == angle::Result::Stop)
7200 {
7201 deleteSync(syncHandle);
7202 return nullptr;
7203 }
7204
7205 return syncHandle;
7206 }
7207
isSync(GLsync sync) const7208 GLboolean Context::isSync(GLsync sync) const
7209 {
7210 return (getSync(sync) != nullptr);
7211 }
7212
clientWaitSync(GLsync sync,GLbitfield flags,GLuint64 timeout)7213 GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
7214 {
7215 Sync *syncObject = getSync(sync);
7216
7217 GLenum result = GL_WAIT_FAILED;
7218 if (syncObject->clientWait(this, flags, timeout, &result) == angle::Result::Stop)
7219 {
7220 return GL_WAIT_FAILED;
7221 }
7222 return result;
7223 }
7224
waitSync(GLsync sync,GLbitfield flags,GLuint64 timeout)7225 void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
7226 {
7227 Sync *syncObject = getSync(sync);
7228 ANGLE_CONTEXT_TRY(syncObject->serverWait(this, flags, timeout));
7229 }
7230
getInteger64v(GLenum pname,GLint64 * params)7231 void Context::getInteger64v(GLenum pname, GLint64 *params)
7232 {
7233 GLenum nativeType = GL_NONE;
7234 unsigned int numParams = 0;
7235 getQueryParameterInfo(pname, &nativeType, &numParams);
7236
7237 if (nativeType == GL_INT_64_ANGLEX)
7238 {
7239 getInteger64vImpl(pname, params);
7240 }
7241 else
7242 {
7243 CastStateValues(this, nativeType, pname, numParams, params);
7244 }
7245 }
7246
getInteger64vRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLint64 * data)7247 void Context::getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data)
7248 {
7249 getInteger64v(pname, data);
7250 }
7251
getBufferParameteri64v(BufferBinding target,GLenum pname,GLint64 * params)7252 void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
7253 {
7254 Buffer *buffer = mState.getTargetBuffer(target);
7255 QueryBufferParameteri64v(buffer, pname, params);
7256 }
7257
getBufferParameteri64vRobust(BufferBinding target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint64 * params)7258 void Context::getBufferParameteri64vRobust(BufferBinding target,
7259 GLenum pname,
7260 GLsizei bufSize,
7261 GLsizei *length,
7262 GLint64 *params)
7263 {
7264 getBufferParameteri64v(target, pname, params);
7265 }
7266
genSamplers(GLsizei count,SamplerID * samplers)7267 void Context::genSamplers(GLsizei count, SamplerID *samplers)
7268 {
7269 for (int i = 0; i < count; i++)
7270 {
7271 samplers[i] = mState.mSamplerManager->createSampler();
7272 }
7273 }
7274
deleteSamplers(GLsizei count,const SamplerID * samplers)7275 void Context::deleteSamplers(GLsizei count, const SamplerID *samplers)
7276 {
7277 for (int i = 0; i < count; i++)
7278 {
7279 SamplerID sampler = samplers[i];
7280
7281 if (mState.mSamplerManager->getSampler(sampler))
7282 {
7283 detachSampler(sampler);
7284 }
7285
7286 mState.mSamplerManager->deleteObject(this, sampler);
7287 }
7288 }
7289
minSampleShading(GLfloat value)7290 void Context::minSampleShading(GLfloat value)
7291 {
7292 UNIMPLEMENTED();
7293 }
7294
getInternalformativ(GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)7295 void Context::getInternalformativ(GLenum target,
7296 GLenum internalformat,
7297 GLenum pname,
7298 GLsizei bufSize,
7299 GLint *params)
7300 {
7301 const TextureCaps &formatCaps = mState.mTextureCaps.get(internalformat);
7302 QueryInternalFormativ(formatCaps, pname, bufSize, params);
7303 }
7304
getInternalformativRobust(GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)7305 void Context::getInternalformativRobust(GLenum target,
7306 GLenum internalformat,
7307 GLenum pname,
7308 GLsizei bufSize,
7309 GLsizei *length,
7310 GLint *params)
7311 {
7312 getInternalformativ(target, internalformat, pname, bufSize, params);
7313 }
7314
programUniform1i(ShaderProgramID program,UniformLocation location,GLint v0)7315 void Context::programUniform1i(ShaderProgramID program, UniformLocation location, GLint v0)
7316 {
7317 programUniform1iv(program, location, 1, &v0);
7318 }
7319
programUniform2i(ShaderProgramID program,UniformLocation location,GLint v0,GLint v1)7320 void Context::programUniform2i(ShaderProgramID program,
7321 UniformLocation location,
7322 GLint v0,
7323 GLint v1)
7324 {
7325 GLint xy[2] = {v0, v1};
7326 programUniform2iv(program, location, 1, xy);
7327 }
7328
programUniform3i(ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2)7329 void Context::programUniform3i(ShaderProgramID program,
7330 UniformLocation location,
7331 GLint v0,
7332 GLint v1,
7333 GLint v2)
7334 {
7335 GLint xyz[3] = {v0, v1, v2};
7336 programUniform3iv(program, location, 1, xyz);
7337 }
7338
programUniform4i(ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2,GLint v3)7339 void Context::programUniform4i(ShaderProgramID program,
7340 UniformLocation location,
7341 GLint v0,
7342 GLint v1,
7343 GLint v2,
7344 GLint v3)
7345 {
7346 GLint xyzw[4] = {v0, v1, v2, v3};
7347 programUniform4iv(program, location, 1, xyzw);
7348 }
7349
programUniform1ui(ShaderProgramID program,UniformLocation location,GLuint v0)7350 void Context::programUniform1ui(ShaderProgramID program, UniformLocation location, GLuint v0)
7351 {
7352 programUniform1uiv(program, location, 1, &v0);
7353 }
7354
programUniform2ui(ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1)7355 void Context::programUniform2ui(ShaderProgramID program,
7356 UniformLocation location,
7357 GLuint v0,
7358 GLuint v1)
7359 {
7360 GLuint xy[2] = {v0, v1};
7361 programUniform2uiv(program, location, 1, xy);
7362 }
7363
programUniform3ui(ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)7364 void Context::programUniform3ui(ShaderProgramID program,
7365 UniformLocation location,
7366 GLuint v0,
7367 GLuint v1,
7368 GLuint v2)
7369 {
7370 GLuint xyz[3] = {v0, v1, v2};
7371 programUniform3uiv(program, location, 1, xyz);
7372 }
7373
programUniform4ui(ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)7374 void Context::programUniform4ui(ShaderProgramID program,
7375 UniformLocation location,
7376 GLuint v0,
7377 GLuint v1,
7378 GLuint v2,
7379 GLuint v3)
7380 {
7381 GLuint xyzw[4] = {v0, v1, v2, v3};
7382 programUniform4uiv(program, location, 1, xyzw);
7383 }
7384
programUniform1f(ShaderProgramID program,UniformLocation location,GLfloat v0)7385 void Context::programUniform1f(ShaderProgramID program, UniformLocation location, GLfloat v0)
7386 {
7387 programUniform1fv(program, location, 1, &v0);
7388 }
7389
programUniform2f(ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1)7390 void Context::programUniform2f(ShaderProgramID program,
7391 UniformLocation location,
7392 GLfloat v0,
7393 GLfloat v1)
7394 {
7395 GLfloat xy[2] = {v0, v1};
7396 programUniform2fv(program, location, 1, xy);
7397 }
7398
programUniform3f(ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2)7399 void Context::programUniform3f(ShaderProgramID program,
7400 UniformLocation location,
7401 GLfloat v0,
7402 GLfloat v1,
7403 GLfloat v2)
7404 {
7405 GLfloat xyz[3] = {v0, v1, v2};
7406 programUniform3fv(program, location, 1, xyz);
7407 }
7408
programUniform4f(ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)7409 void Context::programUniform4f(ShaderProgramID program,
7410 UniformLocation location,
7411 GLfloat v0,
7412 GLfloat v1,
7413 GLfloat v2,
7414 GLfloat v3)
7415 {
7416 GLfloat xyzw[4] = {v0, v1, v2, v3};
7417 programUniform4fv(program, location, 1, xyzw);
7418 }
7419
programUniform1iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7420 void Context::programUniform1iv(ShaderProgramID program,
7421 UniformLocation location,
7422 GLsizei count,
7423 const GLint *value)
7424 {
7425 Program *programObject = getProgramResolveLink(program);
7426 ASSERT(programObject);
7427 setUniform1iImpl(programObject, location, count, value);
7428 }
7429
programUniform2iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7430 void Context::programUniform2iv(ShaderProgramID program,
7431 UniformLocation location,
7432 GLsizei count,
7433 const GLint *value)
7434 {
7435 Program *programObject = getProgramResolveLink(program);
7436 ASSERT(programObject);
7437 programObject->setUniform2iv(location, count, value);
7438 }
7439
programUniform3iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7440 void Context::programUniform3iv(ShaderProgramID program,
7441 UniformLocation location,
7442 GLsizei count,
7443 const GLint *value)
7444 {
7445 Program *programObject = getProgramResolveLink(program);
7446 ASSERT(programObject);
7447 programObject->setUniform3iv(location, count, value);
7448 }
7449
programUniform4iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7450 void Context::programUniform4iv(ShaderProgramID program,
7451 UniformLocation location,
7452 GLsizei count,
7453 const GLint *value)
7454 {
7455 Program *programObject = getProgramResolveLink(program);
7456 ASSERT(programObject);
7457 programObject->setUniform4iv(location, count, value);
7458 }
7459
programUniform1uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7460 void Context::programUniform1uiv(ShaderProgramID program,
7461 UniformLocation location,
7462 GLsizei count,
7463 const GLuint *value)
7464 {
7465 Program *programObject = getProgramResolveLink(program);
7466 ASSERT(programObject);
7467 programObject->setUniform1uiv(location, count, value);
7468 }
7469
programUniform2uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7470 void Context::programUniform2uiv(ShaderProgramID program,
7471 UniformLocation location,
7472 GLsizei count,
7473 const GLuint *value)
7474 {
7475 Program *programObject = getProgramResolveLink(program);
7476 ASSERT(programObject);
7477 programObject->setUniform2uiv(location, count, value);
7478 }
7479
programUniform3uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7480 void Context::programUniform3uiv(ShaderProgramID program,
7481 UniformLocation location,
7482 GLsizei count,
7483 const GLuint *value)
7484 {
7485 Program *programObject = getProgramResolveLink(program);
7486 ASSERT(programObject);
7487 programObject->setUniform3uiv(location, count, value);
7488 }
7489
programUniform4uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7490 void Context::programUniform4uiv(ShaderProgramID program,
7491 UniformLocation location,
7492 GLsizei count,
7493 const GLuint *value)
7494 {
7495 Program *programObject = getProgramResolveLink(program);
7496 ASSERT(programObject);
7497 programObject->setUniform4uiv(location, count, value);
7498 }
7499
programUniform1fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7500 void Context::programUniform1fv(ShaderProgramID program,
7501 UniformLocation location,
7502 GLsizei count,
7503 const GLfloat *value)
7504 {
7505 Program *programObject = getProgramResolveLink(program);
7506 ASSERT(programObject);
7507 programObject->setUniform1fv(location, count, value);
7508 }
7509
programUniform2fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7510 void Context::programUniform2fv(ShaderProgramID program,
7511 UniformLocation location,
7512 GLsizei count,
7513 const GLfloat *value)
7514 {
7515 Program *programObject = getProgramResolveLink(program);
7516 ASSERT(programObject);
7517 programObject->setUniform2fv(location, count, value);
7518 }
7519
programUniform3fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7520 void Context::programUniform3fv(ShaderProgramID program,
7521 UniformLocation location,
7522 GLsizei count,
7523 const GLfloat *value)
7524 {
7525 Program *programObject = getProgramResolveLink(program);
7526 ASSERT(programObject);
7527 programObject->setUniform3fv(location, count, value);
7528 }
7529
programUniform4fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7530 void Context::programUniform4fv(ShaderProgramID program,
7531 UniformLocation location,
7532 GLsizei count,
7533 const GLfloat *value)
7534 {
7535 Program *programObject = getProgramResolveLink(program);
7536 ASSERT(programObject);
7537 programObject->setUniform4fv(location, count, value);
7538 }
7539
programUniformMatrix2fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7540 void Context::programUniformMatrix2fv(ShaderProgramID program,
7541 UniformLocation location,
7542 GLsizei count,
7543 GLboolean transpose,
7544 const GLfloat *value)
7545 {
7546 Program *programObject = getProgramResolveLink(program);
7547 ASSERT(programObject);
7548 programObject->setUniformMatrix2fv(location, count, transpose, value);
7549 }
7550
programUniformMatrix3fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7551 void Context::programUniformMatrix3fv(ShaderProgramID program,
7552 UniformLocation location,
7553 GLsizei count,
7554 GLboolean transpose,
7555 const GLfloat *value)
7556 {
7557 Program *programObject = getProgramResolveLink(program);
7558 ASSERT(programObject);
7559 programObject->setUniformMatrix3fv(location, count, transpose, value);
7560 }
7561
programUniformMatrix4fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7562 void Context::programUniformMatrix4fv(ShaderProgramID program,
7563 UniformLocation location,
7564 GLsizei count,
7565 GLboolean transpose,
7566 const GLfloat *value)
7567 {
7568 Program *programObject = getProgramResolveLink(program);
7569 ASSERT(programObject);
7570 programObject->setUniformMatrix4fv(location, count, transpose, value);
7571 }
7572
programUniformMatrix2x3fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7573 void Context::programUniformMatrix2x3fv(ShaderProgramID program,
7574 UniformLocation location,
7575 GLsizei count,
7576 GLboolean transpose,
7577 const GLfloat *value)
7578 {
7579 Program *programObject = getProgramResolveLink(program);
7580 ASSERT(programObject);
7581 programObject->setUniformMatrix2x3fv(location, count, transpose, value);
7582 }
7583
programUniformMatrix3x2fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7584 void Context::programUniformMatrix3x2fv(ShaderProgramID program,
7585 UniformLocation location,
7586 GLsizei count,
7587 GLboolean transpose,
7588 const GLfloat *value)
7589 {
7590 Program *programObject = getProgramResolveLink(program);
7591 ASSERT(programObject);
7592 programObject->setUniformMatrix3x2fv(location, count, transpose, value);
7593 }
7594
programUniformMatrix2x4fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7595 void Context::programUniformMatrix2x4fv(ShaderProgramID program,
7596 UniformLocation location,
7597 GLsizei count,
7598 GLboolean transpose,
7599 const GLfloat *value)
7600 {
7601 Program *programObject = getProgramResolveLink(program);
7602 ASSERT(programObject);
7603 programObject->setUniformMatrix2x4fv(location, count, transpose, value);
7604 }
7605
programUniformMatrix4x2fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7606 void Context::programUniformMatrix4x2fv(ShaderProgramID program,
7607 UniformLocation location,
7608 GLsizei count,
7609 GLboolean transpose,
7610 const GLfloat *value)
7611 {
7612 Program *programObject = getProgramResolveLink(program);
7613 ASSERT(programObject);
7614 programObject->setUniformMatrix4x2fv(location, count, transpose, value);
7615 }
7616
programUniformMatrix3x4fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7617 void Context::programUniformMatrix3x4fv(ShaderProgramID program,
7618 UniformLocation location,
7619 GLsizei count,
7620 GLboolean transpose,
7621 const GLfloat *value)
7622 {
7623 Program *programObject = getProgramResolveLink(program);
7624 ASSERT(programObject);
7625 programObject->setUniformMatrix3x4fv(location, count, transpose, value);
7626 }
7627
programUniformMatrix4x3fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7628 void Context::programUniformMatrix4x3fv(ShaderProgramID program,
7629 UniformLocation location,
7630 GLsizei count,
7631 GLboolean transpose,
7632 const GLfloat *value)
7633 {
7634 Program *programObject = getProgramResolveLink(program);
7635 ASSERT(programObject);
7636 programObject->setUniformMatrix4x3fv(location, count, transpose, value);
7637 }
7638
isCurrentTransformFeedback(const TransformFeedback * tf) const7639 bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
7640 {
7641 return mState.isCurrentTransformFeedback(tf);
7642 }
7643
genProgramPipelines(GLsizei count,ProgramPipelineID * pipelines)7644 void Context::genProgramPipelines(GLsizei count, ProgramPipelineID *pipelines)
7645 {
7646 for (int i = 0; i < count; i++)
7647 {
7648 pipelines[i] = createProgramPipeline();
7649 }
7650 }
7651
deleteProgramPipelines(GLsizei count,const ProgramPipelineID * pipelines)7652 void Context::deleteProgramPipelines(GLsizei count, const ProgramPipelineID *pipelines)
7653 {
7654 for (int i = 0; i < count; i++)
7655 {
7656 if (pipelines[i].value != 0)
7657 {
7658 deleteProgramPipeline(pipelines[i]);
7659 }
7660 }
7661 }
7662
isProgramPipeline(ProgramPipelineID pipeline) const7663 GLboolean Context::isProgramPipeline(ProgramPipelineID pipeline) const
7664 {
7665 if (pipeline.value == 0)
7666 {
7667 return GL_FALSE;
7668 }
7669
7670 if (getProgramPipeline(pipeline))
7671 {
7672 return GL_TRUE;
7673 }
7674
7675 return GL_FALSE;
7676 }
7677
finishFenceNV(FenceNVID fence)7678 void Context::finishFenceNV(FenceNVID fence)
7679 {
7680 FenceNV *fenceObject = getFenceNV(fence);
7681
7682 ASSERT(fenceObject && fenceObject->isSet());
7683 ANGLE_CONTEXT_TRY(fenceObject->finish(this));
7684 }
7685
getFenceivNV(FenceNVID fence,GLenum pname,GLint * params)7686 void Context::getFenceivNV(FenceNVID fence, GLenum pname, GLint *params)
7687 {
7688 FenceNV *fenceObject = getFenceNV(fence);
7689
7690 ASSERT(fenceObject && fenceObject->isSet());
7691
7692 switch (pname)
7693 {
7694 case GL_FENCE_STATUS_NV:
7695 {
7696 // GL_NV_fence spec:
7697 // Once the status of a fence has been finished (via FinishFenceNV) or tested and
7698 // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the
7699 // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
7700 GLboolean status = GL_TRUE;
7701 if (fenceObject->getStatus() != GL_TRUE)
7702 {
7703 ANGLE_CONTEXT_TRY(fenceObject->test(this, &status));
7704 }
7705 *params = status;
7706 break;
7707 }
7708
7709 case GL_FENCE_CONDITION_NV:
7710 {
7711 *params = static_cast<GLint>(fenceObject->getCondition());
7712 break;
7713 }
7714
7715 default:
7716 UNREACHABLE();
7717 }
7718 }
7719
getTranslatedShaderSource(ShaderProgramID shader,GLsizei bufsize,GLsizei * length,GLchar * source)7720 void Context::getTranslatedShaderSource(ShaderProgramID shader,
7721 GLsizei bufsize,
7722 GLsizei *length,
7723 GLchar *source)
7724 {
7725 Shader *shaderObject = getShader(shader);
7726 ASSERT(shaderObject);
7727 shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
7728 }
7729
getnUniformfv(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLfloat * params)7730 void Context::getnUniformfv(ShaderProgramID program,
7731 UniformLocation location,
7732 GLsizei bufSize,
7733 GLfloat *params)
7734 {
7735 Program *programObject = getProgramResolveLink(program);
7736 ASSERT(programObject);
7737
7738 programObject->getUniformfv(this, location, params);
7739 }
7740
getnUniformfvRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLfloat * params)7741 void Context::getnUniformfvRobust(ShaderProgramID program,
7742 UniformLocation location,
7743 GLsizei bufSize,
7744 GLsizei *length,
7745 GLfloat *params)
7746 {
7747 UNIMPLEMENTED();
7748 }
7749
getnUniformiv(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLint * params)7750 void Context::getnUniformiv(ShaderProgramID program,
7751 UniformLocation location,
7752 GLsizei bufSize,
7753 GLint *params)
7754 {
7755 Program *programObject = getProgramResolveLink(program);
7756 ASSERT(programObject);
7757
7758 programObject->getUniformiv(this, location, params);
7759 }
7760
getnUniformivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLint * params)7761 void Context::getnUniformivRobust(ShaderProgramID program,
7762 UniformLocation location,
7763 GLsizei bufSize,
7764 GLsizei *length,
7765 GLint *params)
7766 {
7767 UNIMPLEMENTED();
7768 }
7769
getnUniformuivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLuint * params)7770 void Context::getnUniformuivRobust(ShaderProgramID program,
7771 UniformLocation location,
7772 GLsizei bufSize,
7773 GLsizei *length,
7774 GLuint *params)
7775 {
7776 UNIMPLEMENTED();
7777 }
7778
isFenceNV(FenceNVID fence) const7779 GLboolean Context::isFenceNV(FenceNVID fence) const
7780 {
7781 FenceNV *fenceObject = getFenceNV(fence);
7782
7783 if (fenceObject == nullptr)
7784 {
7785 return GL_FALSE;
7786 }
7787
7788 // GL_NV_fence spec:
7789 // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an
7790 // existing fence.
7791 return fenceObject->isSet();
7792 }
7793
readnPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,void * data)7794 void Context::readnPixels(GLint x,
7795 GLint y,
7796 GLsizei width,
7797 GLsizei height,
7798 GLenum format,
7799 GLenum type,
7800 GLsizei bufSize,
7801 void *data)
7802 {
7803 return readPixels(x, y, width, height, format, type, data);
7804 }
7805
setFenceNV(FenceNVID fence,GLenum condition)7806 void Context::setFenceNV(FenceNVID fence, GLenum condition)
7807 {
7808 ASSERT(condition == GL_ALL_COMPLETED_NV);
7809
7810 FenceNV *fenceObject = getFenceNV(fence);
7811 ASSERT(fenceObject != nullptr);
7812 ANGLE_CONTEXT_TRY(fenceObject->set(this, condition));
7813 }
7814
testFenceNV(FenceNVID fence)7815 GLboolean Context::testFenceNV(FenceNVID fence)
7816 {
7817 FenceNV *fenceObject = getFenceNV(fence);
7818
7819 ASSERT(fenceObject != nullptr);
7820 ASSERT(fenceObject->isSet() == GL_TRUE);
7821
7822 GLboolean result = GL_TRUE;
7823 if (fenceObject->test(this, &result) == angle::Result::Stop)
7824 {
7825 return GL_TRUE;
7826 }
7827
7828 return result;
7829 }
7830
deleteMemoryObjects(GLsizei n,const MemoryObjectID * memoryObjects)7831 void Context::deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjects)
7832 {
7833 for (int i = 0; i < n; i++)
7834 {
7835 deleteMemoryObject(memoryObjects[i]);
7836 }
7837 }
7838
isMemoryObject(MemoryObjectID memoryObject) const7839 GLboolean Context::isMemoryObject(MemoryObjectID memoryObject) const
7840 {
7841 if (memoryObject.value == 0)
7842 {
7843 return GL_FALSE;
7844 }
7845
7846 return ConvertToGLBoolean(getMemoryObject(memoryObject));
7847 }
7848
createMemoryObjects(GLsizei n,MemoryObjectID * memoryObjects)7849 void Context::createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjects)
7850 {
7851 for (int i = 0; i < n; i++)
7852 {
7853 memoryObjects[i] = createMemoryObject();
7854 }
7855 }
7856
memoryObjectParameteriv(MemoryObjectID memory,GLenum pname,const GLint * params)7857 void Context::memoryObjectParameteriv(MemoryObjectID memory, GLenum pname, const GLint *params)
7858 {
7859 MemoryObject *memoryObject = getMemoryObject(memory);
7860 ASSERT(memoryObject);
7861 ANGLE_CONTEXT_TRY(SetMemoryObjectParameteriv(this, memoryObject, pname, params));
7862 }
7863
getMemoryObjectParameteriv(MemoryObjectID memory,GLenum pname,GLint * params)7864 void Context::getMemoryObjectParameteriv(MemoryObjectID memory, GLenum pname, GLint *params)
7865 {
7866 const MemoryObject *memoryObject = getMemoryObject(memory);
7867 ASSERT(memoryObject);
7868 QueryMemoryObjectParameteriv(memoryObject, pname, params);
7869 }
7870
texStorageMem2D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,MemoryObjectID memory,GLuint64 offset)7871 void Context::texStorageMem2D(TextureType target,
7872 GLsizei levels,
7873 GLenum internalFormat,
7874 GLsizei width,
7875 GLsizei height,
7876 MemoryObjectID memory,
7877 GLuint64 offset)
7878 {
7879 MemoryObject *memoryObject = getMemoryObject(memory);
7880 ASSERT(memoryObject);
7881 Extents size(width, height, 1);
7882 Texture *texture = getTextureByType(target);
7883 ANGLE_CONTEXT_TRY(texture->setStorageExternalMemory(this, target, levels, internalFormat, size,
7884 memoryObject, offset));
7885 }
7886
texStorageMem2DMultisample(TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)7887 void Context::texStorageMem2DMultisample(TextureType target,
7888 GLsizei samples,
7889 GLenum internalFormat,
7890 GLsizei width,
7891 GLsizei height,
7892 GLboolean fixedSampleLocations,
7893 MemoryObjectID memory,
7894 GLuint64 offset)
7895 {
7896 UNIMPLEMENTED();
7897 }
7898
texStorageMem3D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,MemoryObjectID memory,GLuint64 offset)7899 void Context::texStorageMem3D(TextureType target,
7900 GLsizei levels,
7901 GLenum internalFormat,
7902 GLsizei width,
7903 GLsizei height,
7904 GLsizei depth,
7905 MemoryObjectID memory,
7906 GLuint64 offset)
7907 {
7908 UNIMPLEMENTED();
7909 }
7910
texStorageMem3DMultisample(TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)7911 void Context::texStorageMem3DMultisample(TextureType target,
7912 GLsizei samples,
7913 GLenum internalFormat,
7914 GLsizei width,
7915 GLsizei height,
7916 GLsizei depth,
7917 GLboolean fixedSampleLocations,
7918 MemoryObjectID memory,
7919 GLuint64 offset)
7920 {
7921 UNIMPLEMENTED();
7922 }
7923
bufferStorageMem(TextureType target,GLsizeiptr size,MemoryObjectID memory,GLuint64 offset)7924 void Context::bufferStorageMem(TextureType target,
7925 GLsizeiptr size,
7926 MemoryObjectID memory,
7927 GLuint64 offset)
7928 {
7929 UNIMPLEMENTED();
7930 }
7931
importMemoryFd(MemoryObjectID memory,GLuint64 size,HandleType handleType,GLint fd)7932 void Context::importMemoryFd(MemoryObjectID memory, GLuint64 size, HandleType handleType, GLint fd)
7933 {
7934 MemoryObject *memoryObject = getMemoryObject(memory);
7935 ASSERT(memoryObject != nullptr);
7936 ANGLE_CONTEXT_TRY(memoryObject->importFd(this, size, handleType, fd));
7937 }
7938
importMemoryZirconHandle(MemoryObjectID memory,GLuint64 size,HandleType handleType,GLuint handle)7939 void Context::importMemoryZirconHandle(MemoryObjectID memory,
7940 GLuint64 size,
7941 HandleType handleType,
7942 GLuint handle)
7943 {
7944 MemoryObject *memoryObject = getMemoryObject(memory);
7945 ASSERT(memoryObject != nullptr);
7946 ANGLE_CONTEXT_TRY(memoryObject->importZirconHandle(this, size, handleType, handle));
7947 }
7948
genSemaphores(GLsizei n,SemaphoreID * semaphores)7949 void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores)
7950 {
7951 for (int i = 0; i < n; i++)
7952 {
7953 semaphores[i] = createSemaphore();
7954 }
7955 }
7956
deleteSemaphores(GLsizei n,const SemaphoreID * semaphores)7957 void Context::deleteSemaphores(GLsizei n, const SemaphoreID *semaphores)
7958 {
7959 for (int i = 0; i < n; i++)
7960 {
7961 deleteSemaphore(semaphores[i]);
7962 }
7963 }
7964
isSemaphore(SemaphoreID semaphore) const7965 GLboolean Context::isSemaphore(SemaphoreID semaphore) const
7966 {
7967 if (semaphore.value == 0)
7968 {
7969 return GL_FALSE;
7970 }
7971
7972 return ConvertToGLBoolean(getSemaphore(semaphore));
7973 }
7974
semaphoreParameterui64v(SemaphoreID semaphore,GLenum pname,const GLuint64 * params)7975 void Context::semaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, const GLuint64 *params)
7976 {
7977 UNIMPLEMENTED();
7978 }
7979
getSemaphoreParameterui64v(SemaphoreID semaphore,GLenum pname,GLuint64 * params)7980 void Context::getSemaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, GLuint64 *params)
7981 {
7982 UNIMPLEMENTED();
7983 }
7984
waitSemaphore(SemaphoreID semaphoreHandle,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * srcLayouts)7985 void Context::waitSemaphore(SemaphoreID semaphoreHandle,
7986 GLuint numBufferBarriers,
7987 const BufferID *buffers,
7988 GLuint numTextureBarriers,
7989 const TextureID *textures,
7990 const GLenum *srcLayouts)
7991 {
7992 Semaphore *semaphore = getSemaphore(semaphoreHandle);
7993 ASSERT(semaphore);
7994
7995 BufferBarrierVector bufferBarriers(numBufferBarriers);
7996 for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
7997 {
7998 bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
7999 }
8000
8001 TextureBarrierVector textureBarriers(numTextureBarriers);
8002 for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
8003 {
8004 textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
8005 textureBarriers[textureBarrierIdx].layout = srcLayouts[textureBarrierIdx];
8006 }
8007
8008 ANGLE_CONTEXT_TRY(semaphore->wait(this, bufferBarriers, textureBarriers));
8009 }
8010
signalSemaphore(SemaphoreID semaphoreHandle,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * dstLayouts)8011 void Context::signalSemaphore(SemaphoreID semaphoreHandle,
8012 GLuint numBufferBarriers,
8013 const BufferID *buffers,
8014 GLuint numTextureBarriers,
8015 const TextureID *textures,
8016 const GLenum *dstLayouts)
8017 {
8018 Semaphore *semaphore = getSemaphore(semaphoreHandle);
8019 ASSERT(semaphore);
8020
8021 BufferBarrierVector bufferBarriers(numBufferBarriers);
8022 for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
8023 {
8024 bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
8025 }
8026
8027 TextureBarrierVector textureBarriers(numTextureBarriers);
8028 for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
8029 {
8030 textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
8031 textureBarriers[textureBarrierIdx].layout = dstLayouts[textureBarrierIdx];
8032 }
8033
8034 ANGLE_CONTEXT_TRY(semaphore->signal(this, bufferBarriers, textureBarriers));
8035 }
8036
importSemaphoreFd(SemaphoreID semaphore,HandleType handleType,GLint fd)8037 void Context::importSemaphoreFd(SemaphoreID semaphore, HandleType handleType, GLint fd)
8038 {
8039 Semaphore *semaphoreObject = getSemaphore(semaphore);
8040 ASSERT(semaphoreObject != nullptr);
8041 ANGLE_CONTEXT_TRY(semaphoreObject->importFd(this, handleType, fd));
8042 }
8043
importSemaphoreZirconHandle(SemaphoreID semaphore,HandleType handleType,GLuint handle)8044 void Context::importSemaphoreZirconHandle(SemaphoreID semaphore,
8045 HandleType handleType,
8046 GLuint handle)
8047 {
8048 Semaphore *semaphoreObject = getSemaphore(semaphore);
8049 ASSERT(semaphoreObject != nullptr);
8050 ANGLE_CONTEXT_TRY(semaphoreObject->importZirconHandle(this, handleType, handle));
8051 }
8052
eGLImageTargetTexture2D(TextureType target,GLeglImageOES image)8053 void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image)
8054 {
8055 Texture *texture = getTextureByType(target);
8056 egl::Image *imageObject = static_cast<egl::Image *>(image);
8057 ANGLE_CONTEXT_TRY(texture->setEGLImageTarget(this, target, imageObject));
8058 }
8059
eGLImageTargetRenderbufferStorage(GLenum target,GLeglImageOES image)8060 void Context::eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image)
8061 {
8062 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
8063 egl::Image *imageObject = static_cast<egl::Image *>(image);
8064 ANGLE_CONTEXT_TRY(renderbuffer->setStorageEGLImageTarget(this, imageObject));
8065 }
8066
texStorage1D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)8067 void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
8068 {
8069 UNIMPLEMENTED();
8070 }
8071
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams) const8072 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
8073 {
8074 return GetQueryParameterInfo(mState, pname, type, numParams);
8075 }
8076
getIndexedQueryParameterInfo(GLenum target,GLenum * type,unsigned int * numParams) const8077 bool Context::getIndexedQueryParameterInfo(GLenum target,
8078 GLenum *type,
8079 unsigned int *numParams) const
8080 {
8081 if (getClientVersion() < Version(3, 0))
8082 {
8083 return false;
8084 }
8085
8086 switch (target)
8087 {
8088 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
8089 case GL_UNIFORM_BUFFER_BINDING:
8090 {
8091 *type = GL_INT;
8092 *numParams = 1;
8093 return true;
8094 }
8095 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
8096 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
8097 case GL_UNIFORM_BUFFER_START:
8098 case GL_UNIFORM_BUFFER_SIZE:
8099 {
8100 *type = GL_INT_64_ANGLEX;
8101 *numParams = 1;
8102 return true;
8103 }
8104 }
8105
8106 if (mSupportedExtensions.drawBuffersIndexedAny())
8107 {
8108 switch (target)
8109 {
8110 case GL_BLEND_SRC_RGB:
8111 case GL_BLEND_SRC_ALPHA:
8112 case GL_BLEND_DST_RGB:
8113 case GL_BLEND_DST_ALPHA:
8114 case GL_BLEND_EQUATION_RGB:
8115 case GL_BLEND_EQUATION_ALPHA:
8116 {
8117 *type = GL_INT;
8118 *numParams = 1;
8119 return true;
8120 }
8121 case GL_COLOR_WRITEMASK:
8122 {
8123 *type = GL_BOOL;
8124 *numParams = 4;
8125 return true;
8126 }
8127 }
8128 }
8129
8130 if (getClientVersion() < Version(3, 1))
8131 {
8132 return false;
8133 }
8134
8135 switch (target)
8136 {
8137 case GL_IMAGE_BINDING_LAYERED:
8138 {
8139 *type = GL_BOOL;
8140 *numParams = 1;
8141 return true;
8142 }
8143 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
8144 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
8145 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
8146 case GL_SHADER_STORAGE_BUFFER_BINDING:
8147 case GL_VERTEX_BINDING_BUFFER:
8148 case GL_VERTEX_BINDING_DIVISOR:
8149 case GL_VERTEX_BINDING_OFFSET:
8150 case GL_VERTEX_BINDING_STRIDE:
8151 case GL_SAMPLE_MASK_VALUE:
8152 case GL_IMAGE_BINDING_NAME:
8153 case GL_IMAGE_BINDING_LEVEL:
8154 case GL_IMAGE_BINDING_LAYER:
8155 case GL_IMAGE_BINDING_ACCESS:
8156 case GL_IMAGE_BINDING_FORMAT:
8157 {
8158 *type = GL_INT;
8159 *numParams = 1;
8160 return true;
8161 }
8162 case GL_ATOMIC_COUNTER_BUFFER_START:
8163 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
8164 case GL_SHADER_STORAGE_BUFFER_START:
8165 case GL_SHADER_STORAGE_BUFFER_SIZE:
8166 {
8167 *type = GL_INT_64_ANGLEX;
8168 *numParams = 1;
8169 return true;
8170 }
8171 }
8172
8173 return false;
8174 }
8175
getProgramNoResolveLink(ShaderProgramID handle) const8176 Program *Context::getProgramNoResolveLink(ShaderProgramID handle) const
8177 {
8178 return mState.mShaderProgramManager->getProgram(handle);
8179 }
8180
getShader(ShaderProgramID handle) const8181 Shader *Context::getShader(ShaderProgramID handle) const
8182 {
8183 return mState.mShaderProgramManager->getShader(handle);
8184 }
8185
getFrontendFeatures() const8186 const angle::FrontendFeatures &Context::getFrontendFeatures() const
8187 {
8188 return mDisplay->getFrontendFeatures();
8189 }
8190
isRenderbufferGenerated(RenderbufferID renderbuffer) const8191 bool Context::isRenderbufferGenerated(RenderbufferID renderbuffer) const
8192 {
8193 return mState.mRenderbufferManager->isHandleGenerated(renderbuffer);
8194 }
8195
isFramebufferGenerated(FramebufferID framebuffer) const8196 bool Context::isFramebufferGenerated(FramebufferID framebuffer) const
8197 {
8198 return mState.mFramebufferManager->isHandleGenerated(framebuffer);
8199 }
8200
isProgramPipelineGenerated(ProgramPipelineID pipeline) const8201 bool Context::isProgramPipelineGenerated(ProgramPipelineID pipeline) const
8202 {
8203 return mState.mProgramPipelineManager->isHandleGenerated(pipeline);
8204 }
8205
usingDisplayTextureShareGroup() const8206 bool Context::usingDisplayTextureShareGroup() const
8207 {
8208 return mDisplayTextureShareGroup;
8209 }
8210
getConvertedRenderbufferFormat(GLenum internalformat) const8211 GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const
8212 {
8213 if (mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 &&
8214 internalformat == GL_DEPTH_STENCIL)
8215 {
8216 return GL_DEPTH24_STENCIL8;
8217 }
8218 if (getClientType() == EGL_OPENGL_API && internalformat == GL_DEPTH_COMPONENT)
8219 {
8220 return GL_DEPTH_COMPONENT24;
8221 }
8222 return internalformat;
8223 }
8224
maxShaderCompilerThreads(GLuint count)8225 void Context::maxShaderCompilerThreads(GLuint count)
8226 {
8227 GLuint oldCount = mState.getMaxShaderCompilerThreads();
8228 mState.setMaxShaderCompilerThreads(count);
8229 // A count of zero specifies a request for no parallel compiling or linking.
8230 if ((oldCount == 0 || count == 0) && (oldCount != 0 || count != 0))
8231 {
8232 mThreadPool = angle::WorkerThreadPool::Create(count > 0);
8233 }
8234 mThreadPool->setMaxThreads(count);
8235 mImplementation->setMaxShaderCompilerThreads(count);
8236 }
8237
isGLES1() const8238 bool Context::isGLES1() const
8239 {
8240 return mState.getClientVersion() < Version(2, 0);
8241 }
8242
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)8243 void Context::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
8244 {
8245 switch (index)
8246 {
8247 case kVertexArraySubjectIndex:
8248 switch (message)
8249 {
8250 case angle::SubjectMessage::ContentsChanged:
8251 mState.setObjectDirty(GL_VERTEX_ARRAY);
8252 mStateCache.onVertexArrayBufferContentsChange(this);
8253 break;
8254 case angle::SubjectMessage::SubjectMapped:
8255 case angle::SubjectMessage::SubjectUnmapped:
8256 case angle::SubjectMessage::BindingChanged:
8257 mStateCache.onVertexArrayBufferStateChange(this);
8258 break;
8259 default:
8260 break;
8261 }
8262 break;
8263
8264 case kReadFramebufferSubjectIndex:
8265 ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged);
8266 mState.setReadFramebufferDirty();
8267 break;
8268
8269 case kDrawFramebufferSubjectIndex:
8270 ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged);
8271 mState.setDrawFramebufferDirty();
8272 mStateCache.onDrawFramebufferChange(this);
8273 break;
8274
8275 default:
8276 if (index < kTextureMaxSubjectIndex)
8277 {
8278 if (message != angle::SubjectMessage::ContentsChanged &&
8279 message != angle::SubjectMessage::BindingChanged)
8280 {
8281 mState.onActiveTextureStateChange(this, index);
8282 mStateCache.onActiveTextureChange(this);
8283 }
8284 }
8285 else if (index < kImageMaxSubjectIndex)
8286 {
8287 mState.onImageStateChange(this, index - kImage0SubjectIndex);
8288 if (message == angle::SubjectMessage::ContentsChanged)
8289 {
8290 mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_IMAGE_BINDINGS);
8291 }
8292 }
8293 else if (index < kUniformBufferMaxSubjectIndex)
8294 {
8295 mState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
8296 mStateCache.onUniformBufferStateChange(this);
8297 }
8298 else
8299 {
8300 ASSERT(index < kSamplerMaxSubjectIndex);
8301 mState.setSamplerDirty(index - kSampler0SubjectIndex);
8302 mState.onActiveTextureStateChange(this, index - kSampler0SubjectIndex);
8303 }
8304 break;
8305 }
8306 }
8307
onProgramLink(Program * programObject)8308 angle::Result Context::onProgramLink(Program *programObject)
8309 {
8310 // Don't parallel link a program which is active in any GL contexts. With this assumption, we
8311 // don't need to worry that:
8312 // 1. Draw calls after link use the new executable code or the old one depending on the link
8313 // result.
8314 // 2. When a backend program, e.g., ProgramD3D is linking, other backend classes like
8315 // StateManager11, Renderer11, etc., may have a chance to make unexpected calls to
8316 // ProgramD3D.
8317 if (programObject->isInUse())
8318 {
8319 programObject->resolveLink(this);
8320 if (programObject->isLinked())
8321 {
8322 ANGLE_TRY(mState.onProgramExecutableChange(this, programObject));
8323 }
8324 mStateCache.onProgramExecutableChange(this);
8325 }
8326
8327 // TODO(http://anglebug.com/4559): Use the Subject/Observer pattern for
8328 // Programs in PPOs so we can remove this.
8329 // Need to mark any PPOs that this Program is bound to as dirty
8330 bool foundPipeline = false;
8331 for (ResourceMap<ProgramPipeline, ProgramPipelineID>::Iterator ppoIterator =
8332 mState.mProgramPipelineManager->begin();
8333 ppoIterator != mState.mProgramPipelineManager->end(); ++ppoIterator)
8334 {
8335 ProgramPipeline *pipeline = ppoIterator->second;
8336 pipeline->setDirtyBit(ProgramPipeline::DirtyBitType::DIRTY_BIT_PROGRAM_STAGE);
8337 foundPipeline = true;
8338 }
8339 // Also need to make sure the PPO dirty bits get handled by marking the PPO
8340 // objects dirty.
8341 if (foundPipeline)
8342 {
8343 mState.mDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
8344 }
8345
8346 return angle::Result::Continue;
8347 }
8348
setDefaultFramebuffer(egl::Surface * drawSurface,egl::Surface * readSurface)8349 egl::Error Context::setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface)
8350 {
8351 ASSERT(mCurrentDrawSurface == nullptr);
8352 ASSERT(mCurrentReadSurface == nullptr);
8353
8354 Framebuffer *newDefaultFramebuffer = nullptr;
8355
8356 mCurrentDrawSurface = drawSurface;
8357 mCurrentReadSurface = readSurface;
8358
8359 if (drawSurface != nullptr)
8360 {
8361 ANGLE_TRY(drawSurface->makeCurrent(this));
8362 newDefaultFramebuffer = drawSurface->createDefaultFramebuffer(this, readSurface);
8363 }
8364 else
8365 {
8366 newDefaultFramebuffer = new Framebuffer(this, mImplementation.get(), readSurface);
8367 }
8368 ASSERT(newDefaultFramebuffer);
8369
8370 if (readSurface && (drawSurface != readSurface))
8371 {
8372 ANGLE_TRY(readSurface->makeCurrent(this));
8373 }
8374
8375 // Update default framebuffer, the binding of the previous default
8376 // framebuffer (or lack of) will have a nullptr.
8377 mState.mFramebufferManager->setDefaultFramebuffer(newDefaultFramebuffer);
8378 if (mState.getDrawFramebuffer() == nullptr)
8379 {
8380 bindDrawFramebuffer(newDefaultFramebuffer->id());
8381 }
8382 if (mState.getReadFramebuffer() == nullptr)
8383 {
8384 bindReadFramebuffer(newDefaultFramebuffer->id());
8385 }
8386
8387 return egl::NoError();
8388 }
8389
unsetDefaultFramebuffer()8390 egl::Error Context::unsetDefaultFramebuffer()
8391 {
8392 gl::Framebuffer *defaultFramebuffer =
8393 mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
8394
8395 // Remove the default framebuffer
8396 if (mState.getReadFramebuffer() == defaultFramebuffer)
8397 {
8398 mState.setReadFramebufferBinding(nullptr);
8399 mReadFramebufferObserverBinding.bind(nullptr);
8400 }
8401
8402 if (mState.getDrawFramebuffer() == defaultFramebuffer)
8403 {
8404 mState.setDrawFramebufferBinding(nullptr);
8405 mDrawFramebufferObserverBinding.bind(nullptr);
8406 }
8407
8408 if (defaultFramebuffer)
8409 {
8410 defaultFramebuffer->onDestroy(this);
8411 delete defaultFramebuffer;
8412 }
8413
8414 mState.mFramebufferManager->setDefaultFramebuffer(nullptr);
8415
8416 // Always unset the current surface, even if setIsCurrent fails.
8417 egl::Surface *drawSurface = mCurrentDrawSurface;
8418 egl::Surface *readSurface = mCurrentReadSurface;
8419 mCurrentDrawSurface = nullptr;
8420 mCurrentReadSurface = nullptr;
8421 if (drawSurface)
8422 {
8423 ANGLE_TRY(drawSurface->unMakeCurrent(this));
8424 }
8425 if (drawSurface != readSurface)
8426 {
8427 ANGLE_TRY(readSurface->unMakeCurrent(this));
8428 }
8429
8430 return egl::NoError();
8431 }
8432
onPostSwap() const8433 void Context::onPostSwap() const
8434 {
8435 // Dump frame capture if enabled.
8436 mFrameCapture->onEndFrame(this);
8437 }
8438
getTexImage(TextureTarget target,GLint level,GLenum format,GLenum type,void * pixels)8439 void Context::getTexImage(TextureTarget target,
8440 GLint level,
8441 GLenum format,
8442 GLenum type,
8443 void *pixels)
8444 {
8445 Texture *texture = getTextureByTarget(target);
8446 Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
8447 ANGLE_CONTEXT_TRY(texture->getTexImage(this, mState.getPackState(), packBuffer, target, level,
8448 format, type, pixels));
8449 }
8450
getRenderbufferImage(GLenum target,GLenum format,GLenum type,void * pixels)8451 void Context::getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels)
8452 {
8453 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
8454 Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
8455 ANGLE_CONTEXT_TRY(renderbuffer->getRenderbufferImage(this, mState.getPackState(), packBuffer,
8456 format, type, pixels));
8457 }
8458
8459 // ErrorSet implementation.
ErrorSet(Context * context)8460 ErrorSet::ErrorSet(Context *context) : mContext(context) {}
8461
8462 ErrorSet::~ErrorSet() = default;
8463
handleError(GLenum errorCode,const char * message,const char * file,const char * function,unsigned int line)8464 void ErrorSet::handleError(GLenum errorCode,
8465 const char *message,
8466 const char *file,
8467 const char *function,
8468 unsigned int line)
8469 {
8470 if (errorCode == GL_OUT_OF_MEMORY &&
8471 mContext->getGraphicsResetStrategy() == GL_LOSE_CONTEXT_ON_RESET_EXT &&
8472 mContext->getDisplay()->getFrontendFeatures().loseContextOnOutOfMemory.enabled)
8473 {
8474 mContext->markContextLost(GraphicsResetStatus::UnknownContextReset);
8475 }
8476
8477 std::stringstream errorStream;
8478 errorStream << "Error: " << gl::FmtHex(errorCode) << ", in " << file << ", " << function << ":"
8479 << line << ". " << message;
8480
8481 std::string formattedMessage = errorStream.str();
8482
8483 // Process the error, but log it with WARN severity so it shows up in logs.
8484 ASSERT(errorCode != GL_NO_ERROR);
8485 mErrors.insert(errorCode);
8486
8487 mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
8488 errorCode, GL_DEBUG_SEVERITY_HIGH, message,
8489 gl::LOG_WARN);
8490 }
8491
validationError(GLenum errorCode,const char * message)8492 void ErrorSet::validationError(GLenum errorCode, const char *message)
8493 {
8494 ASSERT(errorCode != GL_NO_ERROR);
8495 mErrors.insert(errorCode);
8496
8497 mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
8498 errorCode, GL_DEBUG_SEVERITY_HIGH, message,
8499 gl::LOG_INFO);
8500 }
8501
empty() const8502 bool ErrorSet::empty() const
8503 {
8504 return mErrors.empty();
8505 }
8506
popError()8507 GLenum ErrorSet::popError()
8508 {
8509 ASSERT(!empty());
8510 GLenum error = *mErrors.begin();
8511 mErrors.erase(mErrors.begin());
8512 return error;
8513 }
8514
8515 // StateCache implementation.
StateCache()8516 StateCache::StateCache()
8517 : mCachedHasAnyEnabledClientAttrib(false),
8518 mCachedNonInstancedVertexElementLimit(0),
8519 mCachedInstancedVertexElementLimit(0),
8520 mCachedBasicDrawStatesError(kInvalidPointer),
8521 mCachedBasicDrawElementsError(kInvalidPointer),
8522 mCachedTransformFeedbackActiveUnpaused(false),
8523 mCachedCanDraw(false)
8524 {}
8525
8526 StateCache::~StateCache() = default;
8527
updateVertexElementLimits(Context * context)8528 ANGLE_INLINE void StateCache::updateVertexElementLimits(Context *context)
8529 {
8530 if (context->isBufferAccessValidationEnabled())
8531 {
8532 updateVertexElementLimitsImpl(context);
8533 }
8534 }
8535
initialize(Context * context)8536 void StateCache::initialize(Context *context)
8537 {
8538 updateValidDrawModes(context);
8539 updateValidBindTextureTypes(context);
8540 updateValidDrawElementsTypes(context);
8541 updateBasicDrawStatesError();
8542 updateBasicDrawElementsError();
8543 updateVertexAttribTypesValidation(context);
8544 updateCanDraw(context);
8545 }
8546
updateActiveAttribsMask(Context * context)8547 void StateCache::updateActiveAttribsMask(Context *context)
8548 {
8549 bool isGLES1 = context->isGLES1();
8550 const State &glState = context->getState();
8551
8552 if (!isGLES1 && !glState.getProgramExecutable())
8553 {
8554 mCachedActiveBufferedAttribsMask = AttributesMask();
8555 mCachedActiveClientAttribsMask = AttributesMask();
8556 mCachedActiveDefaultAttribsMask = AttributesMask();
8557 return;
8558 }
8559
8560 AttributesMask activeAttribs =
8561 isGLES1 ? glState.gles1().getActiveAttributesMask()
8562 : glState.getProgramExecutable()->getActiveAttribLocationsMask();
8563
8564 const VertexArray *vao = glState.getVertexArray();
8565 ASSERT(vao);
8566
8567 const AttributesMask &clientAttribs = vao->getClientAttribsMask();
8568 const AttributesMask &enabledAttribs = vao->getEnabledAttributesMask();
8569 const AttributesMask &activeEnabled = activeAttribs & enabledAttribs;
8570
8571 mCachedActiveClientAttribsMask = activeEnabled & clientAttribs;
8572 mCachedActiveBufferedAttribsMask = activeEnabled & ~clientAttribs;
8573 mCachedActiveDefaultAttribsMask = activeAttribs & ~enabledAttribs;
8574 mCachedHasAnyEnabledClientAttrib = (clientAttribs & enabledAttribs).any();
8575 }
8576
updateVertexElementLimitsImpl(Context * context)8577 void StateCache::updateVertexElementLimitsImpl(Context *context)
8578 {
8579 ASSERT(context->isBufferAccessValidationEnabled());
8580
8581 const VertexArray *vao = context->getState().getVertexArray();
8582
8583 mCachedNonInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
8584 mCachedInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
8585
8586 // VAO can be null on Context startup. If we make this computation lazier we could ASSERT.
8587 // If there are no buffered attributes then we should not limit the draw call count.
8588 if (!vao || !mCachedActiveBufferedAttribsMask.any())
8589 {
8590 return;
8591 }
8592
8593 const auto &vertexAttribs = vao->getVertexAttributes();
8594 const auto &vertexBindings = vao->getVertexBindings();
8595
8596 for (size_t attributeIndex : mCachedActiveBufferedAttribsMask)
8597 {
8598 const VertexAttribute &attrib = vertexAttribs[attributeIndex];
8599
8600 const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
8601 ASSERT(context->isGLES1() ||
8602 context->getState().getProgramExecutable()->isAttribLocationActive(attributeIndex));
8603
8604 GLint64 limit = attrib.getCachedElementLimit();
8605 if (binding.getDivisor() > 0)
8606 {
8607 mCachedInstancedVertexElementLimit =
8608 std::min(mCachedInstancedVertexElementLimit, limit);
8609 }
8610 else
8611 {
8612 mCachedNonInstancedVertexElementLimit =
8613 std::min(mCachedNonInstancedVertexElementLimit, limit);
8614 }
8615 }
8616 }
8617
updateBasicDrawStatesError()8618 void StateCache::updateBasicDrawStatesError()
8619 {
8620 mCachedBasicDrawStatesError = kInvalidPointer;
8621 }
8622
updateBasicDrawElementsError()8623 void StateCache::updateBasicDrawElementsError()
8624 {
8625 mCachedBasicDrawElementsError = kInvalidPointer;
8626 }
8627
getBasicDrawStatesErrorImpl(const Context * context) const8628 intptr_t StateCache::getBasicDrawStatesErrorImpl(const Context *context) const
8629 {
8630 ASSERT(mCachedBasicDrawStatesError == kInvalidPointer);
8631 mCachedBasicDrawStatesError = reinterpret_cast<intptr_t>(ValidateDrawStates(context));
8632 return mCachedBasicDrawStatesError;
8633 }
8634
getBasicDrawElementsErrorImpl(const Context * context) const8635 intptr_t StateCache::getBasicDrawElementsErrorImpl(const Context *context) const
8636 {
8637 ASSERT(mCachedBasicDrawElementsError == kInvalidPointer);
8638 mCachedBasicDrawElementsError = reinterpret_cast<intptr_t>(ValidateDrawElementsStates(context));
8639 return mCachedBasicDrawElementsError;
8640 }
8641
onVertexArrayBindingChange(Context * context)8642 void StateCache::onVertexArrayBindingChange(Context *context)
8643 {
8644 updateActiveAttribsMask(context);
8645 updateVertexElementLimits(context);
8646 updateBasicDrawStatesError();
8647 }
8648
onProgramExecutableChange(Context * context)8649 void StateCache::onProgramExecutableChange(Context *context)
8650 {
8651 updateActiveAttribsMask(context);
8652 updateVertexElementLimits(context);
8653 updateBasicDrawStatesError();
8654 updateValidDrawModes(context);
8655 updateActiveShaderStorageBufferIndices(context);
8656 updateCanDraw(context);
8657 }
8658
onVertexArrayFormatChange(Context * context)8659 void StateCache::onVertexArrayFormatChange(Context *context)
8660 {
8661 updateVertexElementLimits(context);
8662 }
8663
onVertexArrayBufferContentsChange(Context * context)8664 void StateCache::onVertexArrayBufferContentsChange(Context *context)
8665 {
8666 updateVertexElementLimits(context);
8667 updateBasicDrawStatesError();
8668 }
8669
onVertexArrayStateChange(Context * context)8670 void StateCache::onVertexArrayStateChange(Context *context)
8671 {
8672 updateActiveAttribsMask(context);
8673 updateVertexElementLimits(context);
8674 updateBasicDrawStatesError();
8675 }
8676
onVertexArrayBufferStateChange(Context * context)8677 void StateCache::onVertexArrayBufferStateChange(Context *context)
8678 {
8679 updateBasicDrawStatesError();
8680 updateBasicDrawElementsError();
8681 }
8682
onGLES1ClientStateChange(Context * context)8683 void StateCache::onGLES1ClientStateChange(Context *context)
8684 {
8685 updateActiveAttribsMask(context);
8686 }
8687
onDrawFramebufferChange(Context * context)8688 void StateCache::onDrawFramebufferChange(Context *context)
8689 {
8690 updateBasicDrawStatesError();
8691 }
8692
onContextCapChange(Context * context)8693 void StateCache::onContextCapChange(Context *context)
8694 {
8695 updateBasicDrawStatesError();
8696 }
8697
onStencilStateChange(Context * context)8698 void StateCache::onStencilStateChange(Context *context)
8699 {
8700 updateBasicDrawStatesError();
8701 }
8702
onDefaultVertexAttributeChange(Context * context)8703 void StateCache::onDefaultVertexAttributeChange(Context *context)
8704 {
8705 updateBasicDrawStatesError();
8706 }
8707
onActiveTextureChange(Context * context)8708 void StateCache::onActiveTextureChange(Context *context)
8709 {
8710 updateBasicDrawStatesError();
8711 }
8712
onQueryChange(Context * context)8713 void StateCache::onQueryChange(Context *context)
8714 {
8715 updateBasicDrawStatesError();
8716 }
8717
onActiveTransformFeedbackChange(Context * context)8718 void StateCache::onActiveTransformFeedbackChange(Context *context)
8719 {
8720 updateTransformFeedbackActiveUnpaused(context);
8721 updateBasicDrawStatesError();
8722 updateBasicDrawElementsError();
8723 updateValidDrawModes(context);
8724 }
8725
onUniformBufferStateChange(Context * context)8726 void StateCache::onUniformBufferStateChange(Context *context)
8727 {
8728 updateBasicDrawStatesError();
8729 }
8730
onColorMaskChange(Context * context)8731 void StateCache::onColorMaskChange(Context *context)
8732 {
8733 updateBasicDrawStatesError();
8734 }
8735
onBlendFuncIndexedChange(Context * context)8736 void StateCache::onBlendFuncIndexedChange(Context *context)
8737 {
8738 updateBasicDrawStatesError();
8739 }
8740
setValidDrawModes(bool pointsOK,bool linesOK,bool trisOK,bool lineAdjOK,bool triAdjOK)8741 void StateCache::setValidDrawModes(bool pointsOK,
8742 bool linesOK,
8743 bool trisOK,
8744 bool lineAdjOK,
8745 bool triAdjOK)
8746 {
8747 mCachedValidDrawModes[PrimitiveMode::Points] = pointsOK;
8748 mCachedValidDrawModes[PrimitiveMode::Lines] = linesOK;
8749 mCachedValidDrawModes[PrimitiveMode::LineStrip] = linesOK;
8750 mCachedValidDrawModes[PrimitiveMode::LineLoop] = linesOK;
8751 mCachedValidDrawModes[PrimitiveMode::Triangles] = trisOK;
8752 mCachedValidDrawModes[PrimitiveMode::TriangleFan] = trisOK;
8753 mCachedValidDrawModes[PrimitiveMode::TriangleStrip] = trisOK;
8754 mCachedValidDrawModes[PrimitiveMode::LinesAdjacency] = lineAdjOK;
8755 mCachedValidDrawModes[PrimitiveMode::LineStripAdjacency] = lineAdjOK;
8756 mCachedValidDrawModes[PrimitiveMode::TrianglesAdjacency] = triAdjOK;
8757 mCachedValidDrawModes[PrimitiveMode::TriangleStripAdjacency] = triAdjOK;
8758 }
8759
updateValidDrawModes(Context * context)8760 void StateCache::updateValidDrawModes(Context *context)
8761 {
8762 const State &state = context->getState();
8763 Program *program = state.getProgram();
8764
8765 if (mCachedTransformFeedbackActiveUnpaused)
8766 {
8767 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
8768
8769 // ES Spec 3.0 validation text:
8770 // When transform feedback is active and not paused, all geometric primitives generated must
8771 // match the value of primitiveMode passed to BeginTransformFeedback. The error
8772 // INVALID_OPERATION is generated by DrawArrays and DrawArraysInstanced if mode is not
8773 // identical to primitiveMode. The error INVALID_OPERATION is also generated by
8774 // DrawElements, DrawElementsInstanced, and DrawRangeElements while transform feedback is
8775 // active and not paused, regardless of mode. Any primitive type may be used while transform
8776 // feedback is paused.
8777 if (!context->getExtensions().geometryShader)
8778 {
8779 mCachedValidDrawModes.fill(false);
8780 mCachedValidDrawModes[curTransformFeedback->getPrimitiveMode()] = true;
8781 return;
8782 }
8783
8784 // EXT_geometry_shader validation text:
8785 // When transform feedback is active and not paused, all geometric primitives generated must
8786 // be compatible with the value of <primitiveMode> passed to BeginTransformFeedback. If a
8787 // geometry shader is active, the type of primitive emitted by that shader is used instead
8788 // of the <mode> parameter passed to drawing commands for the purposes of this error check.
8789 // Any primitive type may be used while transform feedback is paused.
8790 bool pointsOK = curTransformFeedback->getPrimitiveMode() == PrimitiveMode::Points;
8791 bool linesOK = curTransformFeedback->getPrimitiveMode() == PrimitiveMode::Lines;
8792 bool trisOK = curTransformFeedback->getPrimitiveMode() == PrimitiveMode::Triangles;
8793
8794 setValidDrawModes(pointsOK, linesOK, trisOK, false, false);
8795 return;
8796 }
8797
8798 const ProgramExecutable *programExecutable = context->getState().getProgramExecutable();
8799 if (!programExecutable || !programExecutable->hasLinkedShaderStage(ShaderType::Geometry))
8800 {
8801 mCachedValidDrawModes = kValidBasicDrawModes;
8802 return;
8803 }
8804
8805 ASSERT(programExecutable->hasLinkedShaderStage(ShaderType::Geometry));
8806 PrimitiveMode gsMode = program->getGeometryShaderInputPrimitiveType();
8807
8808 bool pointsOK = gsMode == PrimitiveMode::Points;
8809 bool linesOK = gsMode == PrimitiveMode::Lines;
8810 bool trisOK = gsMode == PrimitiveMode::Triangles;
8811 bool lineAdjOK = gsMode == PrimitiveMode::LinesAdjacency;
8812 bool triAdjOK = gsMode == PrimitiveMode::TrianglesAdjacency;
8813
8814 setValidDrawModes(pointsOK, linesOK, trisOK, lineAdjOK, triAdjOK);
8815 }
8816
updateValidBindTextureTypes(Context * context)8817 void StateCache::updateValidBindTextureTypes(Context *context)
8818 {
8819 const Extensions &exts = context->getExtensions();
8820 bool isGLES3 = context->getClientMajorVersion() >= 3;
8821 bool isGLES31 = context->getClientVersion() >= Version(3, 1);
8822
8823 mCachedValidBindTextureTypes = {{
8824 {TextureType::_2D, true},
8825 {TextureType::_2DArray, isGLES3},
8826 {TextureType::_2DMultisample, isGLES31 || exts.textureMultisample},
8827 {TextureType::_2DMultisampleArray, exts.textureStorageMultisample2DArrayOES},
8828 {TextureType::_3D, isGLES3 || exts.texture3DOES},
8829 {TextureType::External, exts.eglImageExternalOES || exts.eglStreamConsumerExternalNV},
8830 {TextureType::Rectangle, exts.textureRectangle},
8831 {TextureType::CubeMap, true},
8832 {TextureType::CubeMapArray, exts.textureCubeMapArrayAny()},
8833 {TextureType::VideoImage, exts.webglVideoTexture},
8834 }};
8835 }
8836
updateValidDrawElementsTypes(Context * context)8837 void StateCache::updateValidDrawElementsTypes(Context *context)
8838 {
8839 bool supportsUint =
8840 (context->getClientMajorVersion() >= 3 || context->getExtensions().elementIndexUintOES);
8841
8842 mCachedValidDrawElementsTypes = {{
8843 {DrawElementsType::UnsignedByte, true},
8844 {DrawElementsType::UnsignedShort, true},
8845 {DrawElementsType::UnsignedInt, supportsUint},
8846 }};
8847 }
8848
updateTransformFeedbackActiveUnpaused(Context * context)8849 void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
8850 {
8851 TransformFeedback *xfb = context->getState().getCurrentTransformFeedback();
8852 mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused();
8853 }
8854
updateVertexAttribTypesValidation(Context * context)8855 void StateCache::updateVertexAttribTypesValidation(Context *context)
8856 {
8857 VertexAttribTypeCase halfFloatValidity = (context->getExtensions().vertexHalfFloatOES)
8858 ? VertexAttribTypeCase::Valid
8859 : VertexAttribTypeCase::Invalid;
8860
8861 VertexAttribTypeCase vertexType1010102Validity =
8862 (context->getExtensions().vertexAttribType1010102OES) ? VertexAttribTypeCase::ValidSize3or4
8863 : VertexAttribTypeCase::Invalid;
8864
8865 if (context->getClientMajorVersion() <= 2)
8866 {
8867 mCachedVertexAttribTypesValidation = {{
8868 {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
8869 {VertexAttribType::Short, VertexAttribTypeCase::Valid},
8870 {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
8871 {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
8872 {VertexAttribType::Float, VertexAttribTypeCase::Valid},
8873 {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
8874 {VertexAttribType::HalfFloatOES, halfFloatValidity},
8875 }};
8876 }
8877 else
8878 {
8879 mCachedVertexAttribTypesValidation = {{
8880 {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
8881 {VertexAttribType::Short, VertexAttribTypeCase::Valid},
8882 {VertexAttribType::Int, VertexAttribTypeCase::Valid},
8883 {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
8884 {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
8885 {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
8886 {VertexAttribType::Float, VertexAttribTypeCase::Valid},
8887 {VertexAttribType::HalfFloat, VertexAttribTypeCase::Valid},
8888 {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
8889 {VertexAttribType::Int2101010, VertexAttribTypeCase::ValidSize4Only},
8890 {VertexAttribType::HalfFloatOES, halfFloatValidity},
8891 {VertexAttribType::UnsignedInt2101010, VertexAttribTypeCase::ValidSize4Only},
8892 {VertexAttribType::Int1010102, vertexType1010102Validity},
8893 {VertexAttribType::UnsignedInt1010102, vertexType1010102Validity},
8894 }};
8895
8896 mCachedIntegerVertexAttribTypesValidation = {{
8897 {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
8898 {VertexAttribType::Short, VertexAttribTypeCase::Valid},
8899 {VertexAttribType::Int, VertexAttribTypeCase::Valid},
8900 {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
8901 {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
8902 {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
8903 }};
8904 }
8905 }
8906
updateActiveShaderStorageBufferIndices(Context * context)8907 void StateCache::updateActiveShaderStorageBufferIndices(Context *context)
8908 {
8909 mCachedActiveShaderStorageBufferIndices.reset();
8910 Program *program = context->getState().getProgram();
8911 if (program)
8912 {
8913 for (const InterfaceBlock &block : program->getState().getShaderStorageBlocks())
8914 {
8915 mCachedActiveShaderStorageBufferIndices.set(block.binding);
8916 }
8917 }
8918 }
8919
updateCanDraw(Context * context)8920 void StateCache::updateCanDraw(Context *context)
8921 {
8922 mCachedCanDraw = (context->isGLES1() ||
8923 (context->getState().getProgramExecutable() &&
8924 context->getState().getProgramExecutable()->hasVertexAndFragmentShader()));
8925 }
8926 } // namespace gl
8927