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