1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Context.cpp: Implements the es2::Context class, managing all GL state and performing
16 // rendering operations. It is the GLES2 specific implementation of EGLContext.
17 
18 #include "Context.h"
19 
20 #include "main.h"
21 #include "mathutil.h"
22 #include "utilities.h"
23 #include "ResourceManager.h"
24 #include "Buffer.h"
25 #include "Fence.h"
26 #include "Framebuffer.h"
27 #include "Program.h"
28 #include "Query.h"
29 #include "Renderbuffer.h"
30 #include "Sampler.h"
31 #include "Shader.h"
32 #include "Texture.h"
33 #include "TransformFeedback.h"
34 #include "VertexArray.h"
35 #include "VertexDataManager.h"
36 #include "IndexDataManager.h"
37 #include "libEGL/Display.h"
38 #include "common/Surface.hpp"
39 #include "Common/Half.hpp"
40 
41 #include <EGL/eglext.h>
42 
43 #include <algorithm>
44 #include <string>
45 
46 namespace es2
47 {
Context(egl::Display * display,const Context * shareContext,EGLint clientVersion,const egl::Config * config)48 Context::Context(egl::Display *display, const Context *shareContext, EGLint clientVersion, const egl::Config *config)
49 	: egl::Context(display), clientVersion(clientVersion), config(config)
50 {
51 	sw::Context *context = new sw::Context();
52 	device = new es2::Device(context);
53 
54 	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
55 
56 	mState.depthClearValue = 1.0f;
57 	mState.stencilClearValue = 0;
58 
59 	mState.cullFaceEnabled = false;
60 	mState.cullMode = GL_BACK;
61 	mState.frontFace = GL_CCW;
62 	mState.depthTestEnabled = false;
63 	mState.depthFunc = GL_LESS;
64 	mState.blendEnabled = false;
65 	mState.sourceBlendRGB = GL_ONE;
66 	mState.sourceBlendAlpha = GL_ONE;
67 	mState.destBlendRGB = GL_ZERO;
68 	mState.destBlendAlpha = GL_ZERO;
69 	mState.blendEquationRGB = GL_FUNC_ADD;
70 	mState.blendEquationAlpha = GL_FUNC_ADD;
71 	mState.blendColor.red = 0;
72 	mState.blendColor.green = 0;
73 	mState.blendColor.blue = 0;
74 	mState.blendColor.alpha = 0;
75 	mState.stencilTestEnabled = false;
76 	mState.stencilFunc = GL_ALWAYS;
77 	mState.stencilRef = 0;
78 	mState.stencilMask = 0xFFFFFFFFu;
79 	mState.stencilWritemask = 0xFFFFFFFFu;
80 	mState.stencilBackFunc = GL_ALWAYS;
81 	mState.stencilBackRef = 0;
82 	mState.stencilBackMask = 0xFFFFFFFFu;
83 	mState.stencilBackWritemask = 0xFFFFFFFFu;
84 	mState.stencilFail = GL_KEEP;
85 	mState.stencilPassDepthFail = GL_KEEP;
86 	mState.stencilPassDepthPass = GL_KEEP;
87 	mState.stencilBackFail = GL_KEEP;
88 	mState.stencilBackPassDepthFail = GL_KEEP;
89 	mState.stencilBackPassDepthPass = GL_KEEP;
90 	mState.polygonOffsetFillEnabled = false;
91 	mState.polygonOffsetFactor = 0.0f;
92 	mState.polygonOffsetUnits = 0.0f;
93 	mState.sampleAlphaToCoverageEnabled = false;
94 	mState.sampleCoverageEnabled = false;
95 	mState.sampleCoverageValue = 1.0f;
96 	mState.sampleCoverageInvert = false;
97 	mState.scissorTestEnabled = false;
98 	mState.ditherEnabled = true;
99 	mState.primitiveRestartFixedIndexEnabled = false;
100 	mState.rasterizerDiscardEnabled = false;
101 	mState.generateMipmapHint = GL_DONT_CARE;
102 	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
103 	mState.textureFilteringHint = GL_DONT_CARE;
104 
105 	mState.lineWidth = 1.0f;
106 
107 	mState.viewportX = 0;
108 	mState.viewportY = 0;
109 	mState.viewportWidth = 0;
110 	mState.viewportHeight = 0;
111 	mState.zNear = 0.0f;
112 	mState.zFar = 1.0f;
113 
114 	mState.scissorX = 0;
115 	mState.scissorY = 0;
116 	mState.scissorWidth = 0;
117 	mState.scissorHeight = 0;
118 
119 	mState.colorMaskRed = true;
120 	mState.colorMaskGreen = true;
121 	mState.colorMaskBlue = true;
122 	mState.colorMaskAlpha = true;
123 	mState.depthMask = true;
124 
125 	if(shareContext)
126 	{
127 		mResourceManager = shareContext->mResourceManager;
128 		mResourceManager->addRef();
129 	}
130 	else
131 	{
132 		mResourceManager = new ResourceManager();
133 	}
134 
135 	// [OpenGL ES 2.0.24] section 3.7 page 83:
136 	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
137 	// and cube map texture state vectors respectively associated with them.
138 	// In order that access to these initial textures not be lost, they are treated as texture
139 	// objects all of whose names are 0.
140 
141 	mTexture2DZero = new Texture2D(0);
142 	mTexture3DZero = new Texture3D(0);
143 	mTexture2DArrayZero = new Texture2DArray(0);
144 	mTextureCubeMapZero = new TextureCubeMap(0);
145 	mTexture2DRectZero = new Texture2DRect(0);
146 	mTextureExternalZero = new TextureExternal(0);
147 
148 	mState.activeSampler = 0;
149 
150 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
151 	{
152 		bindTexture((TextureType)type, 0);
153 	}
154 
155 	bindVertexArray(0);
156 	bindArrayBuffer(0);
157 	bindElementArrayBuffer(0);
158 	bindReadFramebuffer(0);
159 	bindDrawFramebuffer(0);
160 	bindRenderbuffer(0);
161 	bindGenericUniformBuffer(0);
162 	bindTransformFeedback(0);
163 
164 	mState.currentProgram = 0;
165 
166 	mVertexDataManager = nullptr;
167 	mIndexDataManager = nullptr;
168 
169 	mInvalidEnum = false;
170 	mInvalidValue = false;
171 	mInvalidOperation = false;
172 	mOutOfMemory = false;
173 	mInvalidFramebufferOperation = false;
174 
175 	mHasBeenCurrent = false;
176 
177 	markAllStateDirty();
178 }
179 
~Context()180 Context::~Context()
181 {
182 	if(mState.currentProgram != 0)
183 	{
184 		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
185 		if(programObject)
186 		{
187 			programObject->release();
188 		}
189 		mState.currentProgram = 0;
190 	}
191 
192 	while(!mFramebufferNameSpace.empty())
193 	{
194 		deleteFramebuffer(mFramebufferNameSpace.firstName());
195 	}
196 
197 	while(!mFenceNameSpace.empty())
198 	{
199 		deleteFence(mFenceNameSpace.firstName());
200 	}
201 
202 	while(!mQueryNameSpace.empty())
203 	{
204 		deleteQuery(mQueryNameSpace.firstName());
205 	}
206 
207 	while(!mVertexArrayNameSpace.empty())
208 	{
209 		deleteVertexArray(mVertexArrayNameSpace.lastName());
210 	}
211 
212 	while(!mTransformFeedbackNameSpace.empty())
213 	{
214 		deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());
215 	}
216 
217 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
218 	{
219 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
220 		{
221 			mState.samplerTexture[type][sampler] = nullptr;
222 		}
223 	}
224 
225 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
226 	{
227 		mState.vertexAttribute[i].mBoundBuffer = nullptr;
228 	}
229 
230 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
231 	{
232 		mState.activeQuery[i] = nullptr;
233 	}
234 
235 	mState.arrayBuffer = nullptr;
236 	mState.copyReadBuffer = nullptr;
237 	mState.copyWriteBuffer = nullptr;
238 	mState.pixelPackBuffer = nullptr;
239 	mState.pixelUnpackBuffer = nullptr;
240 	mState.genericUniformBuffer = nullptr;
241 
242 	for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++) {
243 		mState.uniformBuffers[i].set(nullptr, 0, 0);
244 	}
245 
246 	mState.renderbuffer = nullptr;
247 
248 	for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
249 	{
250 		mState.sampler[i] = nullptr;
251 	}
252 
253 	mTexture2DZero = nullptr;
254 	mTexture3DZero = nullptr;
255 	mTexture2DArrayZero = nullptr;
256 	mTextureCubeMapZero = nullptr;
257 	mTexture2DRectZero = nullptr;
258 	mTextureExternalZero = nullptr;
259 
260 	delete mVertexDataManager;
261 	delete mIndexDataManager;
262 
263 	mResourceManager->release();
264 	delete device;
265 }
266 
makeCurrent(gl::Surface * surface)267 void Context::makeCurrent(gl::Surface *surface)
268 {
269 	if(!mHasBeenCurrent)
270 	{
271 		mVertexDataManager = new VertexDataManager(this);
272 		mIndexDataManager = new IndexDataManager();
273 
274 		mState.viewportX = 0;
275 		mState.viewportY = 0;
276 		mState.viewportWidth = surface ? surface->getWidth() : 0;
277 		mState.viewportHeight = surface ? surface->getHeight() : 0;
278 
279 		mState.scissorX = 0;
280 		mState.scissorY = 0;
281 		mState.scissorWidth = surface ? surface->getWidth() : 0;
282 		mState.scissorHeight = surface ? surface->getHeight() : 0;
283 
284 		mHasBeenCurrent = true;
285 	}
286 
287 	if(surface)
288 	{
289 		// Wrap the existing resources into GL objects and assign them to the '0' names
290 		egl::Image *defaultRenderTarget = surface->getRenderTarget();
291 		egl::Image *depthStencil = surface->getDepthStencil();
292 
293 		Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
294 		DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
295 		Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
296 
297 		setFramebufferZero(framebufferZero);
298 
299 		if(defaultRenderTarget)
300 		{
301 			defaultRenderTarget->release();
302 		}
303 
304 		if(depthStencil)
305 		{
306 			depthStencil->release();
307 		}
308 	}
309 	else
310 	{
311 		setFramebufferZero(nullptr);
312 	}
313 
314 	markAllStateDirty();
315 }
316 
getClientVersion() const317 EGLint Context::getClientVersion() const
318 {
319 	return clientVersion;
320 }
321 
getConfigID() const322 EGLint Context::getConfigID() const
323 {
324 	return config->mConfigID;
325 }
326 
327 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
markAllStateDirty()328 void Context::markAllStateDirty()
329 {
330 	mAppliedProgramSerial = 0;
331 
332 	mDepthStateDirty = true;
333 	mMaskStateDirty = true;
334 	mBlendStateDirty = true;
335 	mStencilStateDirty = true;
336 	mPolygonOffsetStateDirty = true;
337 	mSampleStateDirty = true;
338 	mDitherStateDirty = true;
339 	mFrontFaceDirty = true;
340 }
341 
setClearColor(float red,float green,float blue,float alpha)342 void Context::setClearColor(float red, float green, float blue, float alpha)
343 {
344 	mState.colorClearValue.red = red;
345 	mState.colorClearValue.green = green;
346 	mState.colorClearValue.blue = blue;
347 	mState.colorClearValue.alpha = alpha;
348 }
349 
setClearDepth(float depth)350 void Context::setClearDepth(float depth)
351 {
352 	mState.depthClearValue = depth;
353 }
354 
setClearStencil(int stencil)355 void Context::setClearStencil(int stencil)
356 {
357 	mState.stencilClearValue = stencil;
358 }
359 
setCullFaceEnabled(bool enabled)360 void Context::setCullFaceEnabled(bool enabled)
361 {
362 	mState.cullFaceEnabled = enabled;
363 }
364 
isCullFaceEnabled() const365 bool Context::isCullFaceEnabled() const
366 {
367 	return mState.cullFaceEnabled;
368 }
369 
setCullMode(GLenum mode)370 void Context::setCullMode(GLenum mode)
371 {
372    mState.cullMode = mode;
373 }
374 
setFrontFace(GLenum front)375 void Context::setFrontFace(GLenum front)
376 {
377 	if(mState.frontFace != front)
378 	{
379 		mState.frontFace = front;
380 		mFrontFaceDirty = true;
381 	}
382 }
383 
setDepthTestEnabled(bool enabled)384 void Context::setDepthTestEnabled(bool enabled)
385 {
386 	if(mState.depthTestEnabled != enabled)
387 	{
388 		mState.depthTestEnabled = enabled;
389 		mDepthStateDirty = true;
390 	}
391 }
392 
isDepthTestEnabled() const393 bool Context::isDepthTestEnabled() const
394 {
395 	return mState.depthTestEnabled;
396 }
397 
setDepthFunc(GLenum depthFunc)398 void Context::setDepthFunc(GLenum depthFunc)
399 {
400 	if(mState.depthFunc != depthFunc)
401 	{
402 		mState.depthFunc = depthFunc;
403 		mDepthStateDirty = true;
404 	}
405 }
406 
setDepthRange(float zNear,float zFar)407 void Context::setDepthRange(float zNear, float zFar)
408 {
409 	mState.zNear = zNear;
410 	mState.zFar = zFar;
411 }
412 
setBlendEnabled(bool enabled)413 void Context::setBlendEnabled(bool enabled)
414 {
415 	if(mState.blendEnabled != enabled)
416 	{
417 		mState.blendEnabled = enabled;
418 		mBlendStateDirty = true;
419 	}
420 }
421 
isBlendEnabled() const422 bool Context::isBlendEnabled() const
423 {
424 	return mState.blendEnabled;
425 }
426 
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)427 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
428 {
429 	if(mState.sourceBlendRGB != sourceRGB ||
430 	   mState.sourceBlendAlpha != sourceAlpha ||
431 	   mState.destBlendRGB != destRGB ||
432 	   mState.destBlendAlpha != destAlpha)
433 	{
434 		mState.sourceBlendRGB = sourceRGB;
435 		mState.destBlendRGB = destRGB;
436 		mState.sourceBlendAlpha = sourceAlpha;
437 		mState.destBlendAlpha = destAlpha;
438 		mBlendStateDirty = true;
439 	}
440 }
441 
setBlendColor(float red,float green,float blue,float alpha)442 void Context::setBlendColor(float red, float green, float blue, float alpha)
443 {
444 	if(mState.blendColor.red != red ||
445 	   mState.blendColor.green != green ||
446 	   mState.blendColor.blue != blue ||
447 	   mState.blendColor.alpha != alpha)
448 	{
449 		mState.blendColor.red = red;
450 		mState.blendColor.green = green;
451 		mState.blendColor.blue = blue;
452 		mState.blendColor.alpha = alpha;
453 		mBlendStateDirty = true;
454 	}
455 }
456 
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)457 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
458 {
459 	if(mState.blendEquationRGB != rgbEquation ||
460 	   mState.blendEquationAlpha != alphaEquation)
461 	{
462 		mState.blendEquationRGB = rgbEquation;
463 		mState.blendEquationAlpha = alphaEquation;
464 		mBlendStateDirty = true;
465 	}
466 }
467 
setStencilTestEnabled(bool enabled)468 void Context::setStencilTestEnabled(bool enabled)
469 {
470 	if(mState.stencilTestEnabled != enabled)
471 	{
472 		mState.stencilTestEnabled = enabled;
473 		mStencilStateDirty = true;
474 	}
475 }
476 
isStencilTestEnabled() const477 bool Context::isStencilTestEnabled() const
478 {
479 	return mState.stencilTestEnabled;
480 }
481 
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)482 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
483 {
484 	if(mState.stencilFunc != stencilFunc ||
485 	   mState.stencilRef != stencilRef ||
486 	   mState.stencilMask != stencilMask)
487 	{
488 		mState.stencilFunc = stencilFunc;
489 		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
490 		mState.stencilMask = stencilMask;
491 		mStencilStateDirty = true;
492 	}
493 }
494 
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)495 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
496 {
497 	if(mState.stencilBackFunc != stencilBackFunc ||
498 	   mState.stencilBackRef != stencilBackRef ||
499 	   mState.stencilBackMask != stencilBackMask)
500 	{
501 		mState.stencilBackFunc = stencilBackFunc;
502 		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
503 		mState.stencilBackMask = stencilBackMask;
504 		mStencilStateDirty = true;
505 	}
506 }
507 
setStencilWritemask(GLuint stencilWritemask)508 void Context::setStencilWritemask(GLuint stencilWritemask)
509 {
510 	if(mState.stencilWritemask != stencilWritemask)
511 	{
512 		mState.stencilWritemask = stencilWritemask;
513 		mStencilStateDirty = true;
514 	}
515 }
516 
setStencilBackWritemask(GLuint stencilBackWritemask)517 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
518 {
519 	if(mState.stencilBackWritemask != stencilBackWritemask)
520 	{
521 		mState.stencilBackWritemask = stencilBackWritemask;
522 		mStencilStateDirty = true;
523 	}
524 }
525 
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)526 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
527 {
528 	if(mState.stencilFail != stencilFail ||
529 	   mState.stencilPassDepthFail != stencilPassDepthFail ||
530 	   mState.stencilPassDepthPass != stencilPassDepthPass)
531 	{
532 		mState.stencilFail = stencilFail;
533 		mState.stencilPassDepthFail = stencilPassDepthFail;
534 		mState.stencilPassDepthPass = stencilPassDepthPass;
535 		mStencilStateDirty = true;
536 	}
537 }
538 
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)539 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
540 {
541 	if(mState.stencilBackFail != stencilBackFail ||
542 	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
543 	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
544 	{
545 		mState.stencilBackFail = stencilBackFail;
546 		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
547 		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
548 		mStencilStateDirty = true;
549 	}
550 }
551 
setPolygonOffsetFillEnabled(bool enabled)552 void Context::setPolygonOffsetFillEnabled(bool enabled)
553 {
554 	if(mState.polygonOffsetFillEnabled != enabled)
555 	{
556 		mState.polygonOffsetFillEnabled = enabled;
557 		mPolygonOffsetStateDirty = true;
558 	}
559 }
560 
isPolygonOffsetFillEnabled() const561 bool Context::isPolygonOffsetFillEnabled() const
562 {
563 	return mState.polygonOffsetFillEnabled;
564 }
565 
setPolygonOffsetParams(GLfloat factor,GLfloat units)566 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
567 {
568 	if(mState.polygonOffsetFactor != factor ||
569 	   mState.polygonOffsetUnits != units)
570 	{
571 		mState.polygonOffsetFactor = factor;
572 		mState.polygonOffsetUnits = units;
573 		mPolygonOffsetStateDirty = true;
574 	}
575 }
576 
setSampleAlphaToCoverageEnabled(bool enabled)577 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
578 {
579 	if(mState.sampleAlphaToCoverageEnabled != enabled)
580 	{
581 		mState.sampleAlphaToCoverageEnabled = enabled;
582 		mSampleStateDirty = true;
583 	}
584 }
585 
isSampleAlphaToCoverageEnabled() const586 bool Context::isSampleAlphaToCoverageEnabled() const
587 {
588 	return mState.sampleAlphaToCoverageEnabled;
589 }
590 
setSampleCoverageEnabled(bool enabled)591 void Context::setSampleCoverageEnabled(bool enabled)
592 {
593 	if(mState.sampleCoverageEnabled != enabled)
594 	{
595 		mState.sampleCoverageEnabled = enabled;
596 		mSampleStateDirty = true;
597 	}
598 }
599 
isSampleCoverageEnabled() const600 bool Context::isSampleCoverageEnabled() const
601 {
602 	return mState.sampleCoverageEnabled;
603 }
604 
setSampleCoverageParams(GLclampf value,bool invert)605 void Context::setSampleCoverageParams(GLclampf value, bool invert)
606 {
607 	if(mState.sampleCoverageValue != value ||
608 	   mState.sampleCoverageInvert != invert)
609 	{
610 		mState.sampleCoverageValue = value;
611 		mState.sampleCoverageInvert = invert;
612 		mSampleStateDirty = true;
613 	}
614 }
615 
setScissorTestEnabled(bool enabled)616 void Context::setScissorTestEnabled(bool enabled)
617 {
618 	mState.scissorTestEnabled = enabled;
619 }
620 
isScissorTestEnabled() const621 bool Context::isScissorTestEnabled() const
622 {
623 	return mState.scissorTestEnabled;
624 }
625 
setDitherEnabled(bool enabled)626 void Context::setDitherEnabled(bool enabled)
627 {
628 	if(mState.ditherEnabled != enabled)
629 	{
630 		mState.ditherEnabled = enabled;
631 		mDitherStateDirty = true;
632 	}
633 }
634 
isDitherEnabled() const635 bool Context::isDitherEnabled() const
636 {
637 	return mState.ditherEnabled;
638 }
639 
setPrimitiveRestartFixedIndexEnabled(bool enabled)640 void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
641 {
642 	mState.primitiveRestartFixedIndexEnabled = enabled;
643 }
644 
isPrimitiveRestartFixedIndexEnabled() const645 bool Context::isPrimitiveRestartFixedIndexEnabled() const
646 {
647 	return mState.primitiveRestartFixedIndexEnabled;
648 }
649 
setRasterizerDiscardEnabled(bool enabled)650 void Context::setRasterizerDiscardEnabled(bool enabled)
651 {
652 	mState.rasterizerDiscardEnabled = enabled;
653 }
654 
isRasterizerDiscardEnabled() const655 bool Context::isRasterizerDiscardEnabled() const
656 {
657 	return mState.rasterizerDiscardEnabled;
658 }
659 
setLineWidth(GLfloat width)660 void Context::setLineWidth(GLfloat width)
661 {
662 	mState.lineWidth = width;
663 	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
664 }
665 
setGenerateMipmapHint(GLenum hint)666 void Context::setGenerateMipmapHint(GLenum hint)
667 {
668 	mState.generateMipmapHint = hint;
669 }
670 
setFragmentShaderDerivativeHint(GLenum hint)671 void Context::setFragmentShaderDerivativeHint(GLenum hint)
672 {
673 	mState.fragmentShaderDerivativeHint = hint;
674 	// TODO: Propagate the hint to shader translator so we can write
675 	// ddx, ddx_coarse, or ddx_fine depending on the hint.
676 	// Ignore for now. It is valid for implementations to ignore hint.
677 }
678 
setTextureFilteringHint(GLenum hint)679 void Context::setTextureFilteringHint(GLenum hint)
680 {
681 	mState.textureFilteringHint = hint;
682 }
683 
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)684 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
685 {
686 	mState.viewportX = x;
687 	mState.viewportY = y;
688 	mState.viewportWidth = std::min<GLsizei>(width, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE);     // GL_MAX_VIEWPORT_DIMS[0]
689 	mState.viewportHeight = std::min<GLsizei>(height, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE);   // GL_MAX_VIEWPORT_DIMS[1]
690 }
691 
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)692 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
693 {
694 	mState.scissorX = x;
695 	mState.scissorY = y;
696 	mState.scissorWidth = width;
697 	mState.scissorHeight = height;
698 }
699 
setColorMask(bool red,bool green,bool blue,bool alpha)700 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
701 {
702 	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
703 	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
704 	{
705 		mState.colorMaskRed = red;
706 		mState.colorMaskGreen = green;
707 		mState.colorMaskBlue = blue;
708 		mState.colorMaskAlpha = alpha;
709 		mMaskStateDirty = true;
710 	}
711 }
712 
getColorMask() const713 unsigned int Context::getColorMask() const
714 {
715 	return (mState.colorMaskRed ? 0x1 : 0) |
716 	       (mState.colorMaskGreen ? 0x2 : 0) |
717 	       (mState.colorMaskBlue ? 0x4 : 0) |
718 	       (mState.colorMaskAlpha ? 0x8 : 0);
719 }
720 
setDepthMask(bool mask)721 void Context::setDepthMask(bool mask)
722 {
723 	if(mState.depthMask != mask)
724 	{
725 		mState.depthMask = mask;
726 		mMaskStateDirty = true;
727 	}
728 }
729 
setActiveSampler(unsigned int active)730 void Context::setActiveSampler(unsigned int active)
731 {
732 	mState.activeSampler = active;
733 }
734 
getReadFramebufferName() const735 GLuint Context::getReadFramebufferName() const
736 {
737 	return mState.readFramebuffer;
738 }
739 
getDrawFramebufferName() const740 GLuint Context::getDrawFramebufferName() const
741 {
742 	return mState.drawFramebuffer;
743 }
744 
getRenderbufferName() const745 GLuint Context::getRenderbufferName() const
746 {
747 	return mState.renderbuffer.name();
748 }
749 
setFramebufferReadBuffer(GLuint buf)750 void Context::setFramebufferReadBuffer(GLuint buf)
751 {
752 	Framebuffer *framebuffer = getReadFramebuffer();
753 
754 	if(framebuffer)
755 	{
756 		framebuffer->setReadBuffer(buf);
757 	}
758 	else
759 	{
760 		return error(GL_INVALID_OPERATION);
761 	}
762 }
763 
setFramebufferDrawBuffers(GLsizei n,const GLenum * bufs)764 void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
765 {
766 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
767 
768 	if(drawFramebuffer)
769 	{
770 		for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
771 		{
772 			drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
773 		}
774 	}
775 	else
776 	{
777 		return error(GL_INVALID_OPERATION);
778 	}
779 }
780 
getArrayBufferName() const781 GLuint Context::getArrayBufferName() const
782 {
783 	return mState.arrayBuffer.name();
784 }
785 
getElementArrayBufferName() const786 GLuint Context::getElementArrayBufferName() const
787 {
788 	Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
789 	return elementArrayBuffer ? elementArrayBuffer->name : 0;
790 }
791 
getActiveQuery(GLenum target) const792 GLuint Context::getActiveQuery(GLenum target) const
793 {
794 	Query *queryObject = nullptr;
795 
796 	switch(target)
797 	{
798 	case GL_ANY_SAMPLES_PASSED_EXT:
799 		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
800 		break;
801 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
802 		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
803 		break;
804 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
805 		queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
806 		break;
807 	default:
808 		ASSERT(false);
809 	}
810 
811 	if(queryObject)
812 	{
813 		return queryObject->name;
814 	}
815 
816 	return 0;
817 }
818 
setVertexAttribArrayEnabled(unsigned int attribNum,bool enabled)819 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
820 {
821 	getCurrentVertexArray()->enableAttribute(attribNum, enabled);
822 }
823 
setVertexAttribDivisor(unsigned int attribNum,GLuint divisor)824 void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
825 {
826 	getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
827 }
828 
getVertexAttribState(unsigned int attribNum) const829 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
830 {
831 	return getCurrentVertexArray()->getVertexAttribute(attribNum);
832 }
833 
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,bool pureInteger,GLsizei stride,const void * pointer)834 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
835                                    bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
836 {
837 	getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
838 }
839 
getVertexAttribPointer(unsigned int attribNum) const840 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
841 {
842 	return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
843 }
844 
getVertexArrayAttributes()845 const VertexAttributeArray &Context::getVertexArrayAttributes()
846 {
847 	return getCurrentVertexArray()->getVertexAttributes();
848 }
849 
getCurrentVertexAttributes()850 const VertexAttributeArray &Context::getCurrentVertexAttributes()
851 {
852 	return mState.vertexAttribute;
853 }
854 
setPackAlignment(GLint alignment)855 void Context::setPackAlignment(GLint alignment)
856 {
857 	mState.packParameters.alignment = alignment;
858 }
859 
setUnpackAlignment(GLint alignment)860 void Context::setUnpackAlignment(GLint alignment)
861 {
862 	mState.unpackParameters.alignment = alignment;
863 }
864 
getUnpackParameters() const865 const gl::PixelStorageModes &Context::getUnpackParameters() const
866 {
867 	return mState.unpackParameters;
868 }
869 
setPackRowLength(GLint rowLength)870 void Context::setPackRowLength(GLint rowLength)
871 {
872 	mState.packParameters.rowLength = rowLength;
873 }
874 
setPackSkipPixels(GLint skipPixels)875 void Context::setPackSkipPixels(GLint skipPixels)
876 {
877 	mState.packParameters.skipPixels = skipPixels;
878 }
879 
setPackSkipRows(GLint skipRows)880 void Context::setPackSkipRows(GLint skipRows)
881 {
882 	mState.packParameters.skipRows = skipRows;
883 }
884 
setUnpackRowLength(GLint rowLength)885 void Context::setUnpackRowLength(GLint rowLength)
886 {
887 	mState.unpackParameters.rowLength = rowLength;
888 }
889 
setUnpackImageHeight(GLint imageHeight)890 void Context::setUnpackImageHeight(GLint imageHeight)
891 {
892 	mState.unpackParameters.imageHeight = imageHeight;
893 }
894 
setUnpackSkipPixels(GLint skipPixels)895 void Context::setUnpackSkipPixels(GLint skipPixels)
896 {
897 	mState.unpackParameters.skipPixels = skipPixels;
898 }
899 
setUnpackSkipRows(GLint skipRows)900 void Context::setUnpackSkipRows(GLint skipRows)
901 {
902 	mState.unpackParameters.skipRows = skipRows;
903 }
904 
setUnpackSkipImages(GLint skipImages)905 void Context::setUnpackSkipImages(GLint skipImages)
906 {
907 	mState.unpackParameters.skipImages = skipImages;
908 }
909 
createBuffer()910 GLuint Context::createBuffer()
911 {
912 	return mResourceManager->createBuffer();
913 }
914 
createProgram()915 GLuint Context::createProgram()
916 {
917 	return mResourceManager->createProgram();
918 }
919 
createShader(GLenum type)920 GLuint Context::createShader(GLenum type)
921 {
922 	return mResourceManager->createShader(type);
923 }
924 
createTexture()925 GLuint Context::createTexture()
926 {
927 	return mResourceManager->createTexture();
928 }
929 
createRenderbuffer()930 GLuint Context::createRenderbuffer()
931 {
932 	return mResourceManager->createRenderbuffer();
933 }
934 
935 // Returns an unused framebuffer name
createFramebuffer()936 GLuint Context::createFramebuffer()
937 {
938 	return mFramebufferNameSpace.allocate();
939 }
940 
createFence()941 GLuint Context::createFence()
942 {
943 	return mFenceNameSpace.allocate(new Fence());
944 }
945 
946 // Returns an unused query name
createQuery()947 GLuint Context::createQuery()
948 {
949 	return mQueryNameSpace.allocate();
950 }
951 
952 // Returns an unused vertex array name
createVertexArray()953 GLuint Context::createVertexArray()
954 {
955 	return mVertexArrayNameSpace.allocate();
956 }
957 
createFenceSync(GLenum condition,GLbitfield flags)958 GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
959 {
960 	GLuint handle = mResourceManager->createFenceSync(condition, flags);
961 
962 	return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
963 }
964 
965 // Returns an unused transform feedback name
createTransformFeedback()966 GLuint Context::createTransformFeedback()
967 {
968 	return mTransformFeedbackNameSpace.allocate();
969 }
970 
971 // Returns an unused sampler name
createSampler()972 GLuint Context::createSampler()
973 {
974 	return mResourceManager->createSampler();
975 }
976 
deleteBuffer(GLuint buffer)977 void Context::deleteBuffer(GLuint buffer)
978 {
979 	detachBuffer(buffer);
980 
981 	mResourceManager->deleteBuffer(buffer);
982 }
983 
deleteShader(GLuint shader)984 void Context::deleteShader(GLuint shader)
985 {
986 	mResourceManager->deleteShader(shader);
987 }
988 
deleteProgram(GLuint program)989 void Context::deleteProgram(GLuint program)
990 {
991 	mResourceManager->deleteProgram(program);
992 }
993 
deleteTexture(GLuint texture)994 void Context::deleteTexture(GLuint texture)
995 {
996 	detachTexture(texture);
997 
998 	mResourceManager->deleteTexture(texture);
999 }
1000 
deleteRenderbuffer(GLuint renderbuffer)1001 void Context::deleteRenderbuffer(GLuint renderbuffer)
1002 {
1003 	if(mResourceManager->getRenderbuffer(renderbuffer))
1004 	{
1005 		detachRenderbuffer(renderbuffer);
1006 	}
1007 
1008 	mResourceManager->deleteRenderbuffer(renderbuffer);
1009 }
1010 
deleteFramebuffer(GLuint framebuffer)1011 void Context::deleteFramebuffer(GLuint framebuffer)
1012 {
1013 	detachFramebuffer(framebuffer);
1014 
1015 	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
1016 
1017 	if(framebufferObject)
1018 	{
1019 		delete framebufferObject;
1020 	}
1021 }
1022 
deleteFence(GLuint fence)1023 void Context::deleteFence(GLuint fence)
1024 {
1025 	Fence *fenceObject = mFenceNameSpace.remove(fence);
1026 
1027 	if(fenceObject)
1028 	{
1029 		delete fenceObject;
1030 	}
1031 }
1032 
deleteQuery(GLuint query)1033 void Context::deleteQuery(GLuint query)
1034 {
1035 	Query *queryObject = mQueryNameSpace.remove(query);
1036 
1037 	if(queryObject)
1038 	{
1039 		queryObject->release();
1040 	}
1041 }
1042 
deleteVertexArray(GLuint vertexArray)1043 void Context::deleteVertexArray(GLuint vertexArray)
1044 {
1045 	// [OpenGL ES 3.0.2] section 2.10 page 43:
1046 	// If a vertex array object that is currently bound is deleted, the binding
1047 	// for that object reverts to zero and the default vertex array becomes current.
1048 	if(getCurrentVertexArray()->name == vertexArray)
1049 	{
1050 		bindVertexArray(0);
1051 	}
1052 
1053 	VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);
1054 
1055 	if(vertexArrayObject)
1056 	{
1057 		delete vertexArrayObject;
1058 	}
1059 }
1060 
deleteFenceSync(GLsync fenceSync)1061 void Context::deleteFenceSync(GLsync fenceSync)
1062 {
1063 	// The spec specifies the underlying Fence object is not deleted until all current
1064 	// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
1065 	// and since our API is currently designed for being called from a single thread, we can delete
1066 	// the fence immediately.
1067 	mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
1068 }
1069 
deleteTransformFeedback(GLuint transformFeedback)1070 void Context::deleteTransformFeedback(GLuint transformFeedback)
1071 {
1072 	TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);
1073 
1074 	if(transformFeedbackObject)
1075 	{
1076 		delete transformFeedbackObject;
1077 	}
1078 }
1079 
deleteSampler(GLuint sampler)1080 void Context::deleteSampler(GLuint sampler)
1081 {
1082 	detachSampler(sampler);
1083 
1084 	mResourceManager->deleteSampler(sampler);
1085 }
1086 
getBuffer(GLuint handle) const1087 Buffer *Context::getBuffer(GLuint handle) const
1088 {
1089 	return mResourceManager->getBuffer(handle);
1090 }
1091 
getShader(GLuint handle) const1092 Shader *Context::getShader(GLuint handle) const
1093 {
1094 	return mResourceManager->getShader(handle);
1095 }
1096 
getProgram(GLuint handle) const1097 Program *Context::getProgram(GLuint handle) const
1098 {
1099 	return mResourceManager->getProgram(handle);
1100 }
1101 
getTexture(GLuint handle) const1102 Texture *Context::getTexture(GLuint handle) const
1103 {
1104 	return mResourceManager->getTexture(handle);
1105 }
1106 
getRenderbuffer(GLuint handle) const1107 Renderbuffer *Context::getRenderbuffer(GLuint handle) const
1108 {
1109 	return mResourceManager->getRenderbuffer(handle);
1110 }
1111 
getReadFramebuffer() const1112 Framebuffer *Context::getReadFramebuffer() const
1113 {
1114 	return getFramebuffer(mState.readFramebuffer);
1115 }
1116 
getDrawFramebuffer() const1117 Framebuffer *Context::getDrawFramebuffer() const
1118 {
1119 	return getFramebuffer(mState.drawFramebuffer);
1120 }
1121 
bindArrayBuffer(unsigned int buffer)1122 void Context::bindArrayBuffer(unsigned int buffer)
1123 {
1124 	mResourceManager->checkBufferAllocation(buffer);
1125 
1126 	mState.arrayBuffer = getBuffer(buffer);
1127 }
1128 
bindElementArrayBuffer(unsigned int buffer)1129 void Context::bindElementArrayBuffer(unsigned int buffer)
1130 {
1131 	mResourceManager->checkBufferAllocation(buffer);
1132 
1133 	getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1134 }
1135 
bindCopyReadBuffer(GLuint buffer)1136 void Context::bindCopyReadBuffer(GLuint buffer)
1137 {
1138 	mResourceManager->checkBufferAllocation(buffer);
1139 
1140 	mState.copyReadBuffer = getBuffer(buffer);
1141 }
1142 
bindCopyWriteBuffer(GLuint buffer)1143 void Context::bindCopyWriteBuffer(GLuint buffer)
1144 {
1145 	mResourceManager->checkBufferAllocation(buffer);
1146 
1147 	mState.copyWriteBuffer = getBuffer(buffer);
1148 }
1149 
bindPixelPackBuffer(GLuint buffer)1150 void Context::bindPixelPackBuffer(GLuint buffer)
1151 {
1152 	mResourceManager->checkBufferAllocation(buffer);
1153 
1154 	mState.pixelPackBuffer = getBuffer(buffer);
1155 }
1156 
bindPixelUnpackBuffer(GLuint buffer)1157 void Context::bindPixelUnpackBuffer(GLuint buffer)
1158 {
1159 	mResourceManager->checkBufferAllocation(buffer);
1160 
1161 	mState.pixelUnpackBuffer = getBuffer(buffer);
1162 }
1163 
bindTransformFeedbackBuffer(GLuint buffer)1164 void Context::bindTransformFeedbackBuffer(GLuint buffer)
1165 {
1166 	mResourceManager->checkBufferAllocation(buffer);
1167 
1168 	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1169 
1170 	if(transformFeedback)
1171 	{
1172 		transformFeedback->setGenericBuffer(getBuffer(buffer));
1173 	}
1174 }
1175 
bindTexture(TextureType type,GLuint texture)1176 void Context::bindTexture(TextureType type, GLuint texture)
1177 {
1178 	mResourceManager->checkTextureAllocation(texture, type);
1179 
1180 	mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
1181 }
1182 
bindReadFramebuffer(GLuint framebuffer)1183 void Context::bindReadFramebuffer(GLuint framebuffer)
1184 {
1185 	if(!getFramebuffer(framebuffer))
1186 	{
1187 		if(framebuffer == 0)
1188 		{
1189 			mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1190 		}
1191 		else
1192 		{
1193 			mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1194 		}
1195 	}
1196 
1197 	mState.readFramebuffer = framebuffer;
1198 }
1199 
bindDrawFramebuffer(GLuint framebuffer)1200 void Context::bindDrawFramebuffer(GLuint framebuffer)
1201 {
1202 	if(!getFramebuffer(framebuffer))
1203 	{
1204 		if(framebuffer == 0)
1205 		{
1206 			mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1207 		}
1208 		else
1209 		{
1210 			mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1211 		}
1212 	}
1213 
1214 	mState.drawFramebuffer = framebuffer;
1215 }
1216 
bindRenderbuffer(GLuint renderbuffer)1217 void Context::bindRenderbuffer(GLuint renderbuffer)
1218 {
1219 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
1220 
1221 	mState.renderbuffer = getRenderbuffer(renderbuffer);
1222 }
1223 
bindVertexArray(GLuint array)1224 void Context::bindVertexArray(GLuint array)
1225 {
1226 	VertexArray *vertexArray = getVertexArray(array);
1227 
1228 	if(!vertexArray)
1229 	{
1230 		vertexArray = new VertexArray(array);
1231 		mVertexArrayNameSpace.insert(array, vertexArray);
1232 	}
1233 
1234 	mState.vertexArray = array;
1235 }
1236 
bindGenericUniformBuffer(GLuint buffer)1237 void Context::bindGenericUniformBuffer(GLuint buffer)
1238 {
1239 	mResourceManager->checkBufferAllocation(buffer);
1240 
1241 	mState.genericUniformBuffer = getBuffer(buffer);
1242 }
1243 
bindIndexedUniformBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1244 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1245 {
1246 	mResourceManager->checkBufferAllocation(buffer);
1247 
1248 	Buffer* bufferObject = getBuffer(buffer);
1249 	mState.uniformBuffers[index].set(bufferObject, static_cast<int>(offset), static_cast<int>(size));
1250 }
1251 
bindGenericTransformFeedbackBuffer(GLuint buffer)1252 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1253 {
1254 	mResourceManager->checkBufferAllocation(buffer);
1255 
1256 	getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
1257 }
1258 
bindIndexedTransformFeedbackBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1259 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1260 {
1261 	mResourceManager->checkBufferAllocation(buffer);
1262 
1263 	Buffer* bufferObject = getBuffer(buffer);
1264 	getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
1265 }
1266 
bindTransformFeedback(GLuint id)1267 void Context::bindTransformFeedback(GLuint id)
1268 {
1269 	if(!getTransformFeedback(id))
1270 	{
1271 		mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
1272 	}
1273 
1274 	mState.transformFeedback = id;
1275 }
1276 
bindSampler(GLuint unit,GLuint sampler)1277 bool Context::bindSampler(GLuint unit, GLuint sampler)
1278 {
1279 	mResourceManager->checkSamplerAllocation(sampler);
1280 
1281 	Sampler* samplerObject = getSampler(sampler);
1282 
1283 	mState.sampler[unit] = samplerObject;
1284 
1285 	return !!samplerObject;
1286 }
1287 
useProgram(GLuint program)1288 void Context::useProgram(GLuint program)
1289 {
1290 	GLuint priorProgram = mState.currentProgram;
1291 	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
1292 
1293 	if(priorProgram != program)
1294 	{
1295 		Program *newProgram = mResourceManager->getProgram(program);
1296 		Program *oldProgram = mResourceManager->getProgram(priorProgram);
1297 
1298 		if(newProgram)
1299 		{
1300 			newProgram->addRef();
1301 		}
1302 
1303 		if(oldProgram)
1304 		{
1305 			oldProgram->release();
1306 		}
1307 	}
1308 }
1309 
beginQuery(GLenum target,GLuint query)1310 void Context::beginQuery(GLenum target, GLuint query)
1311 {
1312 	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1313 	// of zero, if the active query object name for <target> is non-zero (for the
1314 	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1315 	// the active query for either target is non-zero), if <id> is the name of an
1316 	// existing query object whose type does not match <target>, or if <id> is the
1317 	// active query object name for any query type, the error INVALID_OPERATION is
1318 	// generated.
1319 
1320 	// Ensure no other queries are active
1321 	// NOTE: If other queries than occlusion are supported, we will need to check
1322 	// separately that:
1323 	//    a) The query ID passed is not the current active query for any target/type
1324 	//    b) There are no active queries for the requested target (and in the case
1325 	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1326 	//       no query may be active for either if glBeginQuery targets either.
1327 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1328 	{
1329 		if(mState.activeQuery[i])
1330 		{
1331 			switch(mState.activeQuery[i]->getType())
1332 			{
1333 			case GL_ANY_SAMPLES_PASSED_EXT:
1334 			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1335 				if((target == GL_ANY_SAMPLES_PASSED_EXT) ||
1336 				   (target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT))
1337 				{
1338 					return error(GL_INVALID_OPERATION);
1339 				}
1340 				break;
1341 			case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1342 				if(target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
1343 				{
1344 					return error(GL_INVALID_OPERATION);
1345 				}
1346 				break;
1347 			default:
1348 				break;
1349 			}
1350 		}
1351 	}
1352 
1353 	QueryType qType;
1354 	switch(target)
1355 	{
1356 	case GL_ANY_SAMPLES_PASSED_EXT:
1357 		qType = QUERY_ANY_SAMPLES_PASSED;
1358 		break;
1359 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1360 		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1361 		break;
1362 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1363 		qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1364 		break;
1365 	default:
1366 		UNREACHABLE(target);
1367 		return error(GL_INVALID_ENUM);
1368 	}
1369 
1370 	Query *queryObject = createQuery(query, target);
1371 
1372 	// Check that name was obtained with glGenQueries
1373 	if(!queryObject)
1374 	{
1375 		return error(GL_INVALID_OPERATION);
1376 	}
1377 
1378 	// Check for type mismatch
1379 	if(queryObject->getType() != target)
1380 	{
1381 		return error(GL_INVALID_OPERATION);
1382 	}
1383 
1384 	// Set query as active for specified target
1385 	mState.activeQuery[qType] = queryObject;
1386 
1387 	// Begin query
1388 	queryObject->begin();
1389 }
1390 
endQuery(GLenum target)1391 void Context::endQuery(GLenum target)
1392 {
1393 	QueryType qType;
1394 
1395 	switch(target)
1396 	{
1397 	case GL_ANY_SAMPLES_PASSED_EXT:                qType = QUERY_ANY_SAMPLES_PASSED;                    break;
1398 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;       break;
1399 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
1400 	default: UNREACHABLE(target); return;
1401 	}
1402 
1403 	Query *queryObject = mState.activeQuery[qType];
1404 
1405 	if(!queryObject)
1406 	{
1407 		return error(GL_INVALID_OPERATION);
1408 	}
1409 
1410 	queryObject->end();
1411 
1412 	mState.activeQuery[qType] = nullptr;
1413 }
1414 
setFramebufferZero(Framebuffer * buffer)1415 void Context::setFramebufferZero(Framebuffer *buffer)
1416 {
1417 	delete mFramebufferNameSpace.remove(0);
1418 	mFramebufferNameSpace.insert(0, buffer);
1419 }
1420 
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1421 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1422 {
1423 	Renderbuffer *renderbufferObject = mState.renderbuffer;
1424 	renderbufferObject->setStorage(renderbuffer);
1425 }
1426 
getFramebuffer(unsigned int handle) const1427 Framebuffer *Context::getFramebuffer(unsigned int handle) const
1428 {
1429 	return mFramebufferNameSpace.find(handle);
1430 }
1431 
getFence(unsigned int handle) const1432 Fence *Context::getFence(unsigned int handle) const
1433 {
1434 	return mFenceNameSpace.find(handle);
1435 }
1436 
getFenceSync(GLsync handle) const1437 FenceSync *Context::getFenceSync(GLsync handle) const
1438 {
1439 	return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
1440 }
1441 
getQuery(unsigned int handle) const1442 Query *Context::getQuery(unsigned int handle) const
1443 {
1444 	return mQueryNameSpace.find(handle);
1445 }
1446 
createQuery(unsigned int handle,GLenum type)1447 Query *Context::createQuery(unsigned int handle, GLenum type)
1448 {
1449 	if(!mQueryNameSpace.isReserved(handle))
1450 	{
1451 		return nullptr;
1452 	}
1453 	else
1454 	{
1455 		Query *query = mQueryNameSpace.find(handle);
1456 		if(!query)
1457 		{
1458 			query = new Query(handle, type);
1459 			query->addRef();
1460 			mQueryNameSpace.insert(handle, query);
1461 		}
1462 
1463 		return query;
1464 	}
1465 }
1466 
getVertexArray(GLuint array) const1467 VertexArray *Context::getVertexArray(GLuint array) const
1468 {
1469 	return mVertexArrayNameSpace.find(array);
1470 }
1471 
getCurrentVertexArray() const1472 VertexArray *Context::getCurrentVertexArray() const
1473 {
1474 	return getVertexArray(mState.vertexArray);
1475 }
1476 
isVertexArray(GLuint array) const1477 bool Context::isVertexArray(GLuint array) const
1478 {
1479 	return mVertexArrayNameSpace.isReserved(array);
1480 }
1481 
hasZeroDivisor() const1482 bool Context::hasZeroDivisor() const
1483 {
1484 	// Verify there is at least one active attribute with a divisor of zero
1485 	es2::Program *programObject = getCurrentProgram();
1486 	for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
1487 	{
1488 		bool active = (programObject->getAttributeStream(attributeIndex) != -1);
1489 		if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
1490 		{
1491 			return true;
1492 		}
1493 	}
1494 
1495 	return false;
1496 }
1497 
getTransformFeedback(GLuint transformFeedback) const1498 TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
1499 {
1500 	return mTransformFeedbackNameSpace.find(transformFeedback);
1501 }
1502 
isTransformFeedback(GLuint array) const1503 bool Context::isTransformFeedback(GLuint array) const
1504 {
1505 	return mTransformFeedbackNameSpace.isReserved(array);
1506 }
1507 
getSampler(GLuint sampler) const1508 Sampler *Context::getSampler(GLuint sampler) const
1509 {
1510 	return mResourceManager->getSampler(sampler);
1511 }
1512 
isSampler(GLuint sampler) const1513 bool Context::isSampler(GLuint sampler) const
1514 {
1515 	return mResourceManager->isSampler(sampler);
1516 }
1517 
getArrayBuffer() const1518 Buffer *Context::getArrayBuffer() const
1519 {
1520 	return mState.arrayBuffer;
1521 }
1522 
getElementArrayBuffer() const1523 Buffer *Context::getElementArrayBuffer() const
1524 {
1525 	return getCurrentVertexArray()->getElementArrayBuffer();
1526 }
1527 
getCopyReadBuffer() const1528 Buffer *Context::getCopyReadBuffer() const
1529 {
1530 	return mState.copyReadBuffer;
1531 }
1532 
getCopyWriteBuffer() const1533 Buffer *Context::getCopyWriteBuffer() const
1534 {
1535 	return mState.copyWriteBuffer;
1536 }
1537 
getPixelPackBuffer() const1538 Buffer *Context::getPixelPackBuffer() const
1539 {
1540 	return mState.pixelPackBuffer;
1541 }
1542 
getPixelUnpackBuffer() const1543 Buffer *Context::getPixelUnpackBuffer() const
1544 {
1545 	return mState.pixelUnpackBuffer;
1546 }
1547 
getGenericUniformBuffer() const1548 Buffer *Context::getGenericUniformBuffer() const
1549 {
1550 	return mState.genericUniformBuffer;
1551 }
1552 
getRequiredBufferSize(GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type) const1553 GLsizei Context::getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type) const
1554 {
1555 	GLsizei inputWidth = (mState.unpackParameters.rowLength == 0) ? width : mState.unpackParameters.rowLength;
1556 	GLsizei inputPitch = gl::ComputePitch(inputWidth, format, type, mState.unpackParameters.alignment);
1557 	GLsizei inputHeight = (mState.unpackParameters.imageHeight == 0) ? height : mState.unpackParameters.imageHeight;
1558 	return inputPitch * inputHeight * depth;
1559 }
1560 
getPixels(const GLvoid ** pixels,GLenum type,GLsizei imageSize) const1561 GLenum Context::getPixels(const GLvoid **pixels, GLenum type, GLsizei imageSize) const
1562 {
1563 	if(mState.pixelUnpackBuffer)
1564 	{
1565 		ASSERT(mState.pixelUnpackBuffer->name != 0);
1566 
1567 		if(mState.pixelUnpackBuffer->isMapped())
1568 		{
1569 			return GL_INVALID_OPERATION;
1570 		}
1571 
1572 		size_t offset = static_cast<size_t>((ptrdiff_t)(*pixels));
1573 
1574 		if(offset % GetTypeSize(type) != 0)
1575 		{
1576 			return GL_INVALID_OPERATION;
1577 		}
1578 
1579 		if(offset > mState.pixelUnpackBuffer->size())
1580 		{
1581 			return GL_INVALID_OPERATION;
1582 		}
1583 
1584 		if(mState.pixelUnpackBuffer->size() - offset < static_cast<size_t>(imageSize))
1585 		{
1586 			return GL_INVALID_OPERATION;
1587 		}
1588 
1589 		*pixels = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + offset;
1590 	}
1591 
1592 	return GL_NO_ERROR;
1593 }
1594 
getBuffer(GLenum target,es2::Buffer ** buffer) const1595 bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
1596 {
1597 	switch(target)
1598 	{
1599 	case GL_ARRAY_BUFFER:
1600 		*buffer = getArrayBuffer();
1601 		break;
1602 	case GL_ELEMENT_ARRAY_BUFFER:
1603 		*buffer = getElementArrayBuffer();
1604 		break;
1605 	case GL_COPY_READ_BUFFER:
1606 		if(clientVersion >= 3)
1607 		{
1608 			*buffer = getCopyReadBuffer();
1609 			break;
1610 		}
1611 		else return false;
1612 	case GL_COPY_WRITE_BUFFER:
1613 		if(clientVersion >= 3)
1614 		{
1615 			*buffer = getCopyWriteBuffer();
1616 			break;
1617 		}
1618 		else return false;
1619 	case GL_PIXEL_PACK_BUFFER:
1620 		if(clientVersion >= 3)
1621 		{
1622 			*buffer = getPixelPackBuffer();
1623 			break;
1624 		}
1625 		else return false;
1626 	case GL_PIXEL_UNPACK_BUFFER:
1627 		if(clientVersion >= 3)
1628 		{
1629 			*buffer = getPixelUnpackBuffer();
1630 			break;
1631 		}
1632 		else return false;
1633 	case GL_TRANSFORM_FEEDBACK_BUFFER:
1634 		if(clientVersion >= 3)
1635 		{
1636 			TransformFeedback* transformFeedback = getTransformFeedback();
1637 			*buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;
1638 			break;
1639 		}
1640 		else return false;
1641 	case GL_UNIFORM_BUFFER:
1642 		if(clientVersion >= 3)
1643 		{
1644 			*buffer = getGenericUniformBuffer();
1645 			break;
1646 		}
1647 		else return false;
1648 	default:
1649 		return false;
1650 	}
1651 	return true;
1652 }
1653 
getTransformFeedback() const1654 TransformFeedback *Context::getTransformFeedback() const
1655 {
1656 	return getTransformFeedback(mState.transformFeedback);
1657 }
1658 
getCurrentProgram() const1659 Program *Context::getCurrentProgram() const
1660 {
1661 	return mResourceManager->getProgram(mState.currentProgram);
1662 }
1663 
getTexture2D() const1664 Texture2D *Context::getTexture2D() const
1665 {
1666 	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1667 }
1668 
getTexture2D(GLenum target) const1669 Texture2D *Context::getTexture2D(GLenum target) const
1670 {
1671 	switch(target)
1672 	{
1673 	case GL_TEXTURE_2D:            return getTexture2D();
1674 	case GL_TEXTURE_RECTANGLE_ARB: return getTexture2DRect();
1675 	case GL_TEXTURE_EXTERNAL_OES:  return getTextureExternal();
1676 	default:                       UNREACHABLE(target);
1677 	}
1678 
1679 	return nullptr;
1680 }
1681 
getTexture3D() const1682 Texture3D *Context::getTexture3D() const
1683 {
1684 	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1685 }
1686 
getTexture2DArray() const1687 Texture2DArray *Context::getTexture2DArray() const
1688 {
1689 	return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1690 }
1691 
getTextureCubeMap() const1692 TextureCubeMap *Context::getTextureCubeMap() const
1693 {
1694 	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1695 }
1696 
getTexture2DRect() const1697 Texture2DRect *Context::getTexture2DRect() const
1698 {
1699 	return static_cast<Texture2DRect*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_RECT));
1700 }
1701 
getTextureExternal() const1702 TextureExternal *Context::getTextureExternal() const
1703 {
1704 	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1705 }
1706 
getSamplerTexture(unsigned int sampler,TextureType type) const1707 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1708 {
1709 	GLuint texid = mState.samplerTexture[type][sampler].name();
1710 
1711 	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1712 	{
1713 		switch(type)
1714 		{
1715 		case TEXTURE_2D: return mTexture2DZero;
1716 		case TEXTURE_3D: return mTexture3DZero;
1717 		case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
1718 		case TEXTURE_CUBE: return mTextureCubeMapZero;
1719 		case TEXTURE_2D_RECT: return mTexture2DRectZero;
1720 		case TEXTURE_EXTERNAL: return mTextureExternalZero;
1721 		default: UNREACHABLE(type);
1722 		}
1723 	}
1724 
1725 	return mState.samplerTexture[type][sampler];
1726 }
1727 
samplerParameteri(GLuint sampler,GLenum pname,GLint param)1728 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1729 {
1730 	mResourceManager->checkSamplerAllocation(sampler);
1731 
1732 	Sampler *samplerObject = getSampler(sampler);
1733 	ASSERT(samplerObject);
1734 
1735 	switch(pname)
1736 	{
1737 	case GL_TEXTURE_MIN_FILTER:   samplerObject->setMinFilter(static_cast<GLenum>(param));   break;
1738 	case GL_TEXTURE_MAG_FILTER:   samplerObject->setMagFilter(static_cast<GLenum>(param));   break;
1739 	case GL_TEXTURE_WRAP_S:       samplerObject->setWrapS(static_cast<GLenum>(param));       break;
1740 	case GL_TEXTURE_WRAP_T:       samplerObject->setWrapT(static_cast<GLenum>(param));       break;
1741 	case GL_TEXTURE_WRAP_R:       samplerObject->setWrapR(static_cast<GLenum>(param));       break;
1742 	case GL_TEXTURE_MIN_LOD:      samplerObject->setMinLod(static_cast<GLfloat>(param));     break;
1743 	case GL_TEXTURE_MAX_LOD:      samplerObject->setMaxLod(static_cast<GLfloat>(param));     break;
1744 	case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1745 	case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1746 	default:                      UNREACHABLE(pname); break;
1747 	}
1748 }
1749 
samplerParameterf(GLuint sampler,GLenum pname,GLfloat param)1750 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1751 {
1752 	mResourceManager->checkSamplerAllocation(sampler);
1753 
1754 	Sampler *samplerObject = getSampler(sampler);
1755 	ASSERT(samplerObject);
1756 
1757 	switch(pname)
1758 	{
1759 	case GL_TEXTURE_MIN_FILTER:   samplerObject->setMinFilter(static_cast<GLenum>(roundf(param)));   break;
1760 	case GL_TEXTURE_MAG_FILTER:   samplerObject->setMagFilter(static_cast<GLenum>(roundf(param)));   break;
1761 	case GL_TEXTURE_WRAP_S:       samplerObject->setWrapS(static_cast<GLenum>(roundf(param)));       break;
1762 	case GL_TEXTURE_WRAP_T:       samplerObject->setWrapT(static_cast<GLenum>(roundf(param)));       break;
1763 	case GL_TEXTURE_WRAP_R:       samplerObject->setWrapR(static_cast<GLenum>(roundf(param)));       break;
1764 	case GL_TEXTURE_MIN_LOD:      samplerObject->setMinLod(param);                                   break;
1765 	case GL_TEXTURE_MAX_LOD:      samplerObject->setMaxLod(param);                                   break;
1766 	case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(roundf(param))); break;
1767 	case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(roundf(param))); break;
1768 	default:                      UNREACHABLE(pname); break;
1769 	}
1770 }
1771 
getSamplerParameteri(GLuint sampler,GLenum pname)1772 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1773 {
1774 	mResourceManager->checkSamplerAllocation(sampler);
1775 
1776 	Sampler *samplerObject = getSampler(sampler);
1777 	ASSERT(samplerObject);
1778 
1779 	switch(pname)
1780 	{
1781 	case GL_TEXTURE_MIN_FILTER:   return static_cast<GLint>(samplerObject->getMinFilter());
1782 	case GL_TEXTURE_MAG_FILTER:   return static_cast<GLint>(samplerObject->getMagFilter());
1783 	case GL_TEXTURE_WRAP_S:       return static_cast<GLint>(samplerObject->getWrapS());
1784 	case GL_TEXTURE_WRAP_T:       return static_cast<GLint>(samplerObject->getWrapT());
1785 	case GL_TEXTURE_WRAP_R:       return static_cast<GLint>(samplerObject->getWrapR());
1786 	case GL_TEXTURE_MIN_LOD:      return static_cast<GLint>(roundf(samplerObject->getMinLod()));
1787 	case GL_TEXTURE_MAX_LOD:      return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
1788 	case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1789 	case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1790 	default:                      UNREACHABLE(pname); return 0;
1791 	}
1792 }
1793 
getSamplerParameterf(GLuint sampler,GLenum pname)1794 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1795 {
1796 	mResourceManager->checkSamplerAllocation(sampler);
1797 
1798 	Sampler *samplerObject = getSampler(sampler);
1799 	ASSERT(samplerObject);
1800 
1801 	switch(pname)
1802 	{
1803 	case GL_TEXTURE_MIN_FILTER:   return static_cast<GLfloat>(samplerObject->getMinFilter());
1804 	case GL_TEXTURE_MAG_FILTER:   return static_cast<GLfloat>(samplerObject->getMagFilter());
1805 	case GL_TEXTURE_WRAP_S:       return static_cast<GLfloat>(samplerObject->getWrapS());
1806 	case GL_TEXTURE_WRAP_T:       return static_cast<GLfloat>(samplerObject->getWrapT());
1807 	case GL_TEXTURE_WRAP_R:       return static_cast<GLfloat>(samplerObject->getWrapR());
1808 	case GL_TEXTURE_MIN_LOD:      return samplerObject->getMinLod();
1809 	case GL_TEXTURE_MAX_LOD:      return samplerObject->getMaxLod();
1810 	case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1811 	case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1812 	default:                      UNREACHABLE(pname); return 0;
1813 	}
1814 }
1815 
getBooleanv(GLenum pname,GLboolean * params) const1816 bool Context::getBooleanv(GLenum pname, GLboolean *params) const
1817 {
1818 	switch(pname)
1819 	{
1820 	case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
1821 	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
1822 	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
1823 	case GL_COLOR_WRITEMASK:
1824 		params[0] = mState.colorMaskRed;
1825 		params[1] = mState.colorMaskGreen;
1826 		params[2] = mState.colorMaskBlue;
1827 		params[3] = mState.colorMaskAlpha;
1828 		break;
1829 	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;                  break;
1830 	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;         break;
1831 	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled;     break;
1832 	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;            break;
1833 	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;               break;
1834 	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;               break;
1835 	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;                 break;
1836 	case GL_BLEND:                    *params = mState.blendEnabled;                     break;
1837 	case GL_DITHER:                   *params = mState.ditherEnabled;                    break;
1838 	case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
1839 	case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscardEnabled;         break;
1840 	case GL_TRANSFORM_FEEDBACK_ACTIVE:
1841 		{
1842 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1843 			if(transformFeedback)
1844 			{
1845 				*params = transformFeedback->isActive();
1846 				break;
1847 			}
1848 			else return false;
1849 		}
1850 	 case GL_TRANSFORM_FEEDBACK_PAUSED:
1851 		{
1852 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1853 			if(transformFeedback)
1854 			{
1855 				*params = transformFeedback->isPaused();
1856 				break;
1857 			}
1858 			else return false;
1859 		}
1860 	default:
1861 		return false;
1862 	}
1863 
1864 	return true;
1865 }
1866 
getFloatv(GLenum pname,GLfloat * params) const1867 bool Context::getFloatv(GLenum pname, GLfloat *params) const
1868 {
1869 	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1870 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1871 	// GetIntegerv as its native query function. As it would require conversion in any
1872 	// case, this should make no difference to the calling application.
1873 	switch(pname)
1874 	{
1875 	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1876 	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1877 	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1878 	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1879 	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1880 	case GL_ALIASED_LINE_WIDTH_RANGE:
1881 		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1882 		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1883 		break;
1884 	case GL_ALIASED_POINT_SIZE_RANGE:
1885 		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1886 		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1887 		break;
1888 	case GL_DEPTH_RANGE:
1889 		params[0] = mState.zNear;
1890 		params[1] = mState.zFar;
1891 		break;
1892 	case GL_COLOR_CLEAR_VALUE:
1893 		params[0] = mState.colorClearValue.red;
1894 		params[1] = mState.colorClearValue.green;
1895 		params[2] = mState.colorClearValue.blue;
1896 		params[3] = mState.colorClearValue.alpha;
1897 		break;
1898 	case GL_BLEND_COLOR:
1899 		params[0] = mState.blendColor.red;
1900 		params[1] = mState.blendColor.green;
1901 		params[2] = mState.blendColor.blue;
1902 		params[3] = mState.blendColor.alpha;
1903 		break;
1904 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1905 		*params = MAX_TEXTURE_MAX_ANISOTROPY;
1906 		break;
1907 	default:
1908 		return false;
1909 	}
1910 
1911 	return true;
1912 }
1913 
1914 template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
1915 template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
1916 
getIntegerv(GLenum pname,T * params) const1917 template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
1918 {
1919 	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1920 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1921 	// GetIntegerv as its native query function. As it would require conversion in any
1922 	// case, this should make no difference to the calling application. You may find it in
1923 	// Context::getFloatv.
1924 	switch(pname)
1925 	{
1926 	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               return true;
1927 	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       return true;
1928 	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              return true;
1929 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; return true;
1930 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return true;
1931 	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          return true;
1932 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     return true;
1933 	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; return true;
1934 	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    return true;
1935 	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          return true;
1936 	case GL_ARRAY_BUFFER_BINDING:             *params = getArrayBufferName();                 return true;
1937 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = getElementArrayBufferName();          return true;
1938 //	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1939 	case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               return true;
1940 	case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               return true;
1941 	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           return true;
1942 	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                return true;
1943 	case GL_PACK_ALIGNMENT:                   *params = mState.packParameters.alignment;                 return true;
1944 	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackParameters.alignment;          return true;
1945 	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            return true;
1946 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; return true;
1947 	case GL_TEXTURE_FILTERING_HINT_CHROMIUM:  *params = mState.textureFilteringHint;          return true;
1948 	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); return true;
1949 	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   return true;
1950 	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    return true;
1951 	case GL_STENCIL_VALUE_MASK:               *params = sw::clampToSignedInt(mState.stencilMask); return true;
1952 	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               return true;
1953 	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                return true;
1954 	case GL_STENCIL_BACK_VALUE_MASK:          *params = sw::clampToSignedInt(mState.stencilBackMask); return true;
1955 	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   return true;
1956 	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          return true;
1957 	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          return true;
1958 	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               return true;
1959 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      return true;
1960 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      return true;
1961 	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     return true;
1962 	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                return true;
1963 	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              return true;
1964 	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  return true;
1965 	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                return true;
1966 	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              return true;
1967 	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            return true;
1968 	case GL_STENCIL_WRITEMASK:                *params = sw::clampToSignedInt(mState.stencilWritemask); return true;
1969 	case GL_STENCIL_BACK_WRITEMASK:           *params = sw::clampToSignedInt(mState.stencilBackWritemask); return true;
1970 	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             return true;
1971 	case GL_SUBPIXEL_BITS:                    *params = 4;                                    return true;
1972 	case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
1973 	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          return true;
1974 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; return true;
1975 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           return true;
1976 	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;               return true;
1977 	case GL_SAMPLE_BUFFERS:
1978 	case GL_SAMPLES:
1979 		{
1980 			Framebuffer *framebuffer = getDrawFramebuffer();
1981 			int width, height, samples;
1982 
1983 			if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE))
1984 			{
1985 				switch(pname)
1986 				{
1987 				case GL_SAMPLE_BUFFERS:
1988 					if(samples > 1)
1989 					{
1990 						*params = 1;
1991 					}
1992 					else
1993 					{
1994 						*params = 0;
1995 					}
1996 					break;
1997 				case GL_SAMPLES:
1998 					*params = samples;
1999 					break;
2000 				}
2001 			}
2002 			else
2003 			{
2004 				*params = 0;
2005 			}
2006 		}
2007 		return true;
2008 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2009 		{
2010 			Framebuffer *framebuffer = getReadFramebuffer();
2011 			if(framebuffer)
2012 			{
2013 				*params = framebuffer->getImplementationColorReadType();
2014 			}
2015 			else
2016 			{
2017 				return error(GL_INVALID_OPERATION, true);
2018 			}
2019 		}
2020 		return true;
2021 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2022 		{
2023 			Framebuffer *framebuffer = getReadFramebuffer();
2024 			if(framebuffer)
2025 			{
2026 				*params = framebuffer->getImplementationColorReadFormat();
2027 			}
2028 			else
2029 			{
2030 				return error(GL_INVALID_OPERATION, true);
2031 			}
2032 		}
2033 		return true;
2034 	case GL_MAX_VIEWPORT_DIMS:
2035 		{
2036 			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
2037 			params[0] = maxDimension;
2038 			params[1] = maxDimension;
2039 		}
2040 		return true;
2041 	case GL_COMPRESSED_TEXTURE_FORMATS:
2042 		{
2043 			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
2044 			{
2045 				params[i] = compressedTextureFormats[i];
2046 			}
2047 		}
2048 		return true;
2049 	case GL_VIEWPORT:
2050 		params[0] = mState.viewportX;
2051 		params[1] = mState.viewportY;
2052 		params[2] = mState.viewportWidth;
2053 		params[3] = mState.viewportHeight;
2054 		return true;
2055 	case GL_SCISSOR_BOX:
2056 		params[0] = mState.scissorX;
2057 		params[1] = mState.scissorY;
2058 		params[2] = mState.scissorWidth;
2059 		params[3] = mState.scissorHeight;
2060 		return true;
2061 	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 return true;
2062 	case GL_FRONT_FACE:                       *params = mState.frontFace;                return true;
2063 	case GL_RED_BITS:
2064 	case GL_GREEN_BITS:
2065 	case GL_BLUE_BITS:
2066 	case GL_ALPHA_BITS:
2067 		{
2068 			Framebuffer *framebuffer = getDrawFramebuffer();
2069 			Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer(0) : nullptr;
2070 
2071 			if(colorbuffer)
2072 			{
2073 				switch(pname)
2074 				{
2075 				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   return true;
2076 				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); return true;
2077 				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  return true;
2078 				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); return true;
2079 				}
2080 			}
2081 			else
2082 			{
2083 				*params = 0;
2084 			}
2085 		}
2086 		return true;
2087 	case GL_DEPTH_BITS:
2088 		{
2089 			Framebuffer *framebuffer = getDrawFramebuffer();
2090 			Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
2091 
2092 			if(depthbuffer)
2093 			{
2094 				*params = depthbuffer->getDepthSize();
2095 			}
2096 			else
2097 			{
2098 				*params = 0;
2099 			}
2100 		}
2101 		return true;
2102 	case GL_STENCIL_BITS:
2103 		{
2104 			Framebuffer *framebuffer = getDrawFramebuffer();
2105 			Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
2106 
2107 			if(stencilbuffer)
2108 			{
2109 				*params = stencilbuffer->getStencilSize();
2110 			}
2111 			else
2112 			{
2113 				*params = 0;
2114 			}
2115 		}
2116 		return true;
2117 	case GL_TEXTURE_BINDING_2D:
2118 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2119 		{
2120 			error(GL_INVALID_OPERATION);
2121 			return false;
2122 		}
2123 
2124 		*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
2125 		return true;
2126 	case GL_TEXTURE_BINDING_CUBE_MAP:
2127 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2128 		{
2129 			error(GL_INVALID_OPERATION);
2130 			return false;
2131 		}
2132 
2133 		*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
2134 		return true;
2135 	case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2136 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2137 		{
2138 			error(GL_INVALID_OPERATION);
2139 			return false;
2140 		}
2141 
2142 		*params = mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler].name();
2143 		return true;
2144 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
2145 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2146 		{
2147 			error(GL_INVALID_OPERATION);
2148 			return false;
2149 		}
2150 
2151 		*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
2152 		return true;
2153 	case GL_TEXTURE_BINDING_3D_OES:
2154 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2155 		{
2156 			error(GL_INVALID_OPERATION);
2157 			return false;
2158 		}
2159 
2160 		*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
2161 		return true;
2162 	case GL_DRAW_BUFFER0:
2163 	case GL_DRAW_BUFFER1:
2164 	case GL_DRAW_BUFFER2:
2165 	case GL_DRAW_BUFFER3:
2166 	case GL_DRAW_BUFFER4:
2167 	case GL_DRAW_BUFFER5:
2168 	case GL_DRAW_BUFFER6:
2169 	case GL_DRAW_BUFFER7:
2170 	case GL_DRAW_BUFFER8:
2171 	case GL_DRAW_BUFFER9:
2172 	case GL_DRAW_BUFFER10:
2173 	case GL_DRAW_BUFFER11:
2174 	case GL_DRAW_BUFFER12:
2175 	case GL_DRAW_BUFFER13:
2176 	case GL_DRAW_BUFFER14:
2177 	case GL_DRAW_BUFFER15:
2178 		if((pname - GL_DRAW_BUFFER0) < MAX_DRAW_BUFFERS)
2179 		{
2180 			Framebuffer* framebuffer = getDrawFramebuffer();
2181 			*params = framebuffer ? framebuffer->getDrawBuffer(pname - GL_DRAW_BUFFER0) : GL_NONE;
2182 		}
2183 		else
2184 		{
2185 			return false;
2186 		}
2187 		return true;
2188 	case GL_MAX_DRAW_BUFFERS:
2189 		*params = MAX_DRAW_BUFFERS;
2190 		return true;
2191 	case GL_MAX_COLOR_ATTACHMENTS: // Note: MAX_COLOR_ATTACHMENTS_EXT added by GL_EXT_draw_buffers
2192 		*params = MAX_COLOR_ATTACHMENTS;
2193 		return true;
2194 	default:
2195 		break;
2196 	}
2197 
2198 	if(clientVersion >= 3)
2199 	{
2200 		switch(pname)
2201 		{
2202 		case GL_TEXTURE_BINDING_2D_ARRAY:
2203 			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2204 			{
2205 				error(GL_INVALID_OPERATION);
2206 				return false;
2207 			}
2208 
2209 			*params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
2210 			return true;
2211 		case GL_COPY_READ_BUFFER_BINDING:
2212 			*params = mState.copyReadBuffer.name();
2213 			return true;
2214 		case GL_COPY_WRITE_BUFFER_BINDING:
2215 			*params = mState.copyWriteBuffer.name();
2216 			return true;
2217 		case GL_MAJOR_VERSION:
2218 			*params = clientVersion;
2219 			return true;
2220 		case GL_MAX_3D_TEXTURE_SIZE:
2221 			*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2222 			return true;
2223 		case GL_MAX_ARRAY_TEXTURE_LAYERS:
2224 			*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2225 			return true;
2226 		case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2227 			*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
2228 			return true;
2229 		case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2230 			*params = MAX_VERTEX_UNIFORM_BLOCKS + MAX_FRAGMENT_UNIFORM_BLOCKS;
2231 			return true;
2232 		case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2233 			*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
2234 			return true;
2235 		case GL_MAX_ELEMENT_INDEX:
2236 			*params = MAX_ELEMENT_INDEX;
2237 			return true;
2238 		case GL_MAX_ELEMENTS_INDICES:
2239 			*params = MAX_ELEMENTS_INDICES;
2240 			return true;
2241 		case GL_MAX_ELEMENTS_VERTICES:
2242 			*params = MAX_ELEMENTS_VERTICES;
2243 			return true;
2244 		case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2245 			*params = MAX_FRAGMENT_INPUT_VECTORS * 4;
2246 			return true;
2247 		case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2248 			*params = MAX_FRAGMENT_UNIFORM_BLOCKS;
2249 			return true;
2250 		case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2251 			*params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
2252 			return true;
2253 		case GL_MAX_PROGRAM_TEXEL_OFFSET:
2254 			// Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2255 			// In any case, any behavior outside the specified range is valid since the spec mentions:
2256 			// (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2257 			// "If any of the offset values are outside the range of the  implementation-defined values
2258 			//  MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2259 			//  undefined."
2260 			*params = MAX_PROGRAM_TEXEL_OFFSET;
2261 			return true;
2262 		case GL_MAX_SERVER_WAIT_TIMEOUT:
2263 			*params = 0;
2264 			return true;
2265 		case GL_MAX_TEXTURE_LOD_BIAS:
2266 			*params = MAX_TEXTURE_LOD_BIAS;
2267 			return true;
2268 		case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2269 			*params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
2270 			return true;
2271 		case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2272 			*params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
2273 			return true;
2274 		case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2275 			*params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
2276 			return true;
2277 		case GL_MAX_UNIFORM_BLOCK_SIZE:
2278 			*params = MAX_UNIFORM_BLOCK_SIZE;
2279 			return true;
2280 		case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2281 			*params = MAX_UNIFORM_BUFFER_BINDINGS;
2282 			return true;
2283 		case GL_MAX_VARYING_COMPONENTS:
2284 			*params = MAX_VARYING_VECTORS * 4;
2285 			return true;
2286 		case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2287 			*params = MAX_VERTEX_OUTPUT_VECTORS * 4;
2288 			return true;
2289 		case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2290 			*params = MAX_VERTEX_UNIFORM_BLOCKS;
2291 			return true;
2292 		case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2293 			*params = MAX_VERTEX_UNIFORM_COMPONENTS;
2294 			return true;
2295 		case GL_MIN_PROGRAM_TEXEL_OFFSET:
2296 			// Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2297 			// In any case, any behavior outside the specified range is valid since the spec mentions:
2298 			// (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2299 			// "If any of the offset values are outside the range of the  implementation-defined values
2300 			//  MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2301 			//  undefined."
2302 			*params = MIN_PROGRAM_TEXEL_OFFSET;
2303 			return true;
2304 		case GL_MINOR_VERSION:
2305 			*params = 0;
2306 			return true;
2307 		case GL_NUM_EXTENSIONS:
2308 			GLuint numExtensions;
2309 			getExtensions(0, &numExtensions);
2310 			*params = numExtensions;
2311 			return true;
2312 		case GL_NUM_PROGRAM_BINARY_FORMATS:
2313 			*params = NUM_PROGRAM_BINARY_FORMATS;
2314 			return true;
2315 		case GL_PACK_ROW_LENGTH:
2316 			*params = mState.packParameters.rowLength;
2317 			return true;
2318 		case GL_PACK_SKIP_PIXELS:
2319 			*params = mState.packParameters.skipPixels;
2320 			return true;
2321 		case GL_PACK_SKIP_ROWS:
2322 			*params = mState.packParameters.skipRows;
2323 			return true;
2324 		case GL_PIXEL_PACK_BUFFER_BINDING:
2325 			*params = mState.pixelPackBuffer.name();
2326 			return true;
2327 		case GL_PIXEL_UNPACK_BUFFER_BINDING:
2328 			*params = mState.pixelUnpackBuffer.name();
2329 			return true;
2330 		case GL_PROGRAM_BINARY_FORMATS:
2331 			// Since NUM_PROGRAM_BINARY_FORMATS is 0, the input
2332 			// should be a 0 sized array, so don't write to params
2333 			return true;
2334 		case GL_READ_BUFFER:
2335 			{
2336 				Framebuffer* framebuffer = getReadFramebuffer();
2337 				*params = framebuffer ? framebuffer->getReadBuffer() : GL_NONE;
2338 			}
2339 			return true;
2340 		case GL_SAMPLER_BINDING:
2341 			*params = mState.sampler[mState.activeSampler].name();
2342 			return true;
2343 		case GL_UNIFORM_BUFFER_BINDING:
2344 			*params = mState.genericUniformBuffer.name();
2345 			return true;
2346 		case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2347 			*params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
2348 			return true;
2349 		case GL_UNIFORM_BUFFER_SIZE:
2350 			*params = static_cast<T>(mState.genericUniformBuffer->size());
2351 			return true;
2352 		case GL_UNIFORM_BUFFER_START:
2353 			*params = static_cast<T>(mState.genericUniformBuffer->offset());
2354 			return true;
2355 		case GL_UNPACK_IMAGE_HEIGHT:
2356 			*params = mState.unpackParameters.imageHeight;
2357 			return true;
2358 		case GL_UNPACK_ROW_LENGTH:
2359 			*params = mState.unpackParameters.rowLength;
2360 			return true;
2361 		case GL_UNPACK_SKIP_IMAGES:
2362 			*params = mState.unpackParameters.skipImages;
2363 			return true;
2364 		case GL_UNPACK_SKIP_PIXELS:
2365 			*params = mState.unpackParameters.skipPixels;
2366 			return true;
2367 		case GL_UNPACK_SKIP_ROWS:
2368 			*params = mState.unpackParameters.skipRows;
2369 			return true;
2370 		case GL_VERTEX_ARRAY_BINDING:
2371 			*params = getCurrentVertexArray()->name;
2372 			return true;
2373 		case GL_TRANSFORM_FEEDBACK_BINDING:
2374 			{
2375 				TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2376 				if(transformFeedback)
2377 				{
2378 					*params = transformFeedback->name;
2379 				}
2380 				else
2381 				{
2382 					return false;
2383 				}
2384 			}
2385 			return true;
2386 		case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2387 			{
2388 				TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2389 				if(transformFeedback)
2390 				{
2391 					*params = transformFeedback->getGenericBufferName();
2392 				}
2393 				else
2394 				{
2395 					return false;
2396 				}
2397 			}
2398 			return true;
2399 		default:
2400 			break;
2401 		}
2402 	}
2403 
2404 	return false;
2405 }
2406 
2407 template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2408 template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2409 
getTransformFeedbackiv(GLuint index,GLenum pname,T * param) const2410 template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
2411 {
2412 	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2413 	if(!transformFeedback)
2414 	{
2415 		return false;
2416 	}
2417 
2418 	switch(pname)
2419 	{
2420 	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
2421 		*param = transformFeedback->name;
2422 		break;
2423 	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
2424 		*param = transformFeedback->isActive();
2425 		break;
2426 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
2427 		*param = transformFeedback->getBufferName(index);
2428 		break;
2429 	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
2430 		*param = transformFeedback->isPaused();
2431 		break;
2432 	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2433 		if(transformFeedback->getBuffer(index))
2434 		{
2435 			*param = transformFeedback->getSize(index);
2436 			break;
2437 		}
2438 		else return false;
2439 	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2440 		if(transformFeedback->getBuffer(index))
2441 		{
2442 			*param = transformFeedback->getOffset(index);
2443 		break;
2444 		}
2445 		else return false;
2446 	default:
2447 		return false;
2448 	}
2449 
2450 	return true;
2451 }
2452 
2453 template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2454 template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2455 
getUniformBufferiv(GLuint index,GLenum pname,T * param) const2456 template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
2457 {
2458 	switch(pname)
2459 	{
2460 	case GL_UNIFORM_BUFFER_BINDING:
2461 	case GL_UNIFORM_BUFFER_SIZE:
2462 	case GL_UNIFORM_BUFFER_START:
2463 		if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
2464 		{
2465 			return error(GL_INVALID_VALUE, true);
2466 		}
2467 		break;
2468 	default:
2469 		break;
2470 	}
2471 
2472 	const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
2473 
2474 	switch(pname)
2475 	{
2476 	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2477 		*param = uniformBuffer.get().name();
2478 		break;
2479 	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2480 		*param = uniformBuffer.getSize();
2481 		break;
2482 	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2483 		*param = uniformBuffer.getOffset();
2484 		break;
2485 	default:
2486 		return false;
2487 	}
2488 
2489 	return true;
2490 }
2491 
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams) const2492 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
2493 {
2494 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2495 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2496 	// to the fact that it is stored internally as a float, and so would require conversion
2497 	// if returned from Context::getIntegerv. Since this conversion is already implemented
2498 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2499 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2500 	// application.
2501 	switch(pname)
2502 	{
2503 	case GL_COMPRESSED_TEXTURE_FORMATS:
2504 		{
2505 			*type = GL_INT;
2506 			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
2507 		}
2508 		break;
2509 	case GL_SHADER_BINARY_FORMATS:
2510 		{
2511 			*type = GL_INT;
2512 			*numParams = 0;
2513 		}
2514 		break;
2515 	case GL_MAX_VERTEX_ATTRIBS:
2516 	case GL_MAX_VERTEX_UNIFORM_VECTORS:
2517 	case GL_MAX_VARYING_VECTORS:
2518 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2519 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2520 	case GL_MAX_TEXTURE_IMAGE_UNITS:
2521 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2522 	case GL_MAX_RENDERBUFFER_SIZE:
2523 	case GL_NUM_SHADER_BINARY_FORMATS:
2524 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2525 	case GL_ARRAY_BUFFER_BINDING:
2526 	case GL_FRAMEBUFFER_BINDING:        // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2527 	case GL_READ_FRAMEBUFFER_BINDING:   // Same as GL_READ_FRAMEBUFFER_BINDING_ANGLE
2528 	case GL_RENDERBUFFER_BINDING:
2529 	case GL_CURRENT_PROGRAM:
2530 	case GL_PACK_ALIGNMENT:
2531 	case GL_UNPACK_ALIGNMENT:
2532 	case GL_GENERATE_MIPMAP_HINT:
2533 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2534 	case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2535 	case GL_RED_BITS:
2536 	case GL_GREEN_BITS:
2537 	case GL_BLUE_BITS:
2538 	case GL_ALPHA_BITS:
2539 	case GL_DEPTH_BITS:
2540 	case GL_STENCIL_BITS:
2541 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2542 	case GL_CULL_FACE_MODE:
2543 	case GL_FRONT_FACE:
2544 	case GL_ACTIVE_TEXTURE:
2545 	case GL_STENCIL_FUNC:
2546 	case GL_STENCIL_VALUE_MASK:
2547 	case GL_STENCIL_REF:
2548 	case GL_STENCIL_FAIL:
2549 	case GL_STENCIL_PASS_DEPTH_FAIL:
2550 	case GL_STENCIL_PASS_DEPTH_PASS:
2551 	case GL_STENCIL_BACK_FUNC:
2552 	case GL_STENCIL_BACK_VALUE_MASK:
2553 	case GL_STENCIL_BACK_REF:
2554 	case GL_STENCIL_BACK_FAIL:
2555 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2556 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2557 	case GL_DEPTH_FUNC:
2558 	case GL_BLEND_SRC_RGB:
2559 	case GL_BLEND_SRC_ALPHA:
2560 	case GL_BLEND_DST_RGB:
2561 	case GL_BLEND_DST_ALPHA:
2562 	case GL_BLEND_EQUATION_RGB:
2563 	case GL_BLEND_EQUATION_ALPHA:
2564 	case GL_STENCIL_WRITEMASK:
2565 	case GL_STENCIL_BACK_WRITEMASK:
2566 	case GL_STENCIL_CLEAR_VALUE:
2567 	case GL_SUBPIXEL_BITS:
2568 	case GL_MAX_TEXTURE_SIZE:
2569 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2570 	case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2571 	case GL_SAMPLE_BUFFERS:
2572 	case GL_SAMPLES:
2573 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2574 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2575 	case GL_TEXTURE_BINDING_2D:
2576 	case GL_TEXTURE_BINDING_CUBE_MAP:
2577 	case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2578 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
2579 	case GL_TEXTURE_BINDING_3D_OES:
2580 	case GL_COPY_READ_BUFFER_BINDING:
2581 	case GL_COPY_WRITE_BUFFER_BINDING:
2582 	case GL_DRAW_BUFFER0:
2583 	case GL_DRAW_BUFFER1:
2584 	case GL_DRAW_BUFFER2:
2585 	case GL_DRAW_BUFFER3:
2586 	case GL_DRAW_BUFFER4:
2587 	case GL_DRAW_BUFFER5:
2588 	case GL_DRAW_BUFFER6:
2589 	case GL_DRAW_BUFFER7:
2590 	case GL_DRAW_BUFFER8:
2591 	case GL_DRAW_BUFFER9:
2592 	case GL_DRAW_BUFFER10:
2593 	case GL_DRAW_BUFFER11:
2594 	case GL_DRAW_BUFFER12:
2595 	case GL_DRAW_BUFFER13:
2596 	case GL_DRAW_BUFFER14:
2597 	case GL_DRAW_BUFFER15:
2598 	case GL_MAJOR_VERSION:
2599 	case GL_MAX_3D_TEXTURE_SIZE:
2600 	case GL_MAX_ARRAY_TEXTURE_LAYERS:
2601 	case GL_MAX_COLOR_ATTACHMENTS:
2602 	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2603 	case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2604 	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2605 	case GL_MAX_DRAW_BUFFERS:
2606 	case GL_MAX_ELEMENT_INDEX:
2607 	case GL_MAX_ELEMENTS_INDICES:
2608 	case GL_MAX_ELEMENTS_VERTICES:
2609 	case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2610 	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2611 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2612 	case GL_MAX_PROGRAM_TEXEL_OFFSET:
2613 	case GL_MAX_SERVER_WAIT_TIMEOUT:
2614 	case GL_MAX_TEXTURE_LOD_BIAS:
2615 	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2616 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2617 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2618 	case GL_MAX_UNIFORM_BLOCK_SIZE:
2619 	case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2620 	case GL_MAX_VARYING_COMPONENTS:
2621 	case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2622 	case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2623 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2624 	case GL_MIN_PROGRAM_TEXEL_OFFSET:
2625 	case GL_MINOR_VERSION:
2626 	case GL_NUM_EXTENSIONS:
2627 	case GL_NUM_PROGRAM_BINARY_FORMATS:
2628 	case GL_PACK_ROW_LENGTH:
2629 	case GL_PACK_SKIP_PIXELS:
2630 	case GL_PACK_SKIP_ROWS:
2631 	case GL_PIXEL_PACK_BUFFER_BINDING:
2632 	case GL_PIXEL_UNPACK_BUFFER_BINDING:
2633 	case GL_PROGRAM_BINARY_FORMATS:
2634 	case GL_READ_BUFFER:
2635 	case GL_SAMPLER_BINDING:
2636 	case GL_TEXTURE_BINDING_2D_ARRAY:
2637 	case GL_UNIFORM_BUFFER_BINDING:
2638 	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2639 	case GL_UNIFORM_BUFFER_SIZE:
2640 	case GL_UNIFORM_BUFFER_START:
2641 	case GL_UNPACK_IMAGE_HEIGHT:
2642 	case GL_UNPACK_ROW_LENGTH:
2643 	case GL_UNPACK_SKIP_IMAGES:
2644 	case GL_UNPACK_SKIP_PIXELS:
2645 	case GL_UNPACK_SKIP_ROWS:
2646 	case GL_VERTEX_ARRAY_BINDING:
2647 	case GL_TRANSFORM_FEEDBACK_BINDING:
2648 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2649 		{
2650 			*type = GL_INT;
2651 			*numParams = 1;
2652 		}
2653 		break;
2654 	case GL_MAX_SAMPLES:
2655 		{
2656 			*type = GL_INT;
2657 			*numParams = 1;
2658 		}
2659 		break;
2660 	case GL_MAX_VIEWPORT_DIMS:
2661 		{
2662 			*type = GL_INT;
2663 			*numParams = 2;
2664 		}
2665 		break;
2666 	case GL_VIEWPORT:
2667 	case GL_SCISSOR_BOX:
2668 		{
2669 			*type = GL_INT;
2670 			*numParams = 4;
2671 		}
2672 		break;
2673 	case GL_SHADER_COMPILER:
2674 	case GL_SAMPLE_COVERAGE_INVERT:
2675 	case GL_DEPTH_WRITEMASK:
2676 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
2677 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
2678 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2679 	case GL_SAMPLE_COVERAGE:
2680 	case GL_SCISSOR_TEST:
2681 	case GL_STENCIL_TEST:
2682 	case GL_DEPTH_TEST:
2683 	case GL_BLEND:
2684 	case GL_DITHER:
2685 	case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2686 	case GL_RASTERIZER_DISCARD:
2687 	case GL_TRANSFORM_FEEDBACK_ACTIVE:
2688 	case GL_TRANSFORM_FEEDBACK_PAUSED:
2689 		{
2690 			*type = GL_BOOL;
2691 			*numParams = 1;
2692 		}
2693 		break;
2694 	case GL_COLOR_WRITEMASK:
2695 		{
2696 			*type = GL_BOOL;
2697 			*numParams = 4;
2698 		}
2699 		break;
2700 	case GL_POLYGON_OFFSET_FACTOR:
2701 	case GL_POLYGON_OFFSET_UNITS:
2702 	case GL_SAMPLE_COVERAGE_VALUE:
2703 	case GL_DEPTH_CLEAR_VALUE:
2704 	case GL_LINE_WIDTH:
2705 		{
2706 			*type = GL_FLOAT;
2707 			*numParams = 1;
2708 		}
2709 		break;
2710 	case GL_ALIASED_LINE_WIDTH_RANGE:
2711 	case GL_ALIASED_POINT_SIZE_RANGE:
2712 	case GL_DEPTH_RANGE:
2713 		{
2714 			*type = GL_FLOAT;
2715 			*numParams = 2;
2716 		}
2717 		break;
2718 	case GL_COLOR_CLEAR_VALUE:
2719 	case GL_BLEND_COLOR:
2720 		{
2721 			*type = GL_FLOAT;
2722 			*numParams = 4;
2723 		}
2724 		break;
2725 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2726 		*type = GL_FLOAT;
2727 		*numParams = 1;
2728 		break;
2729 	default:
2730 		return false;
2731 	}
2732 
2733 	return true;
2734 }
2735 
applyScissor(int width,int height)2736 void Context::applyScissor(int width, int height)
2737 {
2738 	if(mState.scissorTestEnabled)
2739 	{
2740 		sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
2741 		scissor.clip(0, 0, width, height);
2742 
2743 		device->setScissorRect(scissor);
2744 		device->setScissorEnable(true);
2745 	}
2746 	else
2747 	{
2748 		device->setScissorEnable(false);
2749 	}
2750 }
2751 
2752 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()2753 bool Context::applyRenderTarget()
2754 {
2755 	Framebuffer *framebuffer = getDrawFramebuffer();
2756 	int width, height, samples;
2757 
2758 	if(!framebuffer || (framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE))
2759 	{
2760 		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2761 	}
2762 
2763 	for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2764 	{
2765 		if(framebuffer->getDrawBuffer(i) != GL_NONE)
2766 		{
2767 			egl::Image *renderTarget = framebuffer->getRenderTarget(i);
2768 			GLint layer = framebuffer->getColorbufferLayer(i);
2769 			device->setRenderTarget(i, renderTarget, layer);
2770 			if(renderTarget) renderTarget->release();
2771 		}
2772 		else
2773 		{
2774 			device->setRenderTarget(i, nullptr, 0);
2775 		}
2776 	}
2777 
2778 	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
2779 	GLint dLayer = framebuffer->getDepthbufferLayer();
2780 	device->setDepthBuffer(depthBuffer, dLayer);
2781 	if(depthBuffer) depthBuffer->release();
2782 
2783 	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
2784 	GLint sLayer = framebuffer->getStencilbufferLayer();
2785 	device->setStencilBuffer(stencilBuffer, sLayer);
2786 	if(stencilBuffer) stencilBuffer->release();
2787 
2788 	Viewport viewport;
2789 	float zNear = clamp01(mState.zNear);
2790 	float zFar = clamp01(mState.zFar);
2791 
2792 	viewport.x0 = mState.viewportX;
2793 	viewport.y0 = mState.viewportY;
2794 	viewport.width = mState.viewportWidth;
2795 	viewport.height = mState.viewportHeight;
2796 	viewport.minZ = zNear;
2797 	viewport.maxZ = zFar;
2798 
2799 	device->setViewport(viewport);
2800 
2801 	applyScissor(width, height);
2802 
2803 	Program *program = getCurrentProgram();
2804 
2805 	if(program)
2806 	{
2807 		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2808 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2809 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2810 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2811 	}
2812 
2813 	return true;
2814 }
2815 
2816 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)2817 void Context::applyState(GLenum drawMode)
2818 {
2819 	Framebuffer *framebuffer = getDrawFramebuffer();
2820 
2821 	if(mState.cullFaceEnabled)
2822 	{
2823 		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
2824 	}
2825 	else
2826 	{
2827 		device->setCullMode(sw::CULL_NONE);
2828 	}
2829 
2830 	if(mDepthStateDirty)
2831 	{
2832 		if(mState.depthTestEnabled)
2833 		{
2834 			device->setDepthBufferEnable(true);
2835 			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2836 		}
2837 		else
2838 		{
2839 			device->setDepthBufferEnable(false);
2840 		}
2841 
2842 		mDepthStateDirty = false;
2843 	}
2844 
2845 	if(mBlendStateDirty)
2846 	{
2847 		if(mState.blendEnabled)
2848 		{
2849 			device->setAlphaBlendEnable(true);
2850 			device->setSeparateAlphaBlendEnable(true);
2851 
2852 			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2853 
2854 			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2855 			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2856 			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2857 
2858 			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2859 			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2860 			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2861 		}
2862 		else
2863 		{
2864 			device->setAlphaBlendEnable(false);
2865 		}
2866 
2867 		mBlendStateDirty = false;
2868 	}
2869 
2870 	if(mStencilStateDirty || mFrontFaceDirty)
2871 	{
2872 		if(mState.stencilTestEnabled && framebuffer->hasStencil())
2873 		{
2874 			device->setStencilEnable(true);
2875 			device->setTwoSidedStencil(true);
2876 
2877 			// get the maximum size of the stencil ref
2878 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2879 			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2880 
2881 			if(mState.frontFace == GL_CCW)
2882 			{
2883 				device->setStencilWriteMask(mState.stencilWritemask);
2884 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2885 
2886 				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2887 				device->setStencilMask(mState.stencilMask);
2888 
2889 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2890 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2891 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2892 
2893 				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2894 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2895 
2896 				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2897 				device->setStencilMaskCCW(mState.stencilBackMask);
2898 
2899 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2900 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2901 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2902 			}
2903 			else
2904 			{
2905 				device->setStencilWriteMaskCCW(mState.stencilWritemask);
2906 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2907 
2908 				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2909 				device->setStencilMaskCCW(mState.stencilMask);
2910 
2911 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2912 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2913 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2914 
2915 				device->setStencilWriteMask(mState.stencilBackWritemask);
2916 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2917 
2918 				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2919 				device->setStencilMask(mState.stencilBackMask);
2920 
2921 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2922 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2923 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2924 			}
2925 		}
2926 		else
2927 		{
2928 			device->setStencilEnable(false);
2929 		}
2930 
2931 		mStencilStateDirty = false;
2932 		mFrontFaceDirty = false;
2933 	}
2934 
2935 	if(mMaskStateDirty)
2936 	{
2937 		for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2938 		{
2939 			device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2940 		}
2941 
2942 		device->setDepthWriteEnable(mState.depthMask);
2943 
2944 		mMaskStateDirty = false;
2945 	}
2946 
2947 	if(mPolygonOffsetStateDirty)
2948 	{
2949 		if(mState.polygonOffsetFillEnabled)
2950 		{
2951 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2952 			if(depthbuffer)
2953 			{
2954 				device->setSlopeDepthBias(mState.polygonOffsetFactor);
2955 				float depthBias = ldexp(mState.polygonOffsetUnits, -23);   // We use 32-bit floating-point for all depth formats, with 23 mantissa bits.
2956 				device->setDepthBias(depthBias);
2957 			}
2958 		}
2959 		else
2960 		{
2961 			device->setSlopeDepthBias(0);
2962 			device->setDepthBias(0);
2963 		}
2964 
2965 		mPolygonOffsetStateDirty = false;
2966 	}
2967 
2968 	if(mSampleStateDirty)
2969 	{
2970 		if(mState.sampleAlphaToCoverageEnabled)
2971 		{
2972 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
2973 		}
2974 		else
2975 		{
2976 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
2977 		}
2978 
2979 		if(mState.sampleCoverageEnabled)
2980 		{
2981 			unsigned int mask = 0;
2982 			if(mState.sampleCoverageValue != 0)
2983 			{
2984 				int width, height, samples;
2985 				framebuffer->completeness(width, height, samples);
2986 
2987 				float threshold = 0.5f;
2988 
2989 				for(int i = 0; i < samples; i++)
2990 				{
2991 					mask <<= 1;
2992 
2993 					if((i + 1) * mState.sampleCoverageValue >= threshold)
2994 					{
2995 						threshold += 1.0f;
2996 						mask |= 1;
2997 					}
2998 				}
2999 			}
3000 
3001 			if(mState.sampleCoverageInvert)
3002 			{
3003 				mask = ~mask;
3004 			}
3005 
3006 			device->setMultiSampleMask(mask);
3007 		}
3008 		else
3009 		{
3010 			device->setMultiSampleMask(0xFFFFFFFF);
3011 		}
3012 
3013 		mSampleStateDirty = false;
3014 	}
3015 
3016 	if(mDitherStateDirty)
3017 	{
3018 	//	UNIMPLEMENTED();   // FIXME
3019 
3020 		mDitherStateDirty = false;
3021 	}
3022 
3023 	device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
3024 }
3025 
applyVertexBuffer(GLint base,GLint first,GLsizei count,GLsizei instanceId)3026 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
3027 {
3028 	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
3029 
3030 	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
3031 	if(err != GL_NO_ERROR)
3032 	{
3033 		return err;
3034 	}
3035 
3036 	Program *program = getCurrentProgram();
3037 
3038 	device->resetInputStreams(false);
3039 
3040 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3041 	{
3042 		if(program->getAttributeStream(i) == -1)
3043 		{
3044 			continue;
3045 		}
3046 
3047 		sw::Resource *resource = attributes[i].vertexBuffer;
3048 		const void *buffer = (char*)resource->data() + attributes[i].offset;
3049 
3050 		int stride = attributes[i].stride;
3051 
3052 		buffer = (char*)buffer + stride * base;
3053 
3054 		sw::Stream attribute(resource, buffer, stride);
3055 
3056 		attribute.type = attributes[i].type;
3057 		attribute.count = attributes[i].count;
3058 		attribute.normalized = attributes[i].normalized;
3059 
3060 		int stream = program->getAttributeStream(i);
3061 		device->setInputStream(stream, attribute);
3062 	}
3063 
3064 	return GL_NO_ERROR;
3065 }
3066 
3067 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLuint start,GLuint end,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)3068 GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
3069 {
3070 	GLenum err = mIndexDataManager->prepareIndexData(mode, type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo, isPrimitiveRestartFixedIndexEnabled());
3071 
3072 	if(err == GL_NO_ERROR)
3073 	{
3074 		device->setIndexBuffer(indexInfo->indexBuffer);
3075 	}
3076 
3077 	return err;
3078 }
3079 
3080 // Applies the shaders and shader constants
applyShaders()3081 void Context::applyShaders()
3082 {
3083 	Program *programObject = getCurrentProgram();
3084 	sw::VertexShader *vertexShader = programObject->getVertexShader();
3085 	sw::PixelShader *pixelShader = programObject->getPixelShader();
3086 
3087 	device->setVertexShader(vertexShader);
3088 	device->setPixelShader(pixelShader);
3089 
3090 	if(programObject->getSerial() != mAppliedProgramSerial)
3091 	{
3092 		programObject->dirtyAllUniforms();
3093 		mAppliedProgramSerial = programObject->getSerial();
3094 	}
3095 
3096 	programObject->applyTransformFeedback(device, getTransformFeedback());
3097 	programObject->applyUniformBuffers(device, mState.uniformBuffers);
3098 	programObject->applyUniforms(device);
3099 }
3100 
applyTextures()3101 void Context::applyTextures()
3102 {
3103 	applyTextures(sw::SAMPLER_PIXEL);
3104 	applyTextures(sw::SAMPLER_VERTEX);
3105 }
3106 
applyTextures(sw::SamplerType samplerType)3107 void Context::applyTextures(sw::SamplerType samplerType)
3108 {
3109 	Program *programObject = getCurrentProgram();
3110 
3111 	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
3112 
3113 	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
3114 	{
3115 		int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
3116 
3117 		if(textureUnit != -1)
3118 		{
3119 			TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
3120 
3121 			Texture *texture = getSamplerTexture(textureUnit, textureType);
3122 
3123 			if(texture->isSamplerComplete())
3124 			{
3125 				GLenum wrapS, wrapT, wrapR, minFilter, magFilter, compFunc, compMode;
3126 				GLfloat minLOD, maxLOD;
3127 
3128 				Sampler *samplerObject = mState.sampler[textureUnit];
3129 				if(samplerObject)
3130 				{
3131 					wrapS = samplerObject->getWrapS();
3132 					wrapT = samplerObject->getWrapT();
3133 					wrapR = samplerObject->getWrapR();
3134 					minFilter = samplerObject->getMinFilter();
3135 					magFilter = samplerObject->getMagFilter();
3136 					minLOD = samplerObject->getMinLod();
3137 					maxLOD = samplerObject->getMaxLod();
3138 					compFunc = samplerObject->getCompareFunc();
3139 					compMode = samplerObject->getCompareMode();
3140 				}
3141 				else
3142 				{
3143 					wrapS = texture->getWrapS();
3144 					wrapT = texture->getWrapT();
3145 					wrapR = texture->getWrapR();
3146 					minFilter = texture->getMinFilter();
3147 					magFilter = texture->getMagFilter();
3148 					minLOD = texture->getMinLOD();
3149 					maxLOD = texture->getMaxLOD();
3150 					compFunc = texture->getCompareFunc();
3151 					compMode = texture->getCompareMode();
3152 				}
3153 
3154 				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
3155 				GLint baseLevel = texture->getBaseLevel();
3156 				GLint maxLevel = texture->getMaxLevel();
3157 				GLenum swizzleR = texture->getSwizzleR();
3158 				GLenum swizzleG = texture->getSwizzleG();
3159 				GLenum swizzleB = texture->getSwizzleB();
3160 				GLenum swizzleA = texture->getSwizzleA();
3161 
3162 				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
3163 				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
3164 				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
3165 				device->setCompareFunc(samplerType, samplerIndex, es2sw::ConvertCompareFunc(compFunc, compMode));
3166 				device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
3167 				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
3168 				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
3169 				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
3170 				device->setMinLod(samplerType, samplerIndex, minLOD);
3171 				device->setMaxLod(samplerType, samplerIndex, maxLOD);
3172 				device->setBaseLevel(samplerType, samplerIndex, baseLevel);
3173 				device->setMaxLevel(samplerType, samplerIndex, maxLevel);
3174 				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
3175 				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
3176 				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
3177 				device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
3178 
3179 				applyTexture(samplerType, samplerIndex, texture);
3180 			}
3181 			else
3182 			{
3183 				applyTexture(samplerType, samplerIndex, nullptr);
3184 			}
3185 		}
3186 		else
3187 		{
3188 			applyTexture(samplerType, samplerIndex, nullptr);
3189 		}
3190 	}
3191 }
3192 
applyTexture(sw::SamplerType type,int index,Texture * baseTexture)3193 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
3194 {
3195 	Program *program = getCurrentProgram();
3196 	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
3197 	bool textureUsed = false;
3198 
3199 	if(type == sw::SAMPLER_PIXEL)
3200 	{
3201 		textureUsed = program->getPixelShader()->usesSampler(index);
3202 	}
3203 	else if(type == sw::SAMPLER_VERTEX)
3204 	{
3205 		textureUsed = program->getVertexShader()->usesSampler(index);
3206 	}
3207 	else UNREACHABLE(type);
3208 
3209 	sw::Resource *resource = nullptr;
3210 
3211 	if(baseTexture && textureUsed)
3212 	{
3213 		resource = baseTexture->getResource();
3214 	}
3215 
3216 	device->setTextureResource(sampler, resource);
3217 
3218 	if(baseTexture && textureUsed)
3219 	{
3220 		int baseLevel = baseTexture->getBaseLevel();
3221 		int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
3222 		GLenum target = baseTexture->getTarget();
3223 
3224 		switch(target)
3225 		{
3226 		case GL_TEXTURE_2D:
3227 		case GL_TEXTURE_EXTERNAL_OES:
3228 		case GL_TEXTURE_RECTANGLE_ARB:
3229 			{
3230 				Texture2D *texture = static_cast<Texture2D*>(baseTexture);
3231 
3232 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3233 				{
3234 					int surfaceLevel = mipmapLevel + baseLevel;
3235 
3236 					if(surfaceLevel > maxLevel)
3237 					{
3238 						surfaceLevel = maxLevel;
3239 					}
3240 
3241 					egl::Image *surface = texture->getImage(surfaceLevel);
3242 					device->setTextureLevel(sampler, 0, mipmapLevel, surface,
3243 					                        (target == GL_TEXTURE_RECTANGLE_ARB) ? sw::TEXTURE_RECTANGLE : sw::TEXTURE_2D);
3244 				}
3245 			}
3246 			break;
3247 		case GL_TEXTURE_3D:
3248 			{
3249 				Texture3D *texture = static_cast<Texture3D*>(baseTexture);
3250 
3251 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3252 				{
3253 					int surfaceLevel = mipmapLevel + baseLevel;
3254 
3255 					if(surfaceLevel > maxLevel)
3256 					{
3257 						surfaceLevel = maxLevel;
3258 					}
3259 
3260 					egl::Image *surface = texture->getImage(surfaceLevel);
3261 					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
3262 				}
3263 			}
3264 			break;
3265 		case GL_TEXTURE_2D_ARRAY:
3266 			{
3267 				Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
3268 
3269 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3270 				{
3271 					int surfaceLevel = mipmapLevel + baseLevel;
3272 
3273 					if(surfaceLevel > maxLevel)
3274 					{
3275 						surfaceLevel = maxLevel;
3276 					}
3277 
3278 					egl::Image *surface = texture->getImage(surfaceLevel);
3279 					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
3280 				}
3281 			}
3282 			break;
3283 		case GL_TEXTURE_CUBE_MAP:
3284 			{
3285 				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
3286 
3287 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3288 				{
3289 					cubeTexture->updateBorders(mipmapLevel);
3290 
3291 					for(int face = 0; face < 6; face++)
3292 					{
3293 						int surfaceLevel = mipmapLevel + baseLevel;
3294 
3295 						if(surfaceLevel > maxLevel)
3296 						{
3297 							surfaceLevel = maxLevel;
3298 						}
3299 
3300 						egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
3301 						device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
3302 					}
3303 				}
3304 			}
3305 			break;
3306 		default:
3307 			UNIMPLEMENTED();
3308 			break;
3309 		}
3310 	}
3311 	else
3312 	{
3313 		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
3314 	}
3315 }
3316 
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)3317 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
3318 {
3319 	Framebuffer *framebuffer = getReadFramebuffer();
3320 	int framebufferWidth, framebufferHeight, framebufferSamples;
3321 
3322 	if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE))
3323 	{
3324 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3325 	}
3326 
3327 	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
3328 	{
3329 		return error(GL_INVALID_OPERATION);
3330 	}
3331 
3332 	if(!IsValidReadPixelsFormatType(framebuffer, format, type, clientVersion))
3333 	{
3334 		return error(GL_INVALID_OPERATION);
3335 	}
3336 
3337 	GLsizei outputWidth = (mState.packParameters.rowLength > 0) ? mState.packParameters.rowLength : width;
3338 	GLsizei outputPitch = gl::ComputePitch(outputWidth, format, type, mState.packParameters.alignment);
3339 	GLsizei outputHeight = (mState.packParameters.imageHeight == 0) ? height : mState.packParameters.imageHeight;
3340 	pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
3341 	pixels = ((char*)pixels) + gl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packParameters);
3342 
3343 	// Sized query sanity check
3344 	if(bufSize)
3345 	{
3346 		int requiredSize = outputPitch * height;
3347 		if(requiredSize > *bufSize)
3348 		{
3349 			return error(GL_INVALID_OPERATION);
3350 		}
3351 	}
3352 
3353 	egl::Image *renderTarget = nullptr;
3354 	switch(format)
3355 	{
3356 	case GL_DEPTH_COMPONENT:   // GL_NV_read_depth
3357 		renderTarget = framebuffer->getDepthBuffer();
3358 		break;
3359 	default:
3360 		renderTarget = framebuffer->getReadRenderTarget();
3361 		break;
3362 	}
3363 
3364 	if(!renderTarget)
3365 	{
3366 		return error(GL_INVALID_OPERATION);
3367 	}
3368 
3369 	sw::RectF rect((float)x, (float)y, (float)(x + width), (float)(y + height));
3370 	sw::Rect dstRect(0, 0, width, height);
3371 	rect.clip(0.0f, 0.0f, (float)renderTarget->getWidth(), (float)renderTarget->getHeight());
3372 
3373 	sw::Surface *externalSurface = sw::Surface::create(width, height, 1, gl::ConvertReadFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
3374 	sw::SliceRectF sliceRect(rect);
3375 	sw::SliceRect dstSliceRect(dstRect);
3376 	device->blit(renderTarget, sliceRect, externalSurface, dstSliceRect, false, false, false);
3377 	delete externalSurface;
3378 
3379 	renderTarget->release();
3380 }
3381 
clear(GLbitfield mask)3382 void Context::clear(GLbitfield mask)
3383 {
3384 	if(mState.rasterizerDiscardEnabled)
3385 	{
3386 		return;
3387 	}
3388 
3389 	Framebuffer *framebuffer = getDrawFramebuffer();
3390 
3391 	if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3392 	{
3393 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3394 	}
3395 
3396 	if(!applyRenderTarget())
3397 	{
3398 		return;
3399 	}
3400 
3401 	if(mask & GL_COLOR_BUFFER_BIT)
3402 	{
3403 		unsigned int rgbaMask = getColorMask();
3404 
3405 		if(rgbaMask != 0)
3406 		{
3407 			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
3408 		}
3409 	}
3410 
3411 	if(mask & GL_DEPTH_BUFFER_BIT)
3412 	{
3413 		if(mState.depthMask != 0)
3414 		{
3415 			float depth = clamp01(mState.depthClearValue);
3416 			device->clearDepth(depth);
3417 		}
3418 	}
3419 
3420 	if(mask & GL_STENCIL_BUFFER_BIT)
3421 	{
3422 		if(mState.stencilWritemask != 0)
3423 		{
3424 			int stencil = mState.stencilClearValue & 0x000000FF;
3425 			device->clearStencil(stencil, mState.stencilWritemask);
3426 		}
3427 	}
3428 }
3429 
clearColorBuffer(GLint drawbuffer,void * value,sw::Format format)3430 void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
3431 {
3432 	unsigned int rgbaMask = getColorMask();
3433 	if(rgbaMask && !mState.rasterizerDiscardEnabled)
3434 	{
3435 		Framebuffer *framebuffer = getDrawFramebuffer();
3436 		if(!framebuffer)
3437 		{
3438 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3439 		}
3440 		egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
3441 
3442 		if(colorbuffer)
3443 		{
3444 			sw::Rect clearRect = colorbuffer->getRect();
3445 
3446 			if(mState.scissorTestEnabled)
3447 			{
3448 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3449 			}
3450 
3451 			device->clear(value, format, colorbuffer, clearRect, rgbaMask);
3452 
3453 			colorbuffer->release();
3454 		}
3455 	}
3456 }
3457 
clearColorBuffer(GLint drawbuffer,const GLint * value)3458 void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
3459 {
3460 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
3461 }
3462 
clearColorBuffer(GLint drawbuffer,const GLuint * value)3463 void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
3464 {
3465 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
3466 }
3467 
clearColorBuffer(GLint drawbuffer,const GLfloat * value)3468 void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
3469 {
3470 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
3471 }
3472 
clearDepthBuffer(const GLfloat value)3473 void Context::clearDepthBuffer(const GLfloat value)
3474 {
3475 	if(mState.depthMask && !mState.rasterizerDiscardEnabled)
3476 	{
3477 		Framebuffer *framebuffer = getDrawFramebuffer();
3478 		if(!framebuffer)
3479 		{
3480 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3481 		}
3482 		egl::Image *depthbuffer = framebuffer->getDepthBuffer();
3483 
3484 		if(depthbuffer)
3485 		{
3486 			float depth = clamp01(value);
3487 			sw::Rect clearRect = depthbuffer->getRect();
3488 
3489 			if(mState.scissorTestEnabled)
3490 			{
3491 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3492 			}
3493 
3494 			depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3495 
3496 			depthbuffer->release();
3497 		}
3498 	}
3499 }
3500 
clearStencilBuffer(const GLint value)3501 void Context::clearStencilBuffer(const GLint value)
3502 {
3503 	if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
3504 	{
3505 		Framebuffer *framebuffer = getDrawFramebuffer();
3506 		if(!framebuffer)
3507 		{
3508 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3509 		}
3510 		egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
3511 
3512 		if(stencilbuffer)
3513 		{
3514 			unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
3515 			sw::Rect clearRect = stencilbuffer->getRect();
3516 
3517 			if(mState.scissorTestEnabled)
3518 			{
3519 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3520 			}
3521 
3522 			stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3523 
3524 			stencilbuffer->release();
3525 		}
3526 	}
3527 }
3528 
drawArrays(GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)3529 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
3530 {
3531 	if(!applyRenderTarget())
3532 	{
3533 		return;
3534 	}
3535 
3536 	if(mState.currentProgram == 0)
3537 	{
3538 		return;   // Nothing to process.
3539 	}
3540 
3541 	sw::DrawType primitiveType;
3542 	int primitiveCount;
3543 	int verticesPerPrimitive;
3544 
3545 	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
3546 	{
3547 		return error(GL_INVALID_ENUM);
3548 	}
3549 
3550 	applyState(mode);
3551 
3552 	for(int i = 0; i < instanceCount; ++i)
3553 	{
3554 		device->setInstanceID(i);
3555 
3556 		GLenum err = applyVertexBuffer(0, first, count, i);
3557 		if(err != GL_NO_ERROR)
3558 		{
3559 			return error(err);
3560 		}
3561 
3562 		applyShaders();
3563 		applyTextures();
3564 
3565 		if(!getCurrentProgram()->validateSamplers(false))
3566 		{
3567 			return error(GL_INVALID_OPERATION);
3568 		}
3569 
3570 		if(primitiveCount <= 0)
3571 		{
3572 			return;
3573 		}
3574 
3575 		TransformFeedback* transformFeedback = getTransformFeedback();
3576 		if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3577 		{
3578 			device->drawPrimitive(primitiveType, primitiveCount);
3579 		}
3580 		if(transformFeedback)
3581 		{
3582 			transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
3583 		}
3584 	}
3585 }
3586 
drawElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices,GLsizei instanceCount)3587 void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
3588 {
3589 	if(!applyRenderTarget())
3590 	{
3591 		return;
3592 	}
3593 
3594 	if(mState.currentProgram == 0)
3595 	{
3596 		return;   // Nothing to process.
3597 	}
3598 
3599 	if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
3600 	{
3601 		return error(GL_INVALID_OPERATION);
3602 	}
3603 
3604 	GLenum internalMode = mode;
3605 	if(isPrimitiveRestartFixedIndexEnabled())
3606 	{
3607 		switch(mode)
3608 		{
3609 		case GL_TRIANGLE_FAN:
3610 		case GL_TRIANGLE_STRIP:
3611 			internalMode = GL_TRIANGLES;
3612 			break;
3613 		case GL_LINE_LOOP:
3614 		case GL_LINE_STRIP:
3615 			internalMode = GL_LINES;
3616 			break;
3617 		default:
3618 			break;
3619 		}
3620 	}
3621 
3622 	sw::DrawType primitiveType;
3623 	int primitiveCount;
3624 	int verticesPerPrimitive;
3625 
3626 	if(!es2sw::ConvertPrimitiveType(internalMode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
3627 	{
3628 		return error(GL_INVALID_ENUM);
3629 	}
3630 
3631 	TranslatedIndexData indexInfo(primitiveCount);
3632 	GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
3633 	if(err != GL_NO_ERROR)
3634 	{
3635 		return error(err);
3636 	}
3637 
3638 	applyState(internalMode);
3639 
3640 	for(int i = 0; i < instanceCount; ++i)
3641 	{
3642 		device->setInstanceID(i);
3643 
3644 		GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
3645 		err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
3646 		if(err != GL_NO_ERROR)
3647 		{
3648 			return error(err);
3649 		}
3650 
3651 		applyShaders();
3652 		applyTextures();
3653 
3654 		if(!getCurrentProgram()->validateSamplers(false))
3655 		{
3656 			return error(GL_INVALID_OPERATION);
3657 		}
3658 
3659 		if(primitiveCount <= 0)
3660 		{
3661 			return;
3662 		}
3663 
3664 		TransformFeedback* transformFeedback = getTransformFeedback();
3665 		if(!cullSkipsDraw(internalMode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3666 		{
3667 			device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, indexInfo.primitiveCount);
3668 		}
3669 		if(transformFeedback)
3670 		{
3671 			transformFeedback->addVertexOffset(indexInfo.primitiveCount * verticesPerPrimitive);
3672 		}
3673 	}
3674 }
3675 
blit(sw::Surface * source,const sw::SliceRect & sRect,sw::Surface * dest,const sw::SliceRect & dRect)3676 void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
3677 {
3678 	sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
3679 	device->blit(source, sRectF, dest, dRect, false);
3680 }
3681 
finish()3682 void Context::finish()
3683 {
3684 	device->finish();
3685 }
3686 
flush()3687 void Context::flush()
3688 {
3689 	// We don't queue anything without processing it as fast as possible
3690 }
3691 
recordInvalidEnum()3692 void Context::recordInvalidEnum()
3693 {
3694 	mInvalidEnum = true;
3695 }
3696 
recordInvalidValue()3697 void Context::recordInvalidValue()
3698 {
3699 	mInvalidValue = true;
3700 }
3701 
recordInvalidOperation()3702 void Context::recordInvalidOperation()
3703 {
3704 	mInvalidOperation = true;
3705 }
3706 
recordOutOfMemory()3707 void Context::recordOutOfMemory()
3708 {
3709 	mOutOfMemory = true;
3710 }
3711 
recordInvalidFramebufferOperation()3712 void Context::recordInvalidFramebufferOperation()
3713 {
3714 	mInvalidFramebufferOperation = true;
3715 }
3716 
3717 // Get one of the recorded errors and clear its flag, if any.
3718 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()3719 GLenum Context::getError()
3720 {
3721 	if(mInvalidEnum)
3722 	{
3723 		mInvalidEnum = false;
3724 
3725 		return GL_INVALID_ENUM;
3726 	}
3727 
3728 	if(mInvalidValue)
3729 	{
3730 		mInvalidValue = false;
3731 
3732 		return GL_INVALID_VALUE;
3733 	}
3734 
3735 	if(mInvalidOperation)
3736 	{
3737 		mInvalidOperation = false;
3738 
3739 		return GL_INVALID_OPERATION;
3740 	}
3741 
3742 	if(mOutOfMemory)
3743 	{
3744 		mOutOfMemory = false;
3745 
3746 		return GL_OUT_OF_MEMORY;
3747 	}
3748 
3749 	if(mInvalidFramebufferOperation)
3750 	{
3751 		mInvalidFramebufferOperation = false;
3752 
3753 		return GL_INVALID_FRAMEBUFFER_OPERATION;
3754 	}
3755 
3756 	return GL_NO_ERROR;
3757 }
3758 
getSupportedMultisampleCount(int requested)3759 int Context::getSupportedMultisampleCount(int requested)
3760 {
3761 	int supported = 0;
3762 
3763 	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
3764 	{
3765 		if(supported >= requested)
3766 		{
3767 			return supported;
3768 		}
3769 
3770 		supported = multisampleCount[i];
3771 	}
3772 
3773 	return supported;
3774 }
3775 
detachBuffer(GLuint buffer)3776 void Context::detachBuffer(GLuint buffer)
3777 {
3778 	// [OpenGL ES 2.0.24] section 2.9 page 22:
3779 	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
3780 	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
3781 
3782 	if(mState.copyReadBuffer.name() == buffer)
3783 	{
3784 		mState.copyReadBuffer = nullptr;
3785 	}
3786 
3787 	if(mState.copyWriteBuffer.name() == buffer)
3788 	{
3789 		mState.copyWriteBuffer = nullptr;
3790 	}
3791 
3792 	if(mState.pixelPackBuffer.name() == buffer)
3793 	{
3794 		mState.pixelPackBuffer = nullptr;
3795 	}
3796 
3797 	if(mState.pixelUnpackBuffer.name() == buffer)
3798 	{
3799 		mState.pixelUnpackBuffer = nullptr;
3800 	}
3801 
3802 	if(mState.genericUniformBuffer.name() == buffer)
3803 	{
3804 		mState.genericUniformBuffer = nullptr;
3805 	}
3806 
3807 	if(getArrayBufferName() == buffer)
3808 	{
3809 		mState.arrayBuffer = nullptr;
3810 	}
3811 
3812 	// Only detach from the current transform feedback
3813 	TransformFeedback* currentTransformFeedback = getTransformFeedback();
3814 	if(currentTransformFeedback)
3815 	{
3816 		currentTransformFeedback->detachBuffer(buffer);
3817 	}
3818 
3819 	// Only detach from the current vertex array
3820 	VertexArray* currentVertexArray = getCurrentVertexArray();
3821 	if(currentVertexArray)
3822 	{
3823 		currentVertexArray->detachBuffer(buffer);
3824 	}
3825 
3826 	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3827 	{
3828 		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3829 		{
3830 			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
3831 		}
3832 	}
3833 }
3834 
detachTexture(GLuint texture)3835 void Context::detachTexture(GLuint texture)
3836 {
3837 	// [OpenGL ES 2.0.24] section 3.8 page 84:
3838 	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3839 	// rebound to texture object zero
3840 
3841 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3842 	{
3843 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3844 		{
3845 			if(mState.samplerTexture[type][sampler].name() == texture)
3846 			{
3847 				mState.samplerTexture[type][sampler] = nullptr;
3848 			}
3849 		}
3850 	}
3851 
3852 	// [OpenGL ES 2.0.24] section 4.4 page 112:
3853 	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3854 	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3855 	// image was attached in the currently bound framebuffer.
3856 
3857 	Framebuffer *readFramebuffer = getReadFramebuffer();
3858 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
3859 
3860 	if(readFramebuffer)
3861 	{
3862 		readFramebuffer->detachTexture(texture);
3863 	}
3864 
3865 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3866 	{
3867 		drawFramebuffer->detachTexture(texture);
3868 	}
3869 }
3870 
detachFramebuffer(GLuint framebuffer)3871 void Context::detachFramebuffer(GLuint framebuffer)
3872 {
3873 	// [OpenGL ES 2.0.24] section 4.4 page 107:
3874 	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3875 	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3876 
3877 	if(mState.readFramebuffer == framebuffer)
3878 	{
3879 		bindReadFramebuffer(0);
3880 	}
3881 
3882 	if(mState.drawFramebuffer == framebuffer)
3883 	{
3884 		bindDrawFramebuffer(0);
3885 	}
3886 }
3887 
detachRenderbuffer(GLuint renderbuffer)3888 void Context::detachRenderbuffer(GLuint renderbuffer)
3889 {
3890 	// [OpenGL ES 2.0.24] section 4.4 page 109:
3891 	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3892 	// had been executed with the target RENDERBUFFER and name of zero.
3893 
3894 	if(mState.renderbuffer.name() == renderbuffer)
3895 	{
3896 		bindRenderbuffer(0);
3897 	}
3898 
3899 	// [OpenGL ES 2.0.24] section 4.4 page 111:
3900 	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3901 	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3902 	// point to which this image was attached in the currently bound framebuffer.
3903 
3904 	Framebuffer *readFramebuffer = getReadFramebuffer();
3905 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
3906 
3907 	if(readFramebuffer)
3908 	{
3909 		readFramebuffer->detachRenderbuffer(renderbuffer);
3910 	}
3911 
3912 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3913 	{
3914 		drawFramebuffer->detachRenderbuffer(renderbuffer);
3915 	}
3916 }
3917 
detachSampler(GLuint sampler)3918 void Context::detachSampler(GLuint sampler)
3919 {
3920 	// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3921 	// If a sampler object that is currently bound to one or more texture units is
3922 	// deleted, it is as though BindSampler is called once for each texture unit to
3923 	// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3924 	for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
3925 	{
3926 		gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
3927 		if(samplerBinding.name() == sampler)
3928 		{
3929 			samplerBinding = nullptr;
3930 		}
3931 	}
3932 }
3933 
cullSkipsDraw(GLenum drawMode)3934 bool Context::cullSkipsDraw(GLenum drawMode)
3935 {
3936 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3937 }
3938 
isTriangleMode(GLenum drawMode)3939 bool Context::isTriangleMode(GLenum drawMode)
3940 {
3941 	switch(drawMode)
3942 	{
3943 	case GL_TRIANGLES:
3944 	case GL_TRIANGLE_FAN:
3945 	case GL_TRIANGLE_STRIP:
3946 		return true;
3947 	case GL_POINTS:
3948 	case GL_LINES:
3949 	case GL_LINE_LOOP:
3950 	case GL_LINE_STRIP:
3951 		return false;
3952 	default: UNREACHABLE(drawMode);
3953 	}
3954 
3955 	return false;
3956 }
3957 
setVertexAttrib(GLuint index,const GLfloat * values)3958 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
3959 {
3960 	ASSERT(index < MAX_VERTEX_ATTRIBS);
3961 
3962 	mState.vertexAttribute[index].setCurrentValue(values);
3963 
3964 	mVertexDataManager->dirtyCurrentValue(index);
3965 }
3966 
setVertexAttrib(GLuint index,const GLint * values)3967 void Context::setVertexAttrib(GLuint index, const GLint *values)
3968 {
3969 	ASSERT(index < MAX_VERTEX_ATTRIBS);
3970 
3971 	mState.vertexAttribute[index].setCurrentValue(values);
3972 
3973 	mVertexDataManager->dirtyCurrentValue(index);
3974 }
3975 
setVertexAttrib(GLuint index,const GLuint * values)3976 void Context::setVertexAttrib(GLuint index, const GLuint *values)
3977 {
3978 	ASSERT(index < MAX_VERTEX_ATTRIBS);
3979 
3980 	mState.vertexAttribute[index].setCurrentValue(values);
3981 
3982 	mVertexDataManager->dirtyCurrentValue(index);
3983 }
3984 
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,bool filter,bool allowPartialDepthStencilBlit)3985 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
3986                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3987                               GLbitfield mask, bool filter, bool allowPartialDepthStencilBlit)
3988 {
3989 	Framebuffer *readFramebuffer = getReadFramebuffer();
3990 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
3991 
3992 	int readBufferWidth, readBufferHeight, readBufferSamples;
3993 	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
3994 
3995 	if(!readFramebuffer || (readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE) ||
3996 	   !drawFramebuffer || (drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE))
3997 	{
3998 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3999 	}
4000 
4001 	if(drawBufferSamples > 1)
4002 	{
4003 		return error(GL_INVALID_OPERATION);
4004 	}
4005 
4006 	sw::SliceRect sourceRect;
4007 	sw::SliceRect destRect;
4008 	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
4009 	bool flipY = (srcY0 < srcY1) ^ (dstY0 < dstY1);
4010 
4011 	if(srcX0 < srcX1)
4012 	{
4013 		sourceRect.x0 = srcX0;
4014 		sourceRect.x1 = srcX1;
4015 	}
4016 	else
4017 	{
4018 		sourceRect.x0 = srcX1;
4019 		sourceRect.x1 = srcX0;
4020 	}
4021 
4022 	if(dstX0 < dstX1)
4023 	{
4024 		destRect.x0 = dstX0;
4025 		destRect.x1 = dstX1;
4026 	}
4027 	else
4028 	{
4029 		destRect.x0 = dstX1;
4030 		destRect.x1 = dstX0;
4031 	}
4032 
4033 	if(srcY0 < srcY1)
4034 	{
4035 		sourceRect.y0 = srcY0;
4036 		sourceRect.y1 = srcY1;
4037 	}
4038 	else
4039 	{
4040 		sourceRect.y0 = srcY1;
4041 		sourceRect.y1 = srcY0;
4042 	}
4043 
4044 	if(dstY0 < dstY1)
4045 	{
4046 		destRect.y0 = dstY0;
4047 		destRect.y1 = dstY1;
4048 	}
4049 	else
4050 	{
4051 		destRect.y0 = dstY1;
4052 		destRect.y1 = dstY0;
4053 	}
4054 
4055 	sw::RectF sourceScissoredRect(static_cast<float>(sourceRect.x0), static_cast<float>(sourceRect.y0),
4056 	                              static_cast<float>(sourceRect.x1), static_cast<float>(sourceRect.y1));
4057 	sw::Rect destScissoredRect = destRect;
4058 
4059 	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
4060 	{
4061 		sw::Rect scissorRect(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
4062 		Device::ClipDstRect(sourceScissoredRect, destScissoredRect, scissorRect, flipX, flipY);
4063 	}
4064 
4065 	sw::SliceRectF sourceTrimmedRect = sourceScissoredRect;
4066 	sw::SliceRect destTrimmedRect = destScissoredRect;
4067 
4068 	// The source & destination rectangles also may need to be trimmed if
4069 	// they fall out of the bounds of the actual draw and read surfaces.
4070 	sw::Rect sourceTrimRect(0, 0, readBufferWidth, readBufferHeight);
4071 	Device::ClipSrcRect(sourceTrimmedRect, destTrimmedRect, sourceTrimRect, flipX, flipY);
4072 
4073 	sw::Rect destTrimRect(0, 0, drawBufferWidth, drawBufferHeight);
4074 	Device::ClipDstRect(sourceTrimmedRect, destTrimmedRect, destTrimRect, flipX, flipY);
4075 
4076 	bool partialBufferCopy = false;
4077 
4078 	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
4079 	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
4080 	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
4081 	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
4082 	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
4083 	{
4084 		partialBufferCopy = true;
4085 	}
4086 
4087 	bool sameBounds = (srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1);
4088 	bool blitRenderTarget = false;
4089 	bool blitDepth = false;
4090 	bool blitStencil = false;
4091 
4092 	if(mask & GL_COLOR_BUFFER_BIT)
4093 	{
4094 		GLenum readColorbufferType = readFramebuffer->getReadBufferType();
4095 		GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
4096 		const bool validReadType = readColorbufferType == GL_TEXTURE_2D || readColorbufferType == GL_TEXTURE_RECTANGLE_ARB || Framebuffer::IsRenderbuffer(readColorbufferType);
4097 		const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || drawColorbufferType == GL_TEXTURE_RECTANGLE_ARB || Framebuffer::IsRenderbuffer(drawColorbufferType);
4098 		if(!validReadType || !validDrawType)
4099 		{
4100 			return error(GL_INVALID_OPERATION);
4101 		}
4102 
4103 		if(partialBufferCopy && readBufferSamples > 1 && !sameBounds)
4104 		{
4105 			return error(GL_INVALID_OPERATION);
4106 		}
4107 
4108 		// The GL ES 3.0.2 spec (pg 193) states that:
4109 		// 1) If the read buffer is fixed point format, the draw buffer must be as well
4110 		// 2) If the read buffer is an unsigned integer format, the draw buffer must be
4111 		// as well
4112 		// 3) If the read buffer is a signed integer format, the draw buffer must be as
4113 		// well
4114 		es2::Renderbuffer *readRenderbuffer = readFramebuffer->getReadColorbuffer();
4115 		es2::Renderbuffer *drawRenderbuffer = drawFramebuffer->getColorbuffer(0);
4116 		GLint readFormat = readRenderbuffer->getFormat();
4117 		GLint drawFormat = drawRenderbuffer->getFormat();
4118 		GLenum readComponentType = GetComponentType(readFormat, GL_COLOR_ATTACHMENT0);
4119 		GLenum drawComponentType = GetComponentType(drawFormat, GL_COLOR_ATTACHMENT0);
4120 		bool readFixedPoint = ((readComponentType == GL_UNSIGNED_NORMALIZED) ||
4121 		                       (readComponentType == GL_SIGNED_NORMALIZED));
4122 		bool drawFixedPoint = ((drawComponentType == GL_UNSIGNED_NORMALIZED) ||
4123 		                       (drawComponentType == GL_SIGNED_NORMALIZED));
4124 		bool readFixedOrFloat = (readFixedPoint || (readComponentType == GL_FLOAT));
4125 		bool drawFixedOrFloat = (drawFixedPoint || (drawComponentType == GL_FLOAT));
4126 
4127 		if(readFixedOrFloat != drawFixedOrFloat)
4128 		{
4129 			return error(GL_INVALID_OPERATION);
4130 		}
4131 
4132 		if((readComponentType == GL_UNSIGNED_INT) && (drawComponentType != GL_UNSIGNED_INT))
4133 		{
4134 			return error(GL_INVALID_OPERATION);
4135 		}
4136 
4137 		if((readComponentType == GL_INT) && (drawComponentType != GL_INT))
4138 		{
4139 			return error(GL_INVALID_OPERATION);
4140 		}
4141 
4142 		// Cannot filter integer data
4143 		if(((readComponentType == GL_UNSIGNED_INT) || (readComponentType == GL_INT)) && filter)
4144 		{
4145 			return error(GL_INVALID_OPERATION);
4146 		}
4147 
4148 		// From the ANGLE_framebuffer_blit extension:
4149 		// "Calling BlitFramebufferANGLE will result in an INVALID_OPERATION error if <mask>
4150 		//  includes COLOR_BUFFER_BIT and the source and destination color formats to not match."
4151 		if((clientVersion < 3) && (readRenderbuffer->getSamples() > 0) && (readFormat != drawFormat))
4152 		{
4153 			return error(GL_INVALID_OPERATION);
4154 		}
4155 
4156 		blitRenderTarget = true;
4157 	}
4158 
4159 	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
4160 	{
4161 		Renderbuffer *readDSBuffer = nullptr;
4162 		Renderbuffer *drawDSBuffer = nullptr;
4163 
4164 		if(mask & GL_DEPTH_BUFFER_BIT)
4165 		{
4166 			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
4167 			{
4168 				GLenum readDepthBufferType = readFramebuffer->getDepthbufferType();
4169 				GLenum drawDepthBufferType = drawFramebuffer->getDepthbufferType();
4170 				if((readDepthBufferType != drawDepthBufferType) &&
4171 				   !(Framebuffer::IsRenderbuffer(readDepthBufferType) && Framebuffer::IsRenderbuffer(drawDepthBufferType)))
4172 				{
4173 					return error(GL_INVALID_OPERATION);
4174 				}
4175 
4176 				blitDepth = true;
4177 				readDSBuffer = readFramebuffer->getDepthbuffer();
4178 				drawDSBuffer = drawFramebuffer->getDepthbuffer();
4179 
4180 				if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4181 				{
4182 					return error(GL_INVALID_OPERATION);
4183 				}
4184 			}
4185 		}
4186 
4187 		if(mask & GL_STENCIL_BUFFER_BIT)
4188 		{
4189 			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
4190 			{
4191 				GLenum readStencilBufferType = readFramebuffer->getStencilbufferType();
4192 				GLenum drawStencilBufferType = drawFramebuffer->getStencilbufferType();
4193 				if((readStencilBufferType != drawStencilBufferType) &&
4194 				   !(Framebuffer::IsRenderbuffer(readStencilBufferType) && Framebuffer::IsRenderbuffer(drawStencilBufferType)))
4195 				{
4196 					return error(GL_INVALID_OPERATION);
4197 				}
4198 
4199 				blitStencil = true;
4200 				readDSBuffer = readFramebuffer->getStencilbuffer();
4201 				drawDSBuffer = drawFramebuffer->getStencilbuffer();
4202 
4203 				if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4204 				{
4205 					return error(GL_INVALID_OPERATION);
4206 				}
4207 			}
4208 		}
4209 
4210 		if(partialBufferCopy && !allowPartialDepthStencilBlit)
4211 		{
4212 			ERR("Only whole-buffer depth and stencil blits are supported by ANGLE_framebuffer_blit.");
4213 			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
4214 		}
4215 
4216 		// OpenGL ES 3.0.4 spec, p.199:
4217 		// ...an INVALID_OPERATION error is generated if the formats of the read
4218 		// and draw framebuffers are not identical or if the source and destination
4219 		// rectangles are not defined with the same(X0, Y 0) and (X1, Y 1) bounds.
4220 		// If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, an
4221 		// INVALID_OPERATION error is generated.
4222 		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
4223 		   ((readDSBuffer && readDSBuffer->getSamples() > 1) &&
4224 		    (!sameBounds || (drawDSBuffer->getFormat() != readDSBuffer->getFormat()))))
4225 		{
4226 			return error(GL_INVALID_OPERATION);
4227 		}
4228 	}
4229 
4230 	if(blitRenderTarget || blitDepth || blitStencil)
4231 	{
4232 		if(flipX)
4233 		{
4234 			swap(destTrimmedRect.x0, destTrimmedRect.x1);
4235 		}
4236 		if(flipY)
4237 		{
4238 			swap(destTrimmedRect.y0, destTrimmedRect.y1);
4239 		}
4240 
4241 		if(blitRenderTarget)
4242 		{
4243 			egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
4244 			egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
4245 
4246 			bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::COLOR_BUFFER);
4247 
4248 			readRenderTarget->release();
4249 			drawRenderTarget->release();
4250 
4251 			if(!success)
4252 			{
4253 				ERR("BlitFramebuffer failed.");
4254 				return;
4255 			}
4256 		}
4257 
4258 		if(blitDepth)
4259 		{
4260 			egl::Image *readRenderTarget = readFramebuffer->getDepthBuffer();
4261 			egl::Image *drawRenderTarget = drawFramebuffer->getDepthBuffer();
4262 
4263 			bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::DEPTH_BUFFER);
4264 
4265 			readRenderTarget->release();
4266 			drawRenderTarget->release();
4267 
4268 			if(!success)
4269 			{
4270 				ERR("BlitFramebuffer failed.");
4271 				return;
4272 			}
4273 		}
4274 
4275 		if(blitStencil)
4276 		{
4277 			egl::Image *readRenderTarget = readFramebuffer->getStencilBuffer();
4278 			egl::Image *drawRenderTarget = drawFramebuffer->getStencilBuffer();
4279 
4280 			bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::STENCIL_BUFFER);
4281 
4282 			readRenderTarget->release();
4283 			drawRenderTarget->release();
4284 
4285 			if(!success)
4286 			{
4287 				ERR("BlitFramebuffer failed.");
4288 				return;
4289 			}
4290 		}
4291 	}
4292 }
4293 
bindTexImage(gl::Surface * surface)4294 void Context::bindTexImage(gl::Surface *surface)
4295 {
4296 	bool isRect = (surface->getTextureTarget() == EGL_TEXTURE_RECTANGLE_ANGLE);
4297 	es2::Texture2D *textureObject = isRect ? getTexture2DRect() : getTexture2D();
4298 
4299 	if(textureObject)
4300 	{
4301 		textureObject->bindTexImage(surface);
4302 	}
4303 }
4304 
validateSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4305 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4306 {
4307 	GLenum textureTarget = GL_NONE;
4308 
4309 	switch(target)
4310 	{
4311 	case EGL_GL_TEXTURE_2D_KHR:
4312 		textureTarget = GL_TEXTURE_2D;
4313 		break;
4314 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
4315 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
4316 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
4317 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
4318 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
4319 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
4320 		textureTarget = GL_TEXTURE_CUBE_MAP;
4321 		break;
4322 	case EGL_GL_RENDERBUFFER_KHR:
4323 		break;
4324 	default:
4325 		return EGL_BAD_PARAMETER;
4326 	}
4327 
4328 	if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4329 	{
4330 		return EGL_BAD_MATCH;
4331 	}
4332 
4333 	if(textureTarget != GL_NONE)
4334 	{
4335 		es2::Texture *texture = getTexture(name);
4336 
4337 		if(!texture || texture->getTarget() != textureTarget)
4338 		{
4339 			return EGL_BAD_PARAMETER;
4340 		}
4341 
4342 		if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
4343 		{
4344 			return EGL_BAD_ACCESS;
4345 		}
4346 
4347 		if(textureLevel != 0 && !texture->isSamplerComplete())
4348 		{
4349 			return EGL_BAD_PARAMETER;
4350 		}
4351 
4352 		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
4353 		{
4354 			return EGL_BAD_PARAMETER;
4355 		}
4356 	}
4357 	else if(target == EGL_GL_RENDERBUFFER_KHR)
4358 	{
4359 		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4360 
4361 		if(!renderbuffer)
4362 		{
4363 			return EGL_BAD_PARAMETER;
4364 		}
4365 
4366 		if(renderbuffer->isShared())   // Already an EGLImage sibling
4367 		{
4368 			return EGL_BAD_ACCESS;
4369 		}
4370 	}
4371 	else UNREACHABLE(target);
4372 
4373 	return EGL_SUCCESS;
4374 }
4375 
createSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4376 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4377 {
4378 	GLenum textureTarget = GL_NONE;
4379 
4380 	switch(target)
4381 	{
4382 	case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
4383 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4384 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4385 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4386 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4387 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4388 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4389 	}
4390 
4391 	if(textureTarget != GL_NONE)
4392 	{
4393 		es2::Texture *texture = getTexture(name);
4394 
4395 		return texture->createSharedImage(textureTarget, textureLevel);
4396 	}
4397 	else if(target == EGL_GL_RENDERBUFFER_KHR)
4398 	{
4399 		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4400 
4401 		return renderbuffer->createSharedImage();
4402 	}
4403 	else UNREACHABLE(target);
4404 
4405 	return nullptr;
4406 }
4407 
getSharedImage(GLeglImageOES image)4408 egl::Image *Context::getSharedImage(GLeglImageOES image)
4409 {
4410 	return display->getSharedImage(image);
4411 }
4412 
getDevice()4413 Device *Context::getDevice()
4414 {
4415 	return device;
4416 }
4417 
getExtensions(GLuint index,GLuint * numExt) const4418 const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
4419 {
4420 	// Keep list sorted in following order:
4421 	// OES extensions
4422 	// EXT extensions
4423 	// Vendor extensions
4424 	static const char *es2extensions[] =
4425 	{
4426 		"GL_OES_compressed_ETC1_RGB8_texture",
4427 		"GL_OES_depth24",
4428 		"GL_OES_depth32",
4429 		"GL_OES_depth_texture",
4430 		"GL_OES_depth_texture_cube_map",
4431 		"GL_OES_EGL_image",
4432 		"GL_OES_EGL_image_external",
4433 		"GL_OES_EGL_sync",
4434 		"GL_OES_element_index_uint",
4435 		"GL_OES_framebuffer_object",
4436 		"GL_OES_packed_depth_stencil",
4437 		"GL_OES_rgb8_rgba8",
4438 		"GL_OES_standard_derivatives",
4439 		"GL_OES_surfaceless_context",
4440 		"GL_OES_texture_float",
4441 		"GL_OES_texture_float_linear",
4442 		"GL_OES_texture_half_float",
4443 		"GL_OES_texture_half_float_linear",
4444 		"GL_OES_texture_npot",
4445 		"GL_OES_texture_3D",
4446 		"GL_OES_vertex_half_float",
4447 		"GL_EXT_blend_minmax",
4448 		"GL_EXT_color_buffer_half_float",
4449 		"GL_EXT_draw_buffers",
4450 		"GL_EXT_instanced_arrays",
4451 		"GL_EXT_occlusion_query_boolean",
4452 		"GL_EXT_read_format_bgra",
4453 		"GL_EXT_texture_compression_dxt1",
4454 		"GL_EXT_texture_filter_anisotropic",
4455 		"GL_EXT_texture_format_BGRA8888",
4456 		"GL_EXT_texture_rg",
4457 #if (ASTC_SUPPORT)
4458 		"GL_KHR_texture_compression_astc_hdr",
4459 		"GL_KHR_texture_compression_astc_ldr",
4460 #endif
4461 		"GL_ARB_texture_rectangle",
4462 		"GL_ANGLE_framebuffer_blit",
4463 		"GL_ANGLE_framebuffer_multisample",
4464 		"GL_ANGLE_instanced_arrays",
4465 		"GL_ANGLE_texture_compression_dxt3",
4466 		"GL_ANGLE_texture_compression_dxt5",
4467 		"GL_APPLE_texture_format_BGRA8888",
4468 		"GL_CHROMIUM_color_buffer_float_rgba", // A subset of EXT_color_buffer_float on top of OpenGL ES 2.0
4469 		"GL_CHROMIUM_texture_filtering_hint",
4470 		"GL_NV_fence",
4471 		"GL_NV_framebuffer_blit",
4472 		"GL_NV_read_depth",
4473 	};
4474 
4475 	// Extensions exclusive to OpenGL ES 3.0 and above.
4476 	static const char *es3extensions[] =
4477 	{
4478 		"GL_EXT_color_buffer_float",
4479 	};
4480 
4481 	GLuint numES2extensions = sizeof(es2extensions) / sizeof(es2extensions[0]);
4482 	GLuint numExtensions = numES2extensions;
4483 
4484 	if(clientVersion >= 3)
4485 	{
4486 		numExtensions += sizeof(es3extensions) / sizeof(es3extensions[0]);
4487 	}
4488 
4489 	if(numExt)
4490 	{
4491 		*numExt = numExtensions;
4492 
4493 		return nullptr;
4494 	}
4495 
4496 	if(index == GL_INVALID_INDEX)
4497 	{
4498 		static std::string extensionsCat;
4499 
4500 		if(extensionsCat.empty() && (numExtensions > 0))
4501 		{
4502 			for(const char *extension : es2extensions)
4503 			{
4504 				extensionsCat += std::string(extension) + " ";
4505 			}
4506 
4507 			if(clientVersion >= 3)
4508 			{
4509 				for(const char *extension : es3extensions)
4510 				{
4511 					extensionsCat += std::string(extension) + " ";
4512 				}
4513 			}
4514 		}
4515 
4516 		return (const GLubyte*)extensionsCat.c_str();
4517 	}
4518 
4519 	if(index >= numExtensions)
4520 	{
4521 		return nullptr;
4522 	}
4523 
4524 	if(index < numES2extensions)
4525 	{
4526 		return (const GLubyte*)es2extensions[index];
4527 	}
4528 	else
4529 	{
4530 		return (const GLubyte*)es3extensions[index - numES2extensions];
4531 	}
4532 }
4533 
4534 }
4535 
es2CreateContext(egl::Display * display,const egl::Context * shareContext,int clientVersion,const egl::Config * config)4536 NO_SANITIZE_FUNCTION egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion, const egl::Config *config)
4537 {
4538 	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext
4539 	return new es2::Context(display, static_cast<const es2::Context*>(shareContext), clientVersion, config);
4540 }
4541