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