• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,const egl::Config * config)48 Context::Context(egl::Display *display, const Context *shareContext, const egl::Config *config)
49 	: egl::Context(display), 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 3;
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 	// Detach if currently bound.
1075 	if(mState.transformFeedback == transformFeedback)
1076 	{
1077 		mState.transformFeedback = 0;
1078 	}
1079 
1080 	if(transformFeedbackObject)
1081 	{
1082 		delete transformFeedbackObject;
1083 	}
1084 }
1085 
deleteSampler(GLuint sampler)1086 void Context::deleteSampler(GLuint sampler)
1087 {
1088 	detachSampler(sampler);
1089 
1090 	mResourceManager->deleteSampler(sampler);
1091 }
1092 
getBuffer(GLuint handle) const1093 Buffer *Context::getBuffer(GLuint handle) const
1094 {
1095 	return mResourceManager->getBuffer(handle);
1096 }
1097 
getShader(GLuint handle) const1098 Shader *Context::getShader(GLuint handle) const
1099 {
1100 	return mResourceManager->getShader(handle);
1101 }
1102 
getProgram(GLuint handle) const1103 Program *Context::getProgram(GLuint handle) const
1104 {
1105 	return mResourceManager->getProgram(handle);
1106 }
1107 
getTexture(GLuint handle) const1108 Texture *Context::getTexture(GLuint handle) const
1109 {
1110 	return mResourceManager->getTexture(handle);
1111 }
1112 
getRenderbuffer(GLuint handle) const1113 Renderbuffer *Context::getRenderbuffer(GLuint handle) const
1114 {
1115 	return mResourceManager->getRenderbuffer(handle);
1116 }
1117 
getReadFramebuffer() const1118 Framebuffer *Context::getReadFramebuffer() const
1119 {
1120 	return getFramebuffer(mState.readFramebuffer);
1121 }
1122 
getDrawFramebuffer() const1123 Framebuffer *Context::getDrawFramebuffer() const
1124 {
1125 	return getFramebuffer(mState.drawFramebuffer);
1126 }
1127 
bindArrayBuffer(unsigned int buffer)1128 void Context::bindArrayBuffer(unsigned int buffer)
1129 {
1130 	mResourceManager->checkBufferAllocation(buffer);
1131 
1132 	mState.arrayBuffer = getBuffer(buffer);
1133 }
1134 
bindElementArrayBuffer(unsigned int buffer)1135 void Context::bindElementArrayBuffer(unsigned int buffer)
1136 {
1137 	mResourceManager->checkBufferAllocation(buffer);
1138 
1139 	getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1140 }
1141 
bindCopyReadBuffer(GLuint buffer)1142 void Context::bindCopyReadBuffer(GLuint buffer)
1143 {
1144 	mResourceManager->checkBufferAllocation(buffer);
1145 
1146 	mState.copyReadBuffer = getBuffer(buffer);
1147 }
1148 
bindCopyWriteBuffer(GLuint buffer)1149 void Context::bindCopyWriteBuffer(GLuint buffer)
1150 {
1151 	mResourceManager->checkBufferAllocation(buffer);
1152 
1153 	mState.copyWriteBuffer = getBuffer(buffer);
1154 }
1155 
bindPixelPackBuffer(GLuint buffer)1156 void Context::bindPixelPackBuffer(GLuint buffer)
1157 {
1158 	mResourceManager->checkBufferAllocation(buffer);
1159 
1160 	mState.pixelPackBuffer = getBuffer(buffer);
1161 }
1162 
bindPixelUnpackBuffer(GLuint buffer)1163 void Context::bindPixelUnpackBuffer(GLuint buffer)
1164 {
1165 	mResourceManager->checkBufferAllocation(buffer);
1166 
1167 	mState.pixelUnpackBuffer = getBuffer(buffer);
1168 }
1169 
bindTransformFeedbackBuffer(GLuint buffer)1170 void Context::bindTransformFeedbackBuffer(GLuint buffer)
1171 {
1172 	mResourceManager->checkBufferAllocation(buffer);
1173 
1174 	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1175 
1176 	if(transformFeedback)
1177 	{
1178 		transformFeedback->setGenericBuffer(getBuffer(buffer));
1179 	}
1180 }
1181 
bindTexture(TextureType type,GLuint texture)1182 void Context::bindTexture(TextureType type, GLuint texture)
1183 {
1184 	mResourceManager->checkTextureAllocation(texture, type);
1185 
1186 	mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
1187 }
1188 
bindReadFramebuffer(GLuint framebuffer)1189 void Context::bindReadFramebuffer(GLuint framebuffer)
1190 {
1191 	if(!getFramebuffer(framebuffer))
1192 	{
1193 		if(framebuffer == 0)
1194 		{
1195 			mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1196 		}
1197 		else
1198 		{
1199 			mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1200 		}
1201 	}
1202 
1203 	mState.readFramebuffer = framebuffer;
1204 }
1205 
bindDrawFramebuffer(GLuint framebuffer)1206 void Context::bindDrawFramebuffer(GLuint framebuffer)
1207 {
1208 	if(!getFramebuffer(framebuffer))
1209 	{
1210 		if(framebuffer == 0)
1211 		{
1212 			mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1213 		}
1214 		else
1215 		{
1216 			mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1217 		}
1218 	}
1219 
1220 	mState.drawFramebuffer = framebuffer;
1221 }
1222 
bindRenderbuffer(GLuint renderbuffer)1223 void Context::bindRenderbuffer(GLuint renderbuffer)
1224 {
1225 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
1226 
1227 	mState.renderbuffer = getRenderbuffer(renderbuffer);
1228 }
1229 
bindVertexArray(GLuint array)1230 void Context::bindVertexArray(GLuint array)
1231 {
1232 	VertexArray *vertexArray = getVertexArray(array);
1233 
1234 	if(!vertexArray)
1235 	{
1236 		vertexArray = new VertexArray(array);
1237 		mVertexArrayNameSpace.insert(array, vertexArray);
1238 	}
1239 
1240 	mState.vertexArray = array;
1241 }
1242 
bindGenericUniformBuffer(GLuint buffer)1243 void Context::bindGenericUniformBuffer(GLuint buffer)
1244 {
1245 	mResourceManager->checkBufferAllocation(buffer);
1246 
1247 	mState.genericUniformBuffer = getBuffer(buffer);
1248 }
1249 
bindIndexedUniformBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1250 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1251 {
1252 	mResourceManager->checkBufferAllocation(buffer);
1253 
1254 	Buffer* bufferObject = getBuffer(buffer);
1255 	mState.uniformBuffers[index].set(bufferObject, static_cast<int>(offset), static_cast<int>(size));
1256 }
1257 
bindGenericTransformFeedbackBuffer(GLuint buffer)1258 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1259 {
1260 	mResourceManager->checkBufferAllocation(buffer);
1261 
1262 	getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
1263 }
1264 
bindIndexedTransformFeedbackBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1265 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1266 {
1267 	mResourceManager->checkBufferAllocation(buffer);
1268 
1269 	Buffer* bufferObject = getBuffer(buffer);
1270 	getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
1271 }
1272 
bindTransformFeedback(GLuint id)1273 void Context::bindTransformFeedback(GLuint id)
1274 {
1275 	if(!getTransformFeedback(id))
1276 	{
1277 		mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
1278 	}
1279 
1280 	mState.transformFeedback = id;
1281 }
1282 
bindSampler(GLuint unit,GLuint sampler)1283 bool Context::bindSampler(GLuint unit, GLuint sampler)
1284 {
1285 	mResourceManager->checkSamplerAllocation(sampler);
1286 
1287 	Sampler* samplerObject = getSampler(sampler);
1288 
1289 	mState.sampler[unit] = samplerObject;
1290 
1291 	return !!samplerObject;
1292 }
1293 
useProgram(GLuint program)1294 void Context::useProgram(GLuint program)
1295 {
1296 	GLuint priorProgram = mState.currentProgram;
1297 	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
1298 
1299 	if(priorProgram != program)
1300 	{
1301 		Program *newProgram = mResourceManager->getProgram(program);
1302 		Program *oldProgram = mResourceManager->getProgram(priorProgram);
1303 
1304 		if(newProgram)
1305 		{
1306 			newProgram->addRef();
1307 		}
1308 
1309 		if(oldProgram)
1310 		{
1311 			oldProgram->release();
1312 		}
1313 	}
1314 }
1315 
beginQuery(GLenum target,GLuint query)1316 void Context::beginQuery(GLenum target, GLuint query)
1317 {
1318 	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1319 	// of zero, if the active query object name for <target> is non-zero (for the
1320 	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1321 	// the active query for either target is non-zero), if <id> is the name of an
1322 	// existing query object whose type does not match <target>, or if <id> is the
1323 	// active query object name for any query type, the error INVALID_OPERATION is
1324 	// generated.
1325 
1326 	// Ensure no other queries are active
1327 	// NOTE: If other queries than occlusion are supported, we will need to check
1328 	// separately that:
1329 	//    a) The query ID passed is not the current active query for any target/type
1330 	//    b) There are no active queries for the requested target (and in the case
1331 	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1332 	//       no query may be active for either if glBeginQuery targets either.
1333 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1334 	{
1335 		if(mState.activeQuery[i])
1336 		{
1337 			switch(mState.activeQuery[i]->getType())
1338 			{
1339 			case GL_ANY_SAMPLES_PASSED_EXT:
1340 			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1341 				if((target == GL_ANY_SAMPLES_PASSED_EXT) ||
1342 				   (target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT))
1343 				{
1344 					return error(GL_INVALID_OPERATION);
1345 				}
1346 				break;
1347 			case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1348 				if(target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
1349 				{
1350 					return error(GL_INVALID_OPERATION);
1351 				}
1352 				break;
1353 			default:
1354 				break;
1355 			}
1356 		}
1357 	}
1358 
1359 	QueryType qType;
1360 	switch(target)
1361 	{
1362 	case GL_ANY_SAMPLES_PASSED_EXT:
1363 		qType = QUERY_ANY_SAMPLES_PASSED;
1364 		break;
1365 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1366 		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1367 		break;
1368 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1369 		qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1370 		break;
1371 	default:
1372 		UNREACHABLE(target);
1373 		return error(GL_INVALID_ENUM);
1374 	}
1375 
1376 	Query *queryObject = createQuery(query, target);
1377 
1378 	// Check that name was obtained with glGenQueries
1379 	if(!queryObject)
1380 	{
1381 		return error(GL_INVALID_OPERATION);
1382 	}
1383 
1384 	// Check for type mismatch
1385 	if(queryObject->getType() != target)
1386 	{
1387 		return error(GL_INVALID_OPERATION);
1388 	}
1389 
1390 	// Set query as active for specified target
1391 	mState.activeQuery[qType] = queryObject;
1392 
1393 	// Begin query
1394 	queryObject->begin();
1395 }
1396 
endQuery(GLenum target)1397 void Context::endQuery(GLenum target)
1398 {
1399 	QueryType qType;
1400 
1401 	switch(target)
1402 	{
1403 	case GL_ANY_SAMPLES_PASSED_EXT:                qType = QUERY_ANY_SAMPLES_PASSED;                    break;
1404 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;       break;
1405 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
1406 	default: UNREACHABLE(target); return;
1407 	}
1408 
1409 	Query *queryObject = mState.activeQuery[qType];
1410 
1411 	if(!queryObject)
1412 	{
1413 		return error(GL_INVALID_OPERATION);
1414 	}
1415 
1416 	queryObject->end();
1417 
1418 	mState.activeQuery[qType] = nullptr;
1419 }
1420 
setFramebufferZero(Framebuffer * buffer)1421 void Context::setFramebufferZero(Framebuffer *buffer)
1422 {
1423 	delete mFramebufferNameSpace.remove(0);
1424 	mFramebufferNameSpace.insert(0, buffer);
1425 }
1426 
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1427 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1428 {
1429 	Renderbuffer *renderbufferObject = mState.renderbuffer;
1430 	renderbufferObject->setStorage(renderbuffer);
1431 }
1432 
getFramebuffer(unsigned int handle) const1433 Framebuffer *Context::getFramebuffer(unsigned int handle) const
1434 {
1435 	return mFramebufferNameSpace.find(handle);
1436 }
1437 
getFence(unsigned int handle) const1438 Fence *Context::getFence(unsigned int handle) const
1439 {
1440 	return mFenceNameSpace.find(handle);
1441 }
1442 
getFenceSync(GLsync handle) const1443 FenceSync *Context::getFenceSync(GLsync handle) const
1444 {
1445 	return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
1446 }
1447 
getQuery(unsigned int handle) const1448 Query *Context::getQuery(unsigned int handle) const
1449 {
1450 	return mQueryNameSpace.find(handle);
1451 }
1452 
createQuery(unsigned int handle,GLenum type)1453 Query *Context::createQuery(unsigned int handle, GLenum type)
1454 {
1455 	if(!mQueryNameSpace.isReserved(handle))
1456 	{
1457 		return nullptr;
1458 	}
1459 	else
1460 	{
1461 		Query *query = mQueryNameSpace.find(handle);
1462 		if(!query)
1463 		{
1464 			query = new Query(handle, type);
1465 			query->addRef();
1466 			mQueryNameSpace.insert(handle, query);
1467 		}
1468 
1469 		return query;
1470 	}
1471 }
1472 
getVertexArray(GLuint array) const1473 VertexArray *Context::getVertexArray(GLuint array) const
1474 {
1475 	return mVertexArrayNameSpace.find(array);
1476 }
1477 
getCurrentVertexArray() const1478 VertexArray *Context::getCurrentVertexArray() const
1479 {
1480 	return getVertexArray(mState.vertexArray);
1481 }
1482 
isVertexArray(GLuint array) const1483 bool Context::isVertexArray(GLuint array) const
1484 {
1485 	return mVertexArrayNameSpace.isReserved(array);
1486 }
1487 
hasZeroDivisor() const1488 bool Context::hasZeroDivisor() const
1489 {
1490 	// Verify there is at least one active attribute with a divisor of zero
1491 	es2::Program *programObject = getCurrentProgram();
1492 	for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
1493 	{
1494 		bool active = (programObject->getAttributeStream(attributeIndex) != -1);
1495 		if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
1496 		{
1497 			return true;
1498 		}
1499 	}
1500 
1501 	return false;
1502 }
1503 
getTransformFeedback(GLuint transformFeedback) const1504 TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
1505 {
1506 	return mTransformFeedbackNameSpace.find(transformFeedback);
1507 }
1508 
isTransformFeedback(GLuint array) const1509 bool Context::isTransformFeedback(GLuint array) const
1510 {
1511 	return mTransformFeedbackNameSpace.isReserved(array);
1512 }
1513 
getSampler(GLuint sampler) const1514 Sampler *Context::getSampler(GLuint sampler) const
1515 {
1516 	return mResourceManager->getSampler(sampler);
1517 }
1518 
isSampler(GLuint sampler) const1519 bool Context::isSampler(GLuint sampler) const
1520 {
1521 	return mResourceManager->isSampler(sampler);
1522 }
1523 
getArrayBuffer() const1524 Buffer *Context::getArrayBuffer() const
1525 {
1526 	return mState.arrayBuffer;
1527 }
1528 
getElementArrayBuffer() const1529 Buffer *Context::getElementArrayBuffer() const
1530 {
1531 	return getCurrentVertexArray()->getElementArrayBuffer();
1532 }
1533 
getCopyReadBuffer() const1534 Buffer *Context::getCopyReadBuffer() const
1535 {
1536 	return mState.copyReadBuffer;
1537 }
1538 
getCopyWriteBuffer() const1539 Buffer *Context::getCopyWriteBuffer() const
1540 {
1541 	return mState.copyWriteBuffer;
1542 }
1543 
getPixelPackBuffer() const1544 Buffer *Context::getPixelPackBuffer() const
1545 {
1546 	return mState.pixelPackBuffer;
1547 }
1548 
getPixelUnpackBuffer() const1549 Buffer *Context::getPixelUnpackBuffer() const
1550 {
1551 	return mState.pixelUnpackBuffer;
1552 }
1553 
getGenericUniformBuffer() const1554 Buffer *Context::getGenericUniformBuffer() const
1555 {
1556 	return mState.genericUniformBuffer;
1557 }
1558 
getRequiredBufferSize(GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type) const1559 GLsizei Context::getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type) const
1560 {
1561 	GLsizei inputWidth = (mState.unpackParameters.rowLength == 0) ? width : mState.unpackParameters.rowLength;
1562 	GLsizei inputPitch = gl::ComputePitch(inputWidth, format, type, mState.unpackParameters.alignment);
1563 	GLsizei inputHeight = (mState.unpackParameters.imageHeight == 0) ? height : mState.unpackParameters.imageHeight;
1564 	return inputPitch * inputHeight * depth;
1565 }
1566 
getPixels(const GLvoid ** pixels,GLenum type,GLsizei imageSize) const1567 GLenum Context::getPixels(const GLvoid **pixels, GLenum type, GLsizei imageSize) const
1568 {
1569 	if(mState.pixelUnpackBuffer)
1570 	{
1571 		ASSERT(mState.pixelUnpackBuffer->name != 0);
1572 
1573 		if(mState.pixelUnpackBuffer->isMapped())
1574 		{
1575 			return GL_INVALID_OPERATION;
1576 		}
1577 
1578 		size_t offset = static_cast<size_t>((ptrdiff_t)(*pixels));
1579 
1580 		if(offset % GetTypeSize(type) != 0)
1581 		{
1582 			return GL_INVALID_OPERATION;
1583 		}
1584 
1585 		if(offset > mState.pixelUnpackBuffer->size())
1586 		{
1587 			return GL_INVALID_OPERATION;
1588 		}
1589 
1590 		if(mState.pixelUnpackBuffer->size() - offset < static_cast<size_t>(imageSize))
1591 		{
1592 			return GL_INVALID_OPERATION;
1593 		}
1594 
1595 		*pixels = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + offset;
1596 	}
1597 
1598 	return GL_NO_ERROR;
1599 }
1600 
getBuffer(GLenum target,es2::Buffer ** buffer) const1601 bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
1602 {
1603 	switch(target)
1604 	{
1605 	case GL_ARRAY_BUFFER:
1606 		*buffer = getArrayBuffer();
1607 		break;
1608 	case GL_ELEMENT_ARRAY_BUFFER:
1609 		*buffer = getElementArrayBuffer();
1610 		break;
1611 	case GL_COPY_READ_BUFFER:
1612 		*buffer = getCopyReadBuffer();
1613 		break;
1614 	case GL_COPY_WRITE_BUFFER:
1615 		*buffer = getCopyWriteBuffer();
1616 		break;
1617 	case GL_PIXEL_PACK_BUFFER:
1618 		*buffer = getPixelPackBuffer();
1619 		break;
1620 	case GL_PIXEL_UNPACK_BUFFER:
1621 		*buffer = getPixelUnpackBuffer();
1622 		break;
1623 	case GL_TRANSFORM_FEEDBACK_BUFFER:
1624 		{
1625 			TransformFeedback* transformFeedback = getTransformFeedback();
1626 			*buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;
1627 		}
1628 		break;
1629 	case GL_UNIFORM_BUFFER:
1630 		*buffer = getGenericUniformBuffer();
1631 		break;
1632 	default:
1633 		return false;
1634 	}
1635 	return true;
1636 }
1637 
getTransformFeedback() const1638 TransformFeedback *Context::getTransformFeedback() const
1639 {
1640 	return getTransformFeedback(mState.transformFeedback);
1641 }
1642 
getCurrentProgram() const1643 Program *Context::getCurrentProgram() const
1644 {
1645 	return mResourceManager->getProgram(mState.currentProgram);
1646 }
1647 
getTexture2D() const1648 Texture2D *Context::getTexture2D() const
1649 {
1650 	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1651 }
1652 
getTexture2D(GLenum target) const1653 Texture2D *Context::getTexture2D(GLenum target) const
1654 {
1655 	switch(target)
1656 	{
1657 	case GL_TEXTURE_2D:            return getTexture2D();
1658 	case GL_TEXTURE_RECTANGLE_ARB: return getTexture2DRect();
1659 	case GL_TEXTURE_EXTERNAL_OES:  return getTextureExternal();
1660 	default:                       UNREACHABLE(target);
1661 	}
1662 
1663 	return nullptr;
1664 }
1665 
getTexture3D() const1666 Texture3D *Context::getTexture3D() const
1667 {
1668 	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1669 }
1670 
getTexture2DArray() const1671 Texture2DArray *Context::getTexture2DArray() const
1672 {
1673 	return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1674 }
1675 
getTextureCubeMap() const1676 TextureCubeMap *Context::getTextureCubeMap() const
1677 {
1678 	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1679 }
1680 
getTexture2DRect() const1681 Texture2DRect *Context::getTexture2DRect() const
1682 {
1683 	return static_cast<Texture2DRect*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_RECT));
1684 }
1685 
getTextureExternal() const1686 TextureExternal *Context::getTextureExternal() const
1687 {
1688 	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1689 }
1690 
getSamplerTexture(unsigned int sampler,TextureType type) const1691 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1692 {
1693 	GLuint texid = mState.samplerTexture[type][sampler].name();
1694 
1695 	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1696 	{
1697 		switch(type)
1698 		{
1699 		case TEXTURE_2D: return mTexture2DZero;
1700 		case TEXTURE_3D: return mTexture3DZero;
1701 		case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
1702 		case TEXTURE_CUBE: return mTextureCubeMapZero;
1703 		case TEXTURE_2D_RECT: return mTexture2DRectZero;
1704 		case TEXTURE_EXTERNAL: return mTextureExternalZero;
1705 		default: UNREACHABLE(type);
1706 		}
1707 	}
1708 
1709 	return mState.samplerTexture[type][sampler];
1710 }
1711 
samplerParameteri(GLuint sampler,GLenum pname,GLint param)1712 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1713 {
1714 	mResourceManager->checkSamplerAllocation(sampler);
1715 
1716 	Sampler *samplerObject = getSampler(sampler);
1717 	ASSERT(samplerObject);
1718 
1719 	switch(pname)
1720 	{
1721 	case GL_TEXTURE_MIN_FILTER:         samplerObject->setMinFilter(static_cast<GLenum>(param));      break;
1722 	case GL_TEXTURE_MAG_FILTER:         samplerObject->setMagFilter(static_cast<GLenum>(param));      break;
1723 	case GL_TEXTURE_WRAP_S:             samplerObject->setWrapS(static_cast<GLenum>(param));          break;
1724 	case GL_TEXTURE_WRAP_T:             samplerObject->setWrapT(static_cast<GLenum>(param));          break;
1725 	case GL_TEXTURE_WRAP_R:             samplerObject->setWrapR(static_cast<GLenum>(param));          break;
1726 	case GL_TEXTURE_MIN_LOD:            samplerObject->setMinLod(static_cast<GLfloat>(param));        break;
1727 	case GL_TEXTURE_MAX_LOD:            samplerObject->setMaxLod(static_cast<GLfloat>(param));        break;
1728 	case GL_TEXTURE_COMPARE_MODE:       samplerObject->setCompareMode(static_cast<GLenum>(param));    break;
1729 	case GL_TEXTURE_COMPARE_FUNC:       samplerObject->setCompareFunc(static_cast<GLenum>(param));    break;
1730 	case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(static_cast<GLfloat>(param)); break;
1731 	default:                            UNREACHABLE(pname); break;
1732 	}
1733 }
1734 
samplerParameterf(GLuint sampler,GLenum pname,GLfloat param)1735 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1736 {
1737 	mResourceManager->checkSamplerAllocation(sampler);
1738 
1739 	Sampler *samplerObject = getSampler(sampler);
1740 	ASSERT(samplerObject);
1741 
1742 	switch(pname)
1743 	{
1744 	case GL_TEXTURE_MIN_FILTER:         samplerObject->setMinFilter(static_cast<GLenum>(roundf(param)));   break;
1745 	case GL_TEXTURE_MAG_FILTER:         samplerObject->setMagFilter(static_cast<GLenum>(roundf(param)));   break;
1746 	case GL_TEXTURE_WRAP_S:             samplerObject->setWrapS(static_cast<GLenum>(roundf(param)));       break;
1747 	case GL_TEXTURE_WRAP_T:             samplerObject->setWrapT(static_cast<GLenum>(roundf(param)));       break;
1748 	case GL_TEXTURE_WRAP_R:             samplerObject->setWrapR(static_cast<GLenum>(roundf(param)));       break;
1749 	case GL_TEXTURE_MIN_LOD:            samplerObject->setMinLod(param);                                   break;
1750 	case GL_TEXTURE_MAX_LOD:            samplerObject->setMaxLod(param);                                   break;
1751 	case GL_TEXTURE_COMPARE_MODE:       samplerObject->setCompareMode(static_cast<GLenum>(roundf(param))); break;
1752 	case GL_TEXTURE_COMPARE_FUNC:       samplerObject->setCompareFunc(static_cast<GLenum>(roundf(param))); break;
1753 	case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(param);                            break;
1754 	default:                            UNREACHABLE(pname); break;
1755 	}
1756 }
1757 
getSamplerParameteri(GLuint sampler,GLenum pname)1758 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1759 {
1760 	mResourceManager->checkSamplerAllocation(sampler);
1761 
1762 	Sampler *samplerObject = getSampler(sampler);
1763 	ASSERT(samplerObject);
1764 
1765 	switch(pname)
1766 	{
1767 	case GL_TEXTURE_MIN_FILTER:         return static_cast<GLint>(samplerObject->getMinFilter());
1768 	case GL_TEXTURE_MAG_FILTER:         return static_cast<GLint>(samplerObject->getMagFilter());
1769 	case GL_TEXTURE_WRAP_S:             return static_cast<GLint>(samplerObject->getWrapS());
1770 	case GL_TEXTURE_WRAP_T:             return static_cast<GLint>(samplerObject->getWrapT());
1771 	case GL_TEXTURE_WRAP_R:             return static_cast<GLint>(samplerObject->getWrapR());
1772 	case GL_TEXTURE_MIN_LOD:            return static_cast<GLint>(roundf(samplerObject->getMinLod()));
1773 	case GL_TEXTURE_MAX_LOD:            return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
1774 	case GL_TEXTURE_COMPARE_MODE:       return static_cast<GLint>(samplerObject->getCompareMode());
1775 	case GL_TEXTURE_COMPARE_FUNC:       return static_cast<GLint>(samplerObject->getCompareFunc());
1776 	case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1777 	default:                            UNREACHABLE(pname); return 0;
1778 	}
1779 }
1780 
getSamplerParameterf(GLuint sampler,GLenum pname)1781 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1782 {
1783 	mResourceManager->checkSamplerAllocation(sampler);
1784 
1785 	Sampler *samplerObject = getSampler(sampler);
1786 	ASSERT(samplerObject);
1787 
1788 	switch(pname)
1789 	{
1790 	case GL_TEXTURE_MIN_FILTER:         return static_cast<GLfloat>(samplerObject->getMinFilter());
1791 	case GL_TEXTURE_MAG_FILTER:         return static_cast<GLfloat>(samplerObject->getMagFilter());
1792 	case GL_TEXTURE_WRAP_S:             return static_cast<GLfloat>(samplerObject->getWrapS());
1793 	case GL_TEXTURE_WRAP_T:             return static_cast<GLfloat>(samplerObject->getWrapT());
1794 	case GL_TEXTURE_WRAP_R:             return static_cast<GLfloat>(samplerObject->getWrapR());
1795 	case GL_TEXTURE_MIN_LOD:            return samplerObject->getMinLod();
1796 	case GL_TEXTURE_MAX_LOD:            return samplerObject->getMaxLod();
1797 	case GL_TEXTURE_COMPARE_MODE:       return static_cast<GLfloat>(samplerObject->getCompareMode());
1798 	case GL_TEXTURE_COMPARE_FUNC:       return static_cast<GLfloat>(samplerObject->getCompareFunc());
1799 	case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1800 	default:                            UNREACHABLE(pname); return 0;
1801 	}
1802 }
1803 
getBooleanv(GLenum pname,GLboolean * params) const1804 bool Context::getBooleanv(GLenum pname, GLboolean *params) const
1805 {
1806 	switch(pname)
1807 	{
1808 	case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
1809 	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
1810 	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
1811 	case GL_COLOR_WRITEMASK:
1812 		params[0] = mState.colorMaskRed;
1813 		params[1] = mState.colorMaskGreen;
1814 		params[2] = mState.colorMaskBlue;
1815 		params[3] = mState.colorMaskAlpha;
1816 		break;
1817 	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;                  break;
1818 	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;         break;
1819 	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled;     break;
1820 	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;            break;
1821 	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;               break;
1822 	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;               break;
1823 	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;                 break;
1824 	case GL_BLEND:                    *params = mState.blendEnabled;                     break;
1825 	case GL_DITHER:                   *params = mState.ditherEnabled;                    break;
1826 	case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
1827 	case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscardEnabled;         break;
1828 	case GL_TRANSFORM_FEEDBACK_ACTIVE:
1829 		{
1830 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1831 			if(transformFeedback)
1832 			{
1833 				*params = transformFeedback->isActive();
1834 				break;
1835 			}
1836 			else return false;
1837 		}
1838 	 case GL_TRANSFORM_FEEDBACK_PAUSED:
1839 		{
1840 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1841 			if(transformFeedback)
1842 			{
1843 				*params = transformFeedback->isPaused();
1844 				break;
1845 			}
1846 			else return false;
1847 		}
1848 	default:
1849 		return false;
1850 	}
1851 
1852 	return true;
1853 }
1854 
getFloatv(GLenum pname,GLfloat * params) const1855 bool Context::getFloatv(GLenum pname, GLfloat *params) const
1856 {
1857 	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1858 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1859 	// GetIntegerv as its native query function. As it would require conversion in any
1860 	// case, this should make no difference to the calling application.
1861 	switch(pname)
1862 	{
1863 	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1864 	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1865 	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1866 	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1867 	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1868 	case GL_ALIASED_LINE_WIDTH_RANGE:
1869 		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1870 		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1871 		break;
1872 	case GL_ALIASED_POINT_SIZE_RANGE:
1873 		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1874 		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1875 		break;
1876 	case GL_DEPTH_RANGE:
1877 		params[0] = mState.zNear;
1878 		params[1] = mState.zFar;
1879 		break;
1880 	case GL_COLOR_CLEAR_VALUE:
1881 		params[0] = mState.colorClearValue.red;
1882 		params[1] = mState.colorClearValue.green;
1883 		params[2] = mState.colorClearValue.blue;
1884 		params[3] = mState.colorClearValue.alpha;
1885 		break;
1886 	case GL_BLEND_COLOR:
1887 		params[0] = mState.blendColor.red;
1888 		params[1] = mState.blendColor.green;
1889 		params[2] = mState.blendColor.blue;
1890 		params[3] = mState.blendColor.alpha;
1891 		break;
1892 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1893 		*params = MAX_TEXTURE_MAX_ANISOTROPY;
1894 		break;
1895 	default:
1896 		return false;
1897 	}
1898 
1899 	return true;
1900 }
1901 
1902 template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
1903 template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
1904 
getIntegerv(GLenum pname,T * params) const1905 template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
1906 {
1907 	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1908 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1909 	// GetIntegerv as its native query function. As it would require conversion in any
1910 	// case, this should make no difference to the calling application. You may find it in
1911 	// Context::getFloatv.
1912 	switch(pname)
1913 	{
1914 	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               return true;
1915 	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       return true;
1916 	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              return true;
1917 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; return true;
1918 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return true;
1919 	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          return true;
1920 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     return true;
1921 	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; return true;
1922 	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    return true;
1923 	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          return true;
1924 	case GL_ARRAY_BUFFER_BINDING:             *params = getArrayBufferName();                 return true;
1925 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = getElementArrayBufferName();          return true;
1926 //	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1927 	case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               return true;
1928 	case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               return true;
1929 	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           return true;
1930 	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                return true;
1931 	case GL_PACK_ALIGNMENT:                   *params = mState.packParameters.alignment;                 return true;
1932 	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackParameters.alignment;          return true;
1933 	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            return true;
1934 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; return true;
1935 	case GL_TEXTURE_FILTERING_HINT_CHROMIUM:  *params = mState.textureFilteringHint;          return true;
1936 	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); return true;
1937 	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   return true;
1938 	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    return true;
1939 	case GL_STENCIL_VALUE_MASK:               *params = sw::clampToSignedInt(mState.stencilMask); return true;
1940 	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               return true;
1941 	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                return true;
1942 	case GL_STENCIL_BACK_VALUE_MASK:          *params = sw::clampToSignedInt(mState.stencilBackMask); return true;
1943 	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   return true;
1944 	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          return true;
1945 	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          return true;
1946 	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               return true;
1947 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      return true;
1948 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      return true;
1949 	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     return true;
1950 	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                return true;
1951 	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              return true;
1952 	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  return true;
1953 	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                return true;
1954 	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              return true;
1955 	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            return true;
1956 	case GL_STENCIL_WRITEMASK:                *params = sw::clampToSignedInt(mState.stencilWritemask); return true;
1957 	case GL_STENCIL_BACK_WRITEMASK:           *params = sw::clampToSignedInt(mState.stencilBackWritemask); return true;
1958 	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             return true;
1959 	case GL_SUBPIXEL_BITS:                    *params = 4;                                    return true;
1960 	case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
1961 	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          return true;
1962 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; return true;
1963 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           return true;
1964 	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;               return true;
1965 	case GL_SAMPLE_BUFFERS:
1966 	case GL_SAMPLES:
1967 		{
1968 			Framebuffer *framebuffer = getDrawFramebuffer();
1969 			int width, height, samples;
1970 
1971 			if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE))
1972 			{
1973 				switch(pname)
1974 				{
1975 				case GL_SAMPLE_BUFFERS:
1976 					if(samples > 1)
1977 					{
1978 						*params = 1;
1979 					}
1980 					else
1981 					{
1982 						*params = 0;
1983 					}
1984 					break;
1985 				case GL_SAMPLES:
1986 					*params = samples;
1987 					break;
1988 				}
1989 			}
1990 			else
1991 			{
1992 				*params = 0;
1993 			}
1994 		}
1995 		return true;
1996 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1997 		{
1998 			Framebuffer *framebuffer = getReadFramebuffer();
1999 			if(framebuffer)
2000 			{
2001 				*params = framebuffer->getImplementationColorReadType();
2002 			}
2003 			else
2004 			{
2005 				return error(GL_INVALID_OPERATION, true);
2006 			}
2007 		}
2008 		return true;
2009 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2010 		{
2011 			Framebuffer *framebuffer = getReadFramebuffer();
2012 			if(framebuffer)
2013 			{
2014 				*params = framebuffer->getImplementationColorReadFormat();
2015 			}
2016 			else
2017 			{
2018 				return error(GL_INVALID_OPERATION, true);
2019 			}
2020 		}
2021 		return true;
2022 	case GL_MAX_VIEWPORT_DIMS:
2023 		{
2024 			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
2025 			params[0] = maxDimension;
2026 			params[1] = maxDimension;
2027 		}
2028 		return true;
2029 	case GL_COMPRESSED_TEXTURE_FORMATS:
2030 		{
2031 			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
2032 			{
2033 				params[i] = compressedTextureFormats[i];
2034 			}
2035 		}
2036 		return true;
2037 	case GL_VIEWPORT:
2038 		params[0] = mState.viewportX;
2039 		params[1] = mState.viewportY;
2040 		params[2] = mState.viewportWidth;
2041 		params[3] = mState.viewportHeight;
2042 		return true;
2043 	case GL_SCISSOR_BOX:
2044 		params[0] = mState.scissorX;
2045 		params[1] = mState.scissorY;
2046 		params[2] = mState.scissorWidth;
2047 		params[3] = mState.scissorHeight;
2048 		return true;
2049 	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 return true;
2050 	case GL_FRONT_FACE:                       *params = mState.frontFace;                return true;
2051 	case GL_RED_BITS:
2052 	case GL_GREEN_BITS:
2053 	case GL_BLUE_BITS:
2054 	case GL_ALPHA_BITS:
2055 		{
2056 			Framebuffer *framebuffer = getDrawFramebuffer();
2057 			Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer(0) : nullptr;
2058 
2059 			if(colorbuffer)
2060 			{
2061 				switch(pname)
2062 				{
2063 				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   return true;
2064 				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); return true;
2065 				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  return true;
2066 				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); return true;
2067 				}
2068 			}
2069 			else
2070 			{
2071 				*params = 0;
2072 			}
2073 		}
2074 		return true;
2075 	case GL_DEPTH_BITS:
2076 		{
2077 			Framebuffer *framebuffer = getDrawFramebuffer();
2078 			Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
2079 
2080 			if(depthbuffer)
2081 			{
2082 				*params = depthbuffer->getDepthSize();
2083 			}
2084 			else
2085 			{
2086 				*params = 0;
2087 			}
2088 		}
2089 		return true;
2090 	case GL_STENCIL_BITS:
2091 		{
2092 			Framebuffer *framebuffer = getDrawFramebuffer();
2093 			Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
2094 
2095 			if(stencilbuffer)
2096 			{
2097 				*params = stencilbuffer->getStencilSize();
2098 			}
2099 			else
2100 			{
2101 				*params = 0;
2102 			}
2103 		}
2104 		return true;
2105 	case GL_TEXTURE_BINDING_2D:
2106 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2107 		{
2108 			error(GL_INVALID_OPERATION);
2109 			return false;
2110 		}
2111 
2112 		*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
2113 		return true;
2114 	case GL_TEXTURE_BINDING_CUBE_MAP:
2115 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2116 		{
2117 			error(GL_INVALID_OPERATION);
2118 			return false;
2119 		}
2120 
2121 		*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
2122 		return true;
2123 	case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2124 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2125 		{
2126 			error(GL_INVALID_OPERATION);
2127 			return false;
2128 		}
2129 
2130 		*params = mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler].name();
2131 		return true;
2132 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
2133 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2134 		{
2135 			error(GL_INVALID_OPERATION);
2136 			return false;
2137 		}
2138 
2139 		*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
2140 		return true;
2141 	case GL_TEXTURE_BINDING_3D_OES:
2142 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2143 		{
2144 			error(GL_INVALID_OPERATION);
2145 			return false;
2146 		}
2147 
2148 		*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
2149 		return true;
2150 	case GL_DRAW_BUFFER0:
2151 	case GL_DRAW_BUFFER1:
2152 	case GL_DRAW_BUFFER2:
2153 	case GL_DRAW_BUFFER3:
2154 	case GL_DRAW_BUFFER4:
2155 	case GL_DRAW_BUFFER5:
2156 	case GL_DRAW_BUFFER6:
2157 	case GL_DRAW_BUFFER7:
2158 	case GL_DRAW_BUFFER8:
2159 	case GL_DRAW_BUFFER9:
2160 	case GL_DRAW_BUFFER10:
2161 	case GL_DRAW_BUFFER11:
2162 	case GL_DRAW_BUFFER12:
2163 	case GL_DRAW_BUFFER13:
2164 	case GL_DRAW_BUFFER14:
2165 	case GL_DRAW_BUFFER15:
2166 		if((pname - GL_DRAW_BUFFER0) < MAX_DRAW_BUFFERS)
2167 		{
2168 			Framebuffer* framebuffer = getDrawFramebuffer();
2169 			*params = framebuffer ? framebuffer->getDrawBuffer(pname - GL_DRAW_BUFFER0) : GL_NONE;
2170 		}
2171 		else
2172 		{
2173 			return false;
2174 		}
2175 		return true;
2176 	case GL_MAX_DRAW_BUFFERS:
2177 		*params = MAX_DRAW_BUFFERS;
2178 		return true;
2179 	case GL_MAX_COLOR_ATTACHMENTS: // Note: MAX_COLOR_ATTACHMENTS_EXT added by GL_EXT_draw_buffers
2180 		*params = MAX_COLOR_ATTACHMENTS;
2181 		return true;
2182 	case GL_TEXTURE_BINDING_2D_ARRAY:
2183 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2184 		{
2185 			error(GL_INVALID_OPERATION);
2186 			return false;
2187 		}
2188 
2189 		*params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
2190 		return true;
2191 	case GL_COPY_READ_BUFFER_BINDING:
2192 		*params = mState.copyReadBuffer.name();
2193 		return true;
2194 	case GL_COPY_WRITE_BUFFER_BINDING:
2195 		*params = mState.copyWriteBuffer.name();
2196 		return true;
2197 	case GL_MAJOR_VERSION:
2198 		*params = 3;
2199 		return true;
2200 	case GL_MINOR_VERSION:
2201 		*params = 0;
2202 		return true;
2203 	case GL_MAX_3D_TEXTURE_SIZE:
2204 		*params = IMPLEMENTATION_MAX_3D_TEXTURE_SIZE;
2205 		return true;
2206 	case GL_MAX_ARRAY_TEXTURE_LAYERS:
2207 		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2208 		return true;
2209 	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2210 		*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
2211 		return true;
2212 	case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2213 		*params = MAX_VERTEX_UNIFORM_BLOCKS + MAX_FRAGMENT_UNIFORM_BLOCKS;
2214 		return true;
2215 	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2216 		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
2217 		return true;
2218 	case GL_MAX_ELEMENT_INDEX:
2219 		*params = MAX_ELEMENT_INDEX;
2220 		return true;
2221 	case GL_MAX_ELEMENTS_INDICES:
2222 		*params = MAX_ELEMENTS_INDICES;
2223 		return true;
2224 	case GL_MAX_ELEMENTS_VERTICES:
2225 		*params = MAX_ELEMENTS_VERTICES;
2226 		return true;
2227 	case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2228 		*params = MAX_FRAGMENT_INPUT_VECTORS * 4;
2229 		return true;
2230 	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2231 		*params = MAX_FRAGMENT_UNIFORM_BLOCKS;
2232 		return true;
2233 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2234 		*params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
2235 		return true;
2236 	case GL_MAX_PROGRAM_TEXEL_OFFSET:
2237 		// Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2238 		// In any case, any behavior outside the specified range is valid since the spec mentions:
2239 		// (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2240 		// "If any of the offset values are outside the range of the  implementation-defined values
2241 		//  MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2242 		//  undefined."
2243 		*params = MAX_PROGRAM_TEXEL_OFFSET;
2244 		return true;
2245 	case GL_MAX_SERVER_WAIT_TIMEOUT:
2246 		*params = 0;
2247 		return true;
2248 	case GL_MAX_TEXTURE_LOD_BIAS:
2249 		*params = MAX_TEXTURE_LOD_BIAS;
2250 		return true;
2251 	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2252 		*params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
2253 		return true;
2254 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2255 		*params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
2256 		return true;
2257 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2258 		*params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
2259 		return true;
2260 	case GL_MAX_UNIFORM_BLOCK_SIZE:
2261 		*params = MAX_UNIFORM_BLOCK_SIZE;
2262 		return true;
2263 	case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2264 		*params = MAX_UNIFORM_BUFFER_BINDINGS;
2265 		return true;
2266 	case GL_MAX_VARYING_COMPONENTS:
2267 		*params = MAX_VARYING_VECTORS * 4;
2268 		return true;
2269 	case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2270 		*params = MAX_VERTEX_OUTPUT_VECTORS * 4;
2271 		return true;
2272 	case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2273 		*params = MAX_VERTEX_UNIFORM_BLOCKS;
2274 		return true;
2275 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2276 		*params = MAX_VERTEX_UNIFORM_COMPONENTS;
2277 		return true;
2278 	case GL_MIN_PROGRAM_TEXEL_OFFSET:
2279 		// Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2280 		// In any case, any behavior outside the specified range is valid since the spec mentions:
2281 		// (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2282 		// "If any of the offset values are outside the range of the  implementation-defined values
2283 		//  MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2284 		//  undefined."
2285 		*params = MIN_PROGRAM_TEXEL_OFFSET;
2286 		return true;
2287 	case GL_NUM_EXTENSIONS:
2288 		GLuint numExtensions;
2289 		getExtensions(0, &numExtensions);
2290 		*params = numExtensions;
2291 		return true;
2292 	case GL_NUM_PROGRAM_BINARY_FORMATS:
2293 		*params = NUM_PROGRAM_BINARY_FORMATS;
2294 		return true;
2295 	case GL_PACK_ROW_LENGTH:
2296 		*params = mState.packParameters.rowLength;
2297 		return true;
2298 	case GL_PACK_SKIP_PIXELS:
2299 		*params = mState.packParameters.skipPixels;
2300 		return true;
2301 	case GL_PACK_SKIP_ROWS:
2302 		*params = mState.packParameters.skipRows;
2303 		return true;
2304 	case GL_PIXEL_PACK_BUFFER_BINDING:
2305 		*params = mState.pixelPackBuffer.name();
2306 		return true;
2307 	case GL_PIXEL_UNPACK_BUFFER_BINDING:
2308 		*params = mState.pixelUnpackBuffer.name();
2309 		return true;
2310 	case GL_PROGRAM_BINARY_FORMATS:
2311 		// Since NUM_PROGRAM_BINARY_FORMATS is 0, the input
2312 		// should be a 0 sized array, so don't write to params
2313 		return true;
2314 	case GL_READ_BUFFER:
2315 		{
2316 			Framebuffer* framebuffer = getReadFramebuffer();
2317 			*params = framebuffer ? framebuffer->getReadBuffer() : GL_NONE;
2318 		}
2319 		return true;
2320 	case GL_SAMPLER_BINDING:
2321 		*params = mState.sampler[mState.activeSampler].name();
2322 		return true;
2323 	case GL_UNIFORM_BUFFER_BINDING:
2324 		*params = mState.genericUniformBuffer.name();
2325 		return true;
2326 	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2327 		*params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
2328 		return true;
2329 	case GL_UNPACK_IMAGE_HEIGHT:
2330 		*params = mState.unpackParameters.imageHeight;
2331 		return true;
2332 	case GL_UNPACK_ROW_LENGTH:
2333 		*params = mState.unpackParameters.rowLength;
2334 		return true;
2335 	case GL_UNPACK_SKIP_IMAGES:
2336 		*params = mState.unpackParameters.skipImages;
2337 		return true;
2338 	case GL_UNPACK_SKIP_PIXELS:
2339 		*params = mState.unpackParameters.skipPixels;
2340 		return true;
2341 	case GL_UNPACK_SKIP_ROWS:
2342 		*params = mState.unpackParameters.skipRows;
2343 		return true;
2344 	case GL_VERTEX_ARRAY_BINDING:
2345 		*params = getCurrentVertexArray()->name;
2346 		return true;
2347 	case GL_TRANSFORM_FEEDBACK_BINDING:
2348 		{
2349 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2350 			if(transformFeedback)
2351 			{
2352 				*params = transformFeedback->name;
2353 			}
2354 			else
2355 			{
2356 				return false;
2357 			}
2358 		}
2359 		return true;
2360 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2361 		{
2362 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2363 			if(transformFeedback)
2364 			{
2365 				*params = transformFeedback->getGenericBufferName();
2366 			}
2367 			else
2368 			{
2369 				return false;
2370 			}
2371 		}
2372 		return true;
2373 	default:
2374 		break;
2375 	}
2376 
2377 	return false;
2378 }
2379 
2380 template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2381 template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2382 
getTransformFeedbackiv(GLuint index,GLenum pname,T * param) const2383 template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
2384 {
2385 	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2386 	if(!transformFeedback)
2387 	{
2388 		return false;
2389 	}
2390 
2391 	switch(pname)
2392 	{
2393 	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
2394 		*param = transformFeedback->name;
2395 		break;
2396 	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
2397 		*param = transformFeedback->isActive();
2398 		break;
2399 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
2400 		*param = transformFeedback->getBufferName(index);
2401 		break;
2402 	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
2403 		*param = transformFeedback->isPaused();
2404 		break;
2405 	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2406 		if(transformFeedback->getBuffer(index))
2407 		{
2408 			*param = transformFeedback->getSize(index);
2409 			break;
2410 		}
2411 		else return false;
2412 	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2413 		if(transformFeedback->getBuffer(index))
2414 		{
2415 			*param = transformFeedback->getOffset(index);
2416 			break;
2417 		}
2418 		else return false;
2419 	default:
2420 		return false;
2421 	}
2422 
2423 	return true;
2424 }
2425 
2426 template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2427 template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2428 
getUniformBufferiv(GLuint index,GLenum pname,T * param) const2429 template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
2430 {
2431 	switch(pname)
2432 	{
2433 	case GL_UNIFORM_BUFFER_BINDING:
2434 	case GL_UNIFORM_BUFFER_SIZE:
2435 	case GL_UNIFORM_BUFFER_START:
2436 		break;
2437 	default:
2438 		return false;
2439 	}
2440 
2441 	if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
2442 	{
2443 		return error(GL_INVALID_VALUE, true);
2444 	}
2445 
2446 	const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
2447 
2448 	switch(pname)
2449 	{
2450 	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2451 		*param = uniformBuffer.get().name();
2452 		break;
2453 	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2454 		*param = uniformBuffer.getSize();
2455 		break;
2456 	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2457 		*param = uniformBuffer.getOffset();
2458 		break;
2459 	default:
2460 		return false;
2461 	}
2462 
2463 	return true;
2464 }
2465 
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams) const2466 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
2467 {
2468 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2469 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2470 	// to the fact that it is stored internally as a float, and so would require conversion
2471 	// if returned from Context::getIntegerv. Since this conversion is already implemented
2472 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2473 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2474 	// application.
2475 	switch(pname)
2476 	{
2477 	case GL_COMPRESSED_TEXTURE_FORMATS:
2478 		{
2479 			*type = GL_INT;
2480 			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
2481 		}
2482 		break;
2483 	case GL_SHADER_BINARY_FORMATS:
2484 		{
2485 			*type = GL_INT;
2486 			*numParams = 0;
2487 		}
2488 		break;
2489 	case GL_MAX_VERTEX_ATTRIBS:
2490 	case GL_MAX_VERTEX_UNIFORM_VECTORS:
2491 	case GL_MAX_VARYING_VECTORS:
2492 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2493 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2494 	case GL_MAX_TEXTURE_IMAGE_UNITS:
2495 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2496 	case GL_MAX_RENDERBUFFER_SIZE:
2497 	case GL_NUM_SHADER_BINARY_FORMATS:
2498 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2499 	case GL_ARRAY_BUFFER_BINDING:
2500 	case GL_FRAMEBUFFER_BINDING:        // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2501 	case GL_READ_FRAMEBUFFER_BINDING:   // Same as GL_READ_FRAMEBUFFER_BINDING_ANGLE
2502 	case GL_RENDERBUFFER_BINDING:
2503 	case GL_CURRENT_PROGRAM:
2504 	case GL_PACK_ALIGNMENT:
2505 	case GL_UNPACK_ALIGNMENT:
2506 	case GL_GENERATE_MIPMAP_HINT:
2507 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2508 	case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2509 	case GL_RED_BITS:
2510 	case GL_GREEN_BITS:
2511 	case GL_BLUE_BITS:
2512 	case GL_ALPHA_BITS:
2513 	case GL_DEPTH_BITS:
2514 	case GL_STENCIL_BITS:
2515 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2516 	case GL_CULL_FACE_MODE:
2517 	case GL_FRONT_FACE:
2518 	case GL_ACTIVE_TEXTURE:
2519 	case GL_STENCIL_FUNC:
2520 	case GL_STENCIL_VALUE_MASK:
2521 	case GL_STENCIL_REF:
2522 	case GL_STENCIL_FAIL:
2523 	case GL_STENCIL_PASS_DEPTH_FAIL:
2524 	case GL_STENCIL_PASS_DEPTH_PASS:
2525 	case GL_STENCIL_BACK_FUNC:
2526 	case GL_STENCIL_BACK_VALUE_MASK:
2527 	case GL_STENCIL_BACK_REF:
2528 	case GL_STENCIL_BACK_FAIL:
2529 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2530 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2531 	case GL_DEPTH_FUNC:
2532 	case GL_BLEND_SRC_RGB:
2533 	case GL_BLEND_SRC_ALPHA:
2534 	case GL_BLEND_DST_RGB:
2535 	case GL_BLEND_DST_ALPHA:
2536 	case GL_BLEND_EQUATION_RGB:
2537 	case GL_BLEND_EQUATION_ALPHA:
2538 	case GL_STENCIL_WRITEMASK:
2539 	case GL_STENCIL_BACK_WRITEMASK:
2540 	case GL_STENCIL_CLEAR_VALUE:
2541 	case GL_SUBPIXEL_BITS:
2542 	case GL_MAX_TEXTURE_SIZE:
2543 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2544 	case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2545 	case GL_SAMPLE_BUFFERS:
2546 	case GL_SAMPLES:
2547 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2548 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2549 	case GL_TEXTURE_BINDING_2D:
2550 	case GL_TEXTURE_BINDING_CUBE_MAP:
2551 	case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2552 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
2553 	case GL_TEXTURE_BINDING_3D_OES:
2554 	case GL_COPY_READ_BUFFER_BINDING:
2555 	case GL_COPY_WRITE_BUFFER_BINDING:
2556 	case GL_DRAW_BUFFER0:
2557 	case GL_DRAW_BUFFER1:
2558 	case GL_DRAW_BUFFER2:
2559 	case GL_DRAW_BUFFER3:
2560 	case GL_DRAW_BUFFER4:
2561 	case GL_DRAW_BUFFER5:
2562 	case GL_DRAW_BUFFER6:
2563 	case GL_DRAW_BUFFER7:
2564 	case GL_DRAW_BUFFER8:
2565 	case GL_DRAW_BUFFER9:
2566 	case GL_DRAW_BUFFER10:
2567 	case GL_DRAW_BUFFER11:
2568 	case GL_DRAW_BUFFER12:
2569 	case GL_DRAW_BUFFER13:
2570 	case GL_DRAW_BUFFER14:
2571 	case GL_DRAW_BUFFER15:
2572 	case GL_MAJOR_VERSION:
2573 	case GL_MAX_3D_TEXTURE_SIZE:
2574 	case GL_MAX_ARRAY_TEXTURE_LAYERS:
2575 	case GL_MAX_COLOR_ATTACHMENTS:
2576 	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2577 	case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2578 	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2579 	case GL_MAX_DRAW_BUFFERS:
2580 	case GL_MAX_ELEMENT_INDEX:
2581 	case GL_MAX_ELEMENTS_INDICES:
2582 	case GL_MAX_ELEMENTS_VERTICES:
2583 	case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2584 	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2585 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2586 	case GL_MAX_PROGRAM_TEXEL_OFFSET:
2587 	case GL_MAX_SERVER_WAIT_TIMEOUT:
2588 	case GL_MAX_TEXTURE_LOD_BIAS:
2589 	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2590 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2591 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2592 	case GL_MAX_UNIFORM_BLOCK_SIZE:
2593 	case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2594 	case GL_MAX_VARYING_COMPONENTS:
2595 	case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2596 	case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2597 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2598 	case GL_MIN_PROGRAM_TEXEL_OFFSET:
2599 	case GL_MINOR_VERSION:
2600 	case GL_NUM_EXTENSIONS:
2601 	case GL_NUM_PROGRAM_BINARY_FORMATS:
2602 	case GL_PACK_ROW_LENGTH:
2603 	case GL_PACK_SKIP_PIXELS:
2604 	case GL_PACK_SKIP_ROWS:
2605 	case GL_PIXEL_PACK_BUFFER_BINDING:
2606 	case GL_PIXEL_UNPACK_BUFFER_BINDING:
2607 	case GL_PROGRAM_BINARY_FORMATS:
2608 	case GL_READ_BUFFER:
2609 	case GL_SAMPLER_BINDING:
2610 	case GL_TEXTURE_BINDING_2D_ARRAY:
2611 	case GL_UNIFORM_BUFFER_BINDING:
2612 	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2613 	case GL_UNPACK_IMAGE_HEIGHT:
2614 	case GL_UNPACK_ROW_LENGTH:
2615 	case GL_UNPACK_SKIP_IMAGES:
2616 	case GL_UNPACK_SKIP_PIXELS:
2617 	case GL_UNPACK_SKIP_ROWS:
2618 	case GL_VERTEX_ARRAY_BINDING:
2619 	case GL_TRANSFORM_FEEDBACK_BINDING:
2620 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2621 		{
2622 			*type = GL_INT;
2623 			*numParams = 1;
2624 		}
2625 		break;
2626 	case GL_MAX_SAMPLES:
2627 		{
2628 			*type = GL_INT;
2629 			*numParams = 1;
2630 		}
2631 		break;
2632 	case GL_MAX_VIEWPORT_DIMS:
2633 		{
2634 			*type = GL_INT;
2635 			*numParams = 2;
2636 		}
2637 		break;
2638 	case GL_VIEWPORT:
2639 	case GL_SCISSOR_BOX:
2640 		{
2641 			*type = GL_INT;
2642 			*numParams = 4;
2643 		}
2644 		break;
2645 	case GL_SHADER_COMPILER:
2646 	case GL_SAMPLE_COVERAGE_INVERT:
2647 	case GL_DEPTH_WRITEMASK:
2648 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
2649 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
2650 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2651 	case GL_SAMPLE_COVERAGE:
2652 	case GL_SCISSOR_TEST:
2653 	case GL_STENCIL_TEST:
2654 	case GL_DEPTH_TEST:
2655 	case GL_BLEND:
2656 	case GL_DITHER:
2657 	case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2658 	case GL_RASTERIZER_DISCARD:
2659 	case GL_TRANSFORM_FEEDBACK_ACTIVE:
2660 	case GL_TRANSFORM_FEEDBACK_PAUSED:
2661 		{
2662 			*type = GL_BOOL;
2663 			*numParams = 1;
2664 		}
2665 		break;
2666 	case GL_COLOR_WRITEMASK:
2667 		{
2668 			*type = GL_BOOL;
2669 			*numParams = 4;
2670 		}
2671 		break;
2672 	case GL_POLYGON_OFFSET_FACTOR:
2673 	case GL_POLYGON_OFFSET_UNITS:
2674 	case GL_SAMPLE_COVERAGE_VALUE:
2675 	case GL_DEPTH_CLEAR_VALUE:
2676 	case GL_LINE_WIDTH:
2677 		{
2678 			*type = GL_FLOAT;
2679 			*numParams = 1;
2680 		}
2681 		break;
2682 	case GL_ALIASED_LINE_WIDTH_RANGE:
2683 	case GL_ALIASED_POINT_SIZE_RANGE:
2684 	case GL_DEPTH_RANGE:
2685 		{
2686 			*type = GL_FLOAT;
2687 			*numParams = 2;
2688 		}
2689 		break;
2690 	case GL_COLOR_CLEAR_VALUE:
2691 	case GL_BLEND_COLOR:
2692 		{
2693 			*type = GL_FLOAT;
2694 			*numParams = 4;
2695 		}
2696 		break;
2697 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2698 		*type = GL_FLOAT;
2699 		*numParams = 1;
2700 		break;
2701 	default:
2702 		return false;
2703 	}
2704 
2705 	return true;
2706 }
2707 
applyScissor(int width,int height)2708 void Context::applyScissor(int width, int height)
2709 {
2710 	if(mState.scissorTestEnabled)
2711 	{
2712 		sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
2713 		scissor.clip(0, 0, width, height);
2714 
2715 		device->setScissorRect(scissor);
2716 		device->setScissorEnable(true);
2717 	}
2718 	else
2719 	{
2720 		device->setScissorEnable(false);
2721 	}
2722 }
2723 
2724 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()2725 bool Context::applyRenderTarget()
2726 {
2727 	Framebuffer *framebuffer = getDrawFramebuffer();
2728 	int width, height, samples;
2729 
2730 	if(!framebuffer || (framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE))
2731 	{
2732 		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2733 	}
2734 
2735 	for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2736 	{
2737 		if(framebuffer->getDrawBuffer(i) != GL_NONE)
2738 		{
2739 			egl::Image *renderTarget = framebuffer->getRenderTarget(i);
2740 			GLint layer = framebuffer->getColorbufferLayer(i);
2741 			device->setRenderTarget(i, renderTarget, layer);
2742 			if(renderTarget) renderTarget->release();
2743 		}
2744 		else
2745 		{
2746 			device->setRenderTarget(i, nullptr, 0);
2747 		}
2748 	}
2749 
2750 	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
2751 	GLint dLayer = framebuffer->getDepthbufferLayer();
2752 	device->setDepthBuffer(depthBuffer, dLayer);
2753 	if(depthBuffer) depthBuffer->release();
2754 
2755 	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
2756 	GLint sLayer = framebuffer->getStencilbufferLayer();
2757 	device->setStencilBuffer(stencilBuffer, sLayer);
2758 	if(stencilBuffer) stencilBuffer->release();
2759 
2760 	Viewport viewport;
2761 	float zNear = clamp01(mState.zNear);
2762 	float zFar = clamp01(mState.zFar);
2763 
2764 	viewport.x0 = mState.viewportX;
2765 	viewport.y0 = mState.viewportY;
2766 	viewport.width = mState.viewportWidth;
2767 	viewport.height = mState.viewportHeight;
2768 	viewport.minZ = zNear;
2769 	viewport.maxZ = zFar;
2770 
2771 	device->setViewport(viewport);
2772 
2773 	applyScissor(width, height);
2774 
2775 	Program *program = getCurrentProgram();
2776 
2777 	if(program)
2778 	{
2779 		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2780 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2781 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2782 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2783 	}
2784 
2785 	return true;
2786 }
2787 
2788 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)2789 void Context::applyState(GLenum drawMode)
2790 {
2791 	Framebuffer *framebuffer = getDrawFramebuffer();
2792 	bool frontFaceCCW = (mState.frontFace == GL_CCW);
2793 
2794 	if(mState.cullFaceEnabled)
2795 	{
2796 		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace), frontFaceCCW);
2797 	}
2798 	else
2799 	{
2800 		device->setCullMode(sw::CULL_NONE, frontFaceCCW);
2801 	}
2802 
2803 	if(mDepthStateDirty)
2804 	{
2805 		if(mState.depthTestEnabled)
2806 		{
2807 			device->setDepthBufferEnable(true);
2808 			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2809 		}
2810 		else
2811 		{
2812 			device->setDepthBufferEnable(false);
2813 		}
2814 
2815 		mDepthStateDirty = false;
2816 	}
2817 
2818 	if(mBlendStateDirty)
2819 	{
2820 		if(mState.blendEnabled)
2821 		{
2822 			device->setAlphaBlendEnable(true);
2823 			device->setSeparateAlphaBlendEnable(true);
2824 
2825 			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2826 
2827 			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2828 			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2829 			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2830 
2831 			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2832 			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2833 			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2834 		}
2835 		else
2836 		{
2837 			device->setAlphaBlendEnable(false);
2838 		}
2839 
2840 		mBlendStateDirty = false;
2841 	}
2842 
2843 	if(mStencilStateDirty || mFrontFaceDirty)
2844 	{
2845 		if(mState.stencilTestEnabled && framebuffer->hasStencil())
2846 		{
2847 			device->setStencilEnable(true);
2848 			device->setTwoSidedStencil(true);
2849 
2850 			// get the maximum size of the stencil ref
2851 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2852 			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2853 
2854 			if(mState.frontFace == GL_CCW)
2855 			{
2856 				device->setStencilWriteMask(mState.stencilWritemask);
2857 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2858 
2859 				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2860 				device->setStencilMask(mState.stencilMask);
2861 
2862 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2863 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2864 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2865 
2866 				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2867 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2868 
2869 				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2870 				device->setStencilMaskCCW(mState.stencilBackMask);
2871 
2872 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2873 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2874 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2875 			}
2876 			else
2877 			{
2878 				device->setStencilWriteMaskCCW(mState.stencilWritemask);
2879 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2880 
2881 				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2882 				device->setStencilMaskCCW(mState.stencilMask);
2883 
2884 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2885 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2886 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2887 
2888 				device->setStencilWriteMask(mState.stencilBackWritemask);
2889 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2890 
2891 				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2892 				device->setStencilMask(mState.stencilBackMask);
2893 
2894 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2895 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2896 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2897 			}
2898 		}
2899 		else
2900 		{
2901 			device->setStencilEnable(false);
2902 		}
2903 
2904 		mStencilStateDirty = false;
2905 		mFrontFaceDirty = false;
2906 	}
2907 
2908 	if(mMaskStateDirty)
2909 	{
2910 		for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2911 		{
2912 			device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2913 		}
2914 
2915 		device->setDepthWriteEnable(mState.depthMask);
2916 
2917 		mMaskStateDirty = false;
2918 	}
2919 
2920 	if(mPolygonOffsetStateDirty)
2921 	{
2922 		if(mState.polygonOffsetFillEnabled)
2923 		{
2924 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2925 			if(depthbuffer)
2926 			{
2927 				device->setSlopeDepthBias(mState.polygonOffsetFactor);
2928 				float depthBias = ldexp(mState.polygonOffsetUnits, -23);   // We use 32-bit floating-point for all depth formats, with 23 mantissa bits.
2929 				device->setDepthBias(depthBias);
2930 			}
2931 		}
2932 		else
2933 		{
2934 			device->setSlopeDepthBias(0);
2935 			device->setDepthBias(0);
2936 		}
2937 
2938 		mPolygonOffsetStateDirty = false;
2939 	}
2940 
2941 	if(mSampleStateDirty)
2942 	{
2943 		if(mState.sampleAlphaToCoverageEnabled)
2944 		{
2945 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
2946 		}
2947 		else
2948 		{
2949 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
2950 		}
2951 
2952 		if(mState.sampleCoverageEnabled)
2953 		{
2954 			unsigned int mask = 0;
2955 			if(mState.sampleCoverageValue != 0)
2956 			{
2957 				int width, height, samples;
2958 				framebuffer->completeness(width, height, samples);
2959 
2960 				float threshold = 0.5f;
2961 
2962 				for(int i = 0; i < samples; i++)
2963 				{
2964 					mask <<= 1;
2965 
2966 					if((i + 1) * mState.sampleCoverageValue >= threshold)
2967 					{
2968 						threshold += 1.0f;
2969 						mask |= 1;
2970 					}
2971 				}
2972 			}
2973 
2974 			if(mState.sampleCoverageInvert)
2975 			{
2976 				mask = ~mask;
2977 			}
2978 
2979 			device->setMultiSampleMask(mask);
2980 		}
2981 		else
2982 		{
2983 			device->setMultiSampleMask(0xFFFFFFFF);
2984 		}
2985 
2986 		mSampleStateDirty = false;
2987 	}
2988 
2989 	if(mDitherStateDirty)
2990 	{
2991 	//	UNIMPLEMENTED();   // FIXME
2992 
2993 		mDitherStateDirty = false;
2994 	}
2995 
2996 	device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
2997 }
2998 
applyVertexBuffer(GLint base,GLint first,GLsizei count,GLsizei instanceId)2999 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
3000 {
3001 	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
3002 
3003 	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
3004 	if(err != GL_NO_ERROR)
3005 	{
3006 		return err;
3007 	}
3008 
3009 	Program *program = getCurrentProgram();
3010 
3011 	device->resetInputStreams(false);
3012 
3013 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3014 	{
3015 		if(program->getAttributeStream(i) == -1)
3016 		{
3017 			continue;
3018 		}
3019 
3020 		sw::Resource *resource = attributes[i].vertexBuffer;
3021 		const void *buffer = (char*)resource->data() + attributes[i].offset;
3022 
3023 		int stride = attributes[i].stride;
3024 
3025 		buffer = (char*)buffer + stride * base;
3026 
3027 		sw::Stream attribute(resource, buffer, stride);
3028 
3029 		attribute.type = attributes[i].type;
3030 		attribute.count = attributes[i].count;
3031 		attribute.normalized = attributes[i].normalized;
3032 
3033 		int stream = program->getAttributeStream(i);
3034 		device->setInputStream(stream, attribute);
3035 	}
3036 
3037 	return GL_NO_ERROR;
3038 }
3039 
3040 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLuint start,GLuint end,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)3041 GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
3042 {
3043 	GLenum err = mIndexDataManager->prepareIndexData(mode, type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo, isPrimitiveRestartFixedIndexEnabled());
3044 
3045 	if(err == GL_NO_ERROR)
3046 	{
3047 		device->setIndexBuffer(indexInfo->indexBuffer);
3048 	}
3049 
3050 	return err;
3051 }
3052 
3053 // Applies the shaders and shader constants
applyShaders()3054 void Context::applyShaders()
3055 {
3056 	Program *programObject = getCurrentProgram();
3057 	sw::VertexShader *vertexShader = programObject->getVertexShader();
3058 	sw::PixelShader *pixelShader = programObject->getPixelShader();
3059 
3060 	device->setVertexShader(vertexShader);
3061 	device->setPixelShader(pixelShader);
3062 
3063 	if(programObject->getSerial() != mAppliedProgramSerial)
3064 	{
3065 		programObject->dirtyAllUniforms();
3066 		mAppliedProgramSerial = programObject->getSerial();
3067 	}
3068 
3069 	programObject->applyTransformFeedback(device, getTransformFeedback());
3070 	programObject->applyUniformBuffers(device, mState.uniformBuffers);
3071 	programObject->applyUniforms(device);
3072 }
3073 
applyTextures()3074 void Context::applyTextures()
3075 {
3076 	applyTextures(sw::SAMPLER_PIXEL);
3077 	applyTextures(sw::SAMPLER_VERTEX);
3078 }
3079 
applyTextures(sw::SamplerType samplerType)3080 void Context::applyTextures(sw::SamplerType samplerType)
3081 {
3082 	Program *programObject = getCurrentProgram();
3083 
3084 	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
3085 
3086 	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
3087 	{
3088 		int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
3089 
3090 		if(textureUnit != -1)
3091 		{
3092 			TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
3093 
3094 			Texture *texture = getSamplerTexture(textureUnit, textureType);
3095 			Sampler *samplerObject = mState.sampler[textureUnit];
3096 
3097 			if(texture->isSamplerComplete(samplerObject))
3098 			{
3099 				GLenum wrapS, wrapT, wrapR, minFilter, magFilter, compFunc, compMode;
3100 				GLfloat minLOD, maxLOD, maxAnisotropy;
3101 
3102 				if(samplerObject)
3103 				{
3104 					wrapS = samplerObject->getWrapS();
3105 					wrapT = samplerObject->getWrapT();
3106 					wrapR = samplerObject->getWrapR();
3107 					minFilter = samplerObject->getMinFilter();
3108 					magFilter = samplerObject->getMagFilter();
3109 					minLOD = samplerObject->getMinLod();
3110 					maxLOD = samplerObject->getMaxLod();
3111 					compFunc = samplerObject->getCompareFunc();
3112 					compMode = samplerObject->getCompareMode();
3113 					maxAnisotropy = samplerObject->getMaxAnisotropy();
3114 				}
3115 				else
3116 				{
3117 					wrapS = texture->getWrapS();
3118 					wrapT = texture->getWrapT();
3119 					wrapR = texture->getWrapR();
3120 					minFilter = texture->getMinFilter();
3121 					magFilter = texture->getMagFilter();
3122 					minLOD = texture->getMinLOD();
3123 					maxLOD = texture->getMaxLOD();
3124 					compFunc = texture->getCompareFunc();
3125 					compMode = texture->getCompareMode();
3126 					maxAnisotropy = texture->getMaxAnisotropy();
3127 				}
3128 
3129 				GLint baseLevel = texture->getBaseLevel();
3130 				GLint maxLevel = texture->getMaxLevel();
3131 				GLenum swizzleR = texture->getSwizzleR();
3132 				GLenum swizzleG = texture->getSwizzleG();
3133 				GLenum swizzleB = texture->getSwizzleB();
3134 				GLenum swizzleA = texture->getSwizzleA();
3135 
3136 				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
3137 				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
3138 				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
3139 				device->setCompareFunc(samplerType, samplerIndex, es2sw::ConvertCompareFunc(compFunc, compMode));
3140 				device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
3141 				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
3142 				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
3143 				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
3144 				device->setMinLod(samplerType, samplerIndex, minLOD);
3145 				device->setMaxLod(samplerType, samplerIndex, maxLOD);
3146 				device->setBaseLevel(samplerType, samplerIndex, baseLevel);
3147 				device->setMaxLevel(samplerType, samplerIndex, maxLevel);
3148 				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
3149 				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
3150 				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
3151 				device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
3152 				device->setSyncRequired(samplerType, samplerIndex, texture->requiresSync());
3153 
3154 				applyTexture(samplerType, samplerIndex, texture);
3155 			}
3156 			else
3157 			{
3158 				applyTexture(samplerType, samplerIndex, nullptr);
3159 			}
3160 		}
3161 		else
3162 		{
3163 			applyTexture(samplerType, samplerIndex, nullptr);
3164 		}
3165 	}
3166 }
3167 
applyTexture(sw::SamplerType type,int index,Texture * baseTexture)3168 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
3169 {
3170 	Program *program = getCurrentProgram();
3171 	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
3172 	bool textureUsed = false;
3173 
3174 	if(type == sw::SAMPLER_PIXEL)
3175 	{
3176 		textureUsed = program->getPixelShader()->usesSampler(index);
3177 	}
3178 	else if(type == sw::SAMPLER_VERTEX)
3179 	{
3180 		textureUsed = program->getVertexShader()->usesSampler(index);
3181 	}
3182 	else UNREACHABLE(type);
3183 
3184 	sw::Resource *resource = nullptr;
3185 
3186 	if(baseTexture && textureUsed)
3187 	{
3188 		resource = baseTexture->getResource();
3189 	}
3190 
3191 	device->setTextureResource(sampler, resource);
3192 
3193 	if(baseTexture && textureUsed)
3194 	{
3195 		int baseLevel = baseTexture->getBaseLevel();
3196 		int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
3197 		GLenum target = baseTexture->getTarget();
3198 
3199 		switch(target)
3200 		{
3201 		case GL_TEXTURE_2D:
3202 		case GL_TEXTURE_EXTERNAL_OES:
3203 		case GL_TEXTURE_RECTANGLE_ARB:
3204 			{
3205 				Texture2D *texture = static_cast<Texture2D*>(baseTexture);
3206 
3207 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3208 				{
3209 					int surfaceLevel = mipmapLevel + baseLevel;
3210 
3211 					if(surfaceLevel > maxLevel)
3212 					{
3213 						surfaceLevel = maxLevel;
3214 					}
3215 
3216 					egl::Image *surface = texture->getImage(surfaceLevel);
3217 					device->setTextureLevel(sampler, 0, mipmapLevel, surface,
3218 					                        (target == GL_TEXTURE_RECTANGLE_ARB) ? sw::TEXTURE_RECTANGLE : sw::TEXTURE_2D);
3219 				}
3220 			}
3221 			break;
3222 		case GL_TEXTURE_3D:
3223 			{
3224 				Texture3D *texture = static_cast<Texture3D*>(baseTexture);
3225 
3226 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3227 				{
3228 					int surfaceLevel = mipmapLevel + baseLevel;
3229 
3230 					if(surfaceLevel > maxLevel)
3231 					{
3232 						surfaceLevel = maxLevel;
3233 					}
3234 
3235 					egl::Image *surface = texture->getImage(surfaceLevel);
3236 					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
3237 				}
3238 			}
3239 			break;
3240 		case GL_TEXTURE_2D_ARRAY:
3241 			{
3242 				Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
3243 
3244 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3245 				{
3246 					int surfaceLevel = mipmapLevel + baseLevel;
3247 
3248 					if(surfaceLevel > maxLevel)
3249 					{
3250 						surfaceLevel = maxLevel;
3251 					}
3252 
3253 					egl::Image *surface = texture->getImage(surfaceLevel);
3254 					device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
3255 				}
3256 			}
3257 			break;
3258 		case GL_TEXTURE_CUBE_MAP:
3259 			{
3260 				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
3261 
3262 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3263 				{
3264 					cubeTexture->updateBorders(mipmapLevel);
3265 
3266 					for(int face = 0; face < 6; face++)
3267 					{
3268 						int surfaceLevel = mipmapLevel + baseLevel;
3269 
3270 						if(surfaceLevel > maxLevel)
3271 						{
3272 							surfaceLevel = maxLevel;
3273 						}
3274 
3275 						egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
3276 						device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
3277 					}
3278 				}
3279 			}
3280 			break;
3281 		default:
3282 			UNIMPLEMENTED();
3283 			break;
3284 		}
3285 	}
3286 	else
3287 	{
3288 		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
3289 	}
3290 }
3291 
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)3292 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
3293 {
3294 	Framebuffer *framebuffer = getReadFramebuffer();
3295 	int framebufferWidth, framebufferHeight, framebufferSamples;
3296 
3297 	if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE))
3298 	{
3299 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3300 	}
3301 
3302 	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
3303 	{
3304 		return error(GL_INVALID_OPERATION);
3305 	}
3306 
3307 	if(!ValidateReadPixelsFormatType(framebuffer, format, type))
3308 	{
3309 		return;
3310 	}
3311 
3312 	GLsizei outputWidth = (mState.packParameters.rowLength > 0) ? mState.packParameters.rowLength : width;
3313 	GLsizei outputPitch = gl::ComputePitch(outputWidth, format, type, mState.packParameters.alignment);
3314 	GLsizei outputHeight = (mState.packParameters.imageHeight == 0) ? height : mState.packParameters.imageHeight;
3315 	pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
3316 	pixels = ((char*)pixels) + gl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packParameters);
3317 
3318 	// Sized query sanity check
3319 	if(bufSize)
3320 	{
3321 		int requiredSize = outputPitch * height;
3322 		if(requiredSize > *bufSize)
3323 		{
3324 			return error(GL_INVALID_OPERATION);
3325 		}
3326 	}
3327 
3328 	egl::Image *renderTarget = nullptr;
3329 	switch(format)
3330 	{
3331 	case GL_DEPTH_COMPONENT:     // GL_NV_read_depth
3332 	case GL_DEPTH_STENCIL_OES:   // GL_NV_read_depth_stencil
3333 		renderTarget = framebuffer->getDepthBuffer();
3334 		break;
3335 	case GL_STENCIL_INDEX_OES:   // GL_NV_read_stencil
3336 		renderTarget = framebuffer->getStencilBuffer();
3337 		break;
3338 	default:
3339 		renderTarget = framebuffer->getReadRenderTarget();
3340 		break;
3341 	}
3342 
3343 	if(!renderTarget)
3344 	{
3345 		return error(GL_INVALID_OPERATION);
3346 	}
3347 
3348 	sw::SliceRectF srcRect((float)x, (float)y, (float)(x + width), (float)(y + height), 0);
3349 	sw::SliceRect dstRect(0, 0, width, height, 0);
3350 	srcRect.clip(0.0f, 0.0f, (float)renderTarget->getWidth(), (float)renderTarget->getHeight());
3351 
3352 	if(format != GL_DEPTH_STENCIL_OES)   // The blitter only handles reading either depth or stencil.
3353 	{
3354 		sw::Surface *externalSurface = sw::Surface::create(width, height, 1, es2::ConvertReadFormatType(format, type), pixels, outputPitch, outputPitch  *  outputHeight);
3355 		device->blit(renderTarget, srcRect, externalSurface, dstRect, false, false, false);
3356 		externalSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3357 		externalSurface->unlockExternal();
3358 		delete externalSurface;
3359 	}
3360 	else   // format == GL_DEPTH_STENCIL_OES
3361 	{
3362 		ASSERT(renderTarget->getInternalFormat() == sw::FORMAT_D32F_LOCKABLE);
3363 		float *depth = (float*)renderTarget->lockInternal((int)srcRect.x0, (int)srcRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3364 		uint8_t *stencil = (uint8_t*)renderTarget->lockStencil((int)srcRect.x0, (int)srcRect.y0, 0, sw::PUBLIC);
3365 
3366 		switch(type)
3367 		{
3368 		case GL_UNSIGNED_INT_24_8_OES:
3369 			{
3370 				uint32_t *output = (uint32_t*)pixels;
3371 
3372 				for(int y = 0; y < height; y++)
3373 				{
3374 					for(int x = 0; x < width; x++)
3375 					{
3376 						output[x] = ((uint32_t)roundf(depth[x] * 0xFFFFFF00) & 0xFFFFFF00) | stencil[x];
3377 					}
3378 
3379 					depth += renderTarget->getInternalPitchP();
3380 					stencil += renderTarget->getStencilPitchB();
3381 					(uint8_t*&)output += outputPitch;
3382 				}
3383 			}
3384 			break;
3385 		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
3386 			{
3387 				struct D32FS8 { float depth32f; unsigned int stencil24_8; };
3388 				D32FS8 *output = (D32FS8*)pixels;
3389 
3390 				for(int y = 0; y < height; y++)
3391 				{
3392 					for(int x = 0; x < width; x++)
3393 					{
3394 						output[x].depth32f = depth[x];
3395 						output[x].stencil24_8 = stencil[x];
3396 					}
3397 
3398 					depth += renderTarget->getInternalPitchP();
3399 					stencil += renderTarget->getStencilPitchB();
3400 					(uint8_t*&)output += outputPitch;
3401 				}
3402 			}
3403 			break;
3404 		default: UNREACHABLE(type);
3405 		}
3406 
3407 		renderTarget->unlockInternal();
3408 		renderTarget->unlockStencil();
3409 	}
3410 
3411 	renderTarget->release();
3412 }
3413 
clear(GLbitfield mask)3414 void Context::clear(GLbitfield mask)
3415 {
3416 	if(mState.rasterizerDiscardEnabled)
3417 	{
3418 		return;
3419 	}
3420 
3421 	Framebuffer *framebuffer = getDrawFramebuffer();
3422 
3423 	if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3424 	{
3425 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3426 	}
3427 
3428 	if(!applyRenderTarget())
3429 	{
3430 		return;
3431 	}
3432 
3433 	if(mask & GL_COLOR_BUFFER_BIT)
3434 	{
3435 		unsigned int rgbaMask = getColorMask();
3436 
3437 		if(rgbaMask != 0)
3438 		{
3439 			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
3440 		}
3441 	}
3442 
3443 	if(mask & GL_DEPTH_BUFFER_BIT)
3444 	{
3445 		if(mState.depthMask != 0)
3446 		{
3447 			float depth = clamp01(mState.depthClearValue);
3448 			device->clearDepth(depth);
3449 		}
3450 	}
3451 
3452 	if(mask & GL_STENCIL_BUFFER_BIT)
3453 	{
3454 		if(mState.stencilWritemask != 0)
3455 		{
3456 			int stencil = mState.stencilClearValue & 0x000000FF;
3457 			device->clearStencil(stencil, mState.stencilWritemask);
3458 		}
3459 	}
3460 }
3461 
clearColorBuffer(GLint drawbuffer,void * value,sw::Format format)3462 void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
3463 {
3464 	unsigned int rgbaMask = getColorMask();
3465 	if(rgbaMask && !mState.rasterizerDiscardEnabled)
3466 	{
3467 		Framebuffer *framebuffer = getDrawFramebuffer();
3468 		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3469 		{
3470 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3471 		}
3472 		egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
3473 
3474 		if(colorbuffer)
3475 		{
3476 			sw::Rect clearRect = colorbuffer->getRect();
3477 
3478 			if(mState.scissorTestEnabled)
3479 			{
3480 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3481 			}
3482 
3483 			device->clear(value, format, colorbuffer, clearRect, rgbaMask);
3484 
3485 			colorbuffer->release();
3486 		}
3487 	}
3488 }
3489 
clearColorBuffer(GLint drawbuffer,const GLint * value)3490 void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
3491 {
3492 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
3493 }
3494 
clearColorBuffer(GLint drawbuffer,const GLuint * value)3495 void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
3496 {
3497 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
3498 }
3499 
clearColorBuffer(GLint drawbuffer,const GLfloat * value)3500 void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
3501 {
3502 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
3503 }
3504 
clearDepthBuffer(const GLfloat value)3505 void Context::clearDepthBuffer(const GLfloat value)
3506 {
3507 	if(mState.depthMask && !mState.rasterizerDiscardEnabled)
3508 	{
3509 		Framebuffer *framebuffer = getDrawFramebuffer();
3510 		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3511 		{
3512 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3513 		}
3514 		egl::Image *depthbuffer = framebuffer->getDepthBuffer();
3515 
3516 		if(depthbuffer)
3517 		{
3518 			float depth = clamp01(value);
3519 			sw::Rect clearRect = depthbuffer->getRect();
3520 
3521 			if(mState.scissorTestEnabled)
3522 			{
3523 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3524 			}
3525 
3526 			depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3527 
3528 			depthbuffer->release();
3529 		}
3530 	}
3531 }
3532 
clearStencilBuffer(const GLint value)3533 void Context::clearStencilBuffer(const GLint value)
3534 {
3535 	if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
3536 	{
3537 		Framebuffer *framebuffer = getDrawFramebuffer();
3538 		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3539 		{
3540 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3541 		}
3542 		egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
3543 
3544 		if(stencilbuffer)
3545 		{
3546 			unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
3547 			sw::Rect clearRect = stencilbuffer->getRect();
3548 
3549 			if(mState.scissorTestEnabled)
3550 			{
3551 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3552 			}
3553 
3554 			stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3555 
3556 			stencilbuffer->release();
3557 		}
3558 	}
3559 }
3560 
drawArrays(GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)3561 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
3562 {
3563 	if(!applyRenderTarget())
3564 	{
3565 		return;
3566 	}
3567 
3568 	if(mState.currentProgram == 0)
3569 	{
3570 		return;   // Nothing to process.
3571 	}
3572 
3573 	sw::DrawType primitiveType;
3574 	int primitiveCount;
3575 	int verticesPerPrimitive;
3576 
3577 	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
3578 	{
3579 		return error(GL_INVALID_ENUM);
3580 	}
3581 
3582 	applyState(mode);
3583 
3584 	for(int i = 0; i < instanceCount; ++i)
3585 	{
3586 		device->setInstanceID(i);
3587 
3588 		GLenum err = applyVertexBuffer(0, first, count, i);
3589 		if(err != GL_NO_ERROR)
3590 		{
3591 			return error(err);
3592 		}
3593 
3594 		applyShaders();
3595 		applyTextures();
3596 
3597 		if(!getCurrentProgram()->validateSamplers(false))
3598 		{
3599 			return error(GL_INVALID_OPERATION);
3600 		}
3601 
3602 		if(primitiveCount <= 0)
3603 		{
3604 			return;
3605 		}
3606 
3607 		TransformFeedback* transformFeedback = getTransformFeedback();
3608 		if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3609 		{
3610 			device->drawPrimitive(primitiveType, primitiveCount);
3611 		}
3612 		if(transformFeedback)
3613 		{
3614 			transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
3615 		}
3616 	}
3617 }
3618 
drawElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices,GLsizei instanceCount)3619 void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
3620 {
3621 	if(!applyRenderTarget())
3622 	{
3623 		return;
3624 	}
3625 
3626 	if(mState.currentProgram == 0)
3627 	{
3628 		return;   // Nothing to process.
3629 	}
3630 
3631 	if(count == 0)
3632 	{
3633 		return;
3634 	}
3635 
3636 	if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
3637 	{
3638 		return error(GL_INVALID_OPERATION);
3639 	}
3640 
3641 	GLenum internalMode = mode;
3642 	if(isPrimitiveRestartFixedIndexEnabled())
3643 	{
3644 		switch(mode)
3645 		{
3646 		case GL_TRIANGLE_FAN:
3647 		case GL_TRIANGLE_STRIP:
3648 			internalMode = GL_TRIANGLES;
3649 			break;
3650 		case GL_LINE_LOOP:
3651 		case GL_LINE_STRIP:
3652 			internalMode = GL_LINES;
3653 			break;
3654 		default:
3655 			break;
3656 		}
3657 	}
3658 
3659 	sw::DrawType primitiveType;
3660 	int primitiveCount;
3661 	int verticesPerPrimitive;
3662 
3663 	if(!es2sw::ConvertPrimitiveType(internalMode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
3664 	{
3665 		return error(GL_INVALID_ENUM);
3666 	}
3667 
3668 	TranslatedIndexData indexInfo(primitiveCount);
3669 	GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
3670 	if(err != GL_NO_ERROR)
3671 	{
3672 		return error(err);
3673 	}
3674 
3675 	applyState(internalMode);
3676 
3677 	for(int i = 0; i < instanceCount; ++i)
3678 	{
3679 		device->setInstanceID(i);
3680 
3681 		GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
3682 		err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
3683 		if(err != GL_NO_ERROR)
3684 		{
3685 			return error(err);
3686 		}
3687 
3688 		applyShaders();
3689 		applyTextures();
3690 
3691 		if(!getCurrentProgram()->validateSamplers(false))
3692 		{
3693 			return error(GL_INVALID_OPERATION);
3694 		}
3695 
3696 		if(primitiveCount <= 0)
3697 		{
3698 			return;
3699 		}
3700 
3701 		TransformFeedback* transformFeedback = getTransformFeedback();
3702 		if(!cullSkipsDraw(internalMode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3703 		{
3704 			device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, indexInfo.primitiveCount);
3705 		}
3706 		if(transformFeedback)
3707 		{
3708 			transformFeedback->addVertexOffset(indexInfo.primitiveCount * verticesPerPrimitive);
3709 		}
3710 	}
3711 }
3712 
blit(sw::Surface * source,const sw::SliceRect & sRect,sw::Surface * dest,const sw::SliceRect & dRect)3713 void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
3714 {
3715 	sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
3716 	device->blit(source, sRectF, dest, dRect, false);
3717 }
3718 
finish()3719 void Context::finish()
3720 {
3721 	device->finish();
3722 }
3723 
flush()3724 void Context::flush()
3725 {
3726 	// We don't queue anything without processing it as fast as possible
3727 }
3728 
recordInvalidEnum()3729 void Context::recordInvalidEnum()
3730 {
3731 	mInvalidEnum = true;
3732 }
3733 
recordInvalidValue()3734 void Context::recordInvalidValue()
3735 {
3736 	mInvalidValue = true;
3737 }
3738 
recordInvalidOperation()3739 void Context::recordInvalidOperation()
3740 {
3741 	mInvalidOperation = true;
3742 }
3743 
recordOutOfMemory()3744 void Context::recordOutOfMemory()
3745 {
3746 	mOutOfMemory = true;
3747 }
3748 
recordInvalidFramebufferOperation()3749 void Context::recordInvalidFramebufferOperation()
3750 {
3751 	mInvalidFramebufferOperation = true;
3752 }
3753 
3754 // Get one of the recorded errors and clear its flag, if any.
3755 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()3756 GLenum Context::getError()
3757 {
3758 	if(mInvalidEnum)
3759 	{
3760 		mInvalidEnum = false;
3761 
3762 		return GL_INVALID_ENUM;
3763 	}
3764 
3765 	if(mInvalidValue)
3766 	{
3767 		mInvalidValue = false;
3768 
3769 		return GL_INVALID_VALUE;
3770 	}
3771 
3772 	if(mInvalidOperation)
3773 	{
3774 		mInvalidOperation = false;
3775 
3776 		return GL_INVALID_OPERATION;
3777 	}
3778 
3779 	if(mOutOfMemory)
3780 	{
3781 		mOutOfMemory = false;
3782 
3783 		return GL_OUT_OF_MEMORY;
3784 	}
3785 
3786 	if(mInvalidFramebufferOperation)
3787 	{
3788 		mInvalidFramebufferOperation = false;
3789 
3790 		return GL_INVALID_FRAMEBUFFER_OPERATION;
3791 	}
3792 
3793 	return GL_NO_ERROR;
3794 }
3795 
getSupportedMultisampleCount(int requested)3796 int Context::getSupportedMultisampleCount(int requested)
3797 {
3798 	int supported = 0;
3799 
3800 	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
3801 	{
3802 		if(supported >= requested)
3803 		{
3804 			return supported;
3805 		}
3806 
3807 		supported = multisampleCount[i];
3808 	}
3809 
3810 	return supported;
3811 }
3812 
detachBuffer(GLuint buffer)3813 void Context::detachBuffer(GLuint buffer)
3814 {
3815 	// [OpenGL ES 2.0.24] section 2.9 page 22:
3816 	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
3817 	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
3818 
3819 	if(mState.copyReadBuffer.name() == buffer)
3820 	{
3821 		mState.copyReadBuffer = nullptr;
3822 	}
3823 
3824 	if(mState.copyWriteBuffer.name() == buffer)
3825 	{
3826 		mState.copyWriteBuffer = nullptr;
3827 	}
3828 
3829 	if(mState.pixelPackBuffer.name() == buffer)
3830 	{
3831 		mState.pixelPackBuffer = nullptr;
3832 	}
3833 
3834 	if(mState.pixelUnpackBuffer.name() == buffer)
3835 	{
3836 		mState.pixelUnpackBuffer = nullptr;
3837 	}
3838 
3839 	if(mState.genericUniformBuffer.name() == buffer)
3840 	{
3841 		mState.genericUniformBuffer = nullptr;
3842 	}
3843 
3844 	if(getArrayBufferName() == buffer)
3845 	{
3846 		mState.arrayBuffer = nullptr;
3847 	}
3848 
3849 	// Only detach from the current transform feedback
3850 	TransformFeedback* currentTransformFeedback = getTransformFeedback();
3851 	if(currentTransformFeedback)
3852 	{
3853 		currentTransformFeedback->detachBuffer(buffer);
3854 	}
3855 
3856 	// Only detach from the current vertex array
3857 	VertexArray* currentVertexArray = getCurrentVertexArray();
3858 	if(currentVertexArray)
3859 	{
3860 		currentVertexArray->detachBuffer(buffer);
3861 	}
3862 
3863 	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3864 	{
3865 		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3866 		{
3867 			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
3868 		}
3869 	}
3870 }
3871 
detachTexture(GLuint texture)3872 void Context::detachTexture(GLuint texture)
3873 {
3874 	// [OpenGL ES 2.0.24] section 3.8 page 84:
3875 	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3876 	// rebound to texture object zero
3877 
3878 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3879 	{
3880 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3881 		{
3882 			if(mState.samplerTexture[type][sampler].name() == texture)
3883 			{
3884 				mState.samplerTexture[type][sampler] = nullptr;
3885 			}
3886 		}
3887 	}
3888 
3889 	// [OpenGL ES 2.0.24] section 4.4 page 112:
3890 	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3891 	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3892 	// image was attached in the currently bound framebuffer.
3893 
3894 	Framebuffer *readFramebuffer = getReadFramebuffer();
3895 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
3896 
3897 	if(readFramebuffer)
3898 	{
3899 		readFramebuffer->detachTexture(texture);
3900 	}
3901 
3902 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3903 	{
3904 		drawFramebuffer->detachTexture(texture);
3905 	}
3906 }
3907 
detachFramebuffer(GLuint framebuffer)3908 void Context::detachFramebuffer(GLuint framebuffer)
3909 {
3910 	// [OpenGL ES 2.0.24] section 4.4 page 107:
3911 	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3912 	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3913 
3914 	if(mState.readFramebuffer == framebuffer)
3915 	{
3916 		bindReadFramebuffer(0);
3917 	}
3918 
3919 	if(mState.drawFramebuffer == framebuffer)
3920 	{
3921 		bindDrawFramebuffer(0);
3922 	}
3923 }
3924 
detachRenderbuffer(GLuint renderbuffer)3925 void Context::detachRenderbuffer(GLuint renderbuffer)
3926 {
3927 	// [OpenGL ES 2.0.24] section 4.4 page 109:
3928 	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3929 	// had been executed with the target RENDERBUFFER and name of zero.
3930 
3931 	if(mState.renderbuffer.name() == renderbuffer)
3932 	{
3933 		bindRenderbuffer(0);
3934 	}
3935 
3936 	// [OpenGL ES 2.0.24] section 4.4 page 111:
3937 	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3938 	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3939 	// point to which this image was attached in the currently bound framebuffer.
3940 
3941 	Framebuffer *readFramebuffer = getReadFramebuffer();
3942 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
3943 
3944 	if(readFramebuffer)
3945 	{
3946 		readFramebuffer->detachRenderbuffer(renderbuffer);
3947 	}
3948 
3949 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3950 	{
3951 		drawFramebuffer->detachRenderbuffer(renderbuffer);
3952 	}
3953 }
3954 
detachSampler(GLuint sampler)3955 void Context::detachSampler(GLuint sampler)
3956 {
3957 	// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3958 	// If a sampler object that is currently bound to one or more texture units is
3959 	// deleted, it is as though BindSampler is called once for each texture unit to
3960 	// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3961 	for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
3962 	{
3963 		gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
3964 		if(samplerBinding.name() == sampler)
3965 		{
3966 			samplerBinding = nullptr;
3967 		}
3968 	}
3969 }
3970 
cullSkipsDraw(GLenum drawMode)3971 bool Context::cullSkipsDraw(GLenum drawMode)
3972 {
3973 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3974 }
3975 
isTriangleMode(GLenum drawMode)3976 bool Context::isTriangleMode(GLenum drawMode)
3977 {
3978 	switch(drawMode)
3979 	{
3980 	case GL_TRIANGLES:
3981 	case GL_TRIANGLE_FAN:
3982 	case GL_TRIANGLE_STRIP:
3983 		return true;
3984 	case GL_POINTS:
3985 	case GL_LINES:
3986 	case GL_LINE_LOOP:
3987 	case GL_LINE_STRIP:
3988 		return false;
3989 	default: UNREACHABLE(drawMode);
3990 	}
3991 
3992 	return false;
3993 }
3994 
setVertexAttrib(GLuint index,const GLfloat * values)3995 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
3996 {
3997 	ASSERT(index < MAX_VERTEX_ATTRIBS);
3998 
3999 	mState.vertexAttribute[index].setCurrentValue(values);
4000 
4001 	mVertexDataManager->dirtyCurrentValue(index);
4002 }
4003 
setVertexAttrib(GLuint index,const GLint * values)4004 void Context::setVertexAttrib(GLuint index, const GLint *values)
4005 {
4006 	ASSERT(index < MAX_VERTEX_ATTRIBS);
4007 
4008 	mState.vertexAttribute[index].setCurrentValue(values);
4009 
4010 	mVertexDataManager->dirtyCurrentValue(index);
4011 }
4012 
setVertexAttrib(GLuint index,const GLuint * values)4013 void Context::setVertexAttrib(GLuint index, const GLuint *values)
4014 {
4015 	ASSERT(index < MAX_VERTEX_ATTRIBS);
4016 
4017 	mState.vertexAttribute[index].setCurrentValue(values);
4018 
4019 	mVertexDataManager->dirtyCurrentValue(index);
4020 }
4021 
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,bool filter,bool allowPartialDepthStencilBlit)4022 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4023                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4024                               GLbitfield mask, bool filter, bool allowPartialDepthStencilBlit)
4025 {
4026 	Framebuffer *readFramebuffer = getReadFramebuffer();
4027 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
4028 
4029 	int readBufferWidth, readBufferHeight, readBufferSamples;
4030 	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
4031 
4032 	if(!readFramebuffer || (readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE) ||
4033 	   !drawFramebuffer || (drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE))
4034 	{
4035 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
4036 	}
4037 
4038 	if(drawBufferSamples > 1)
4039 	{
4040 		return error(GL_INVALID_OPERATION);
4041 	}
4042 
4043 	sw::SliceRect sourceRect;
4044 	sw::SliceRect destRect;
4045 	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
4046 	bool flipY = (srcY0 < srcY1) ^ (dstY0 < dstY1);
4047 
4048 	if(srcX0 < srcX1)
4049 	{
4050 		sourceRect.x0 = srcX0;
4051 		sourceRect.x1 = srcX1;
4052 	}
4053 	else
4054 	{
4055 		sourceRect.x0 = srcX1;
4056 		sourceRect.x1 = srcX0;
4057 	}
4058 
4059 	if(dstX0 < dstX1)
4060 	{
4061 		destRect.x0 = dstX0;
4062 		destRect.x1 = dstX1;
4063 	}
4064 	else
4065 	{
4066 		destRect.x0 = dstX1;
4067 		destRect.x1 = dstX0;
4068 	}
4069 
4070 	if(srcY0 < srcY1)
4071 	{
4072 		sourceRect.y0 = srcY0;
4073 		sourceRect.y1 = srcY1;
4074 	}
4075 	else
4076 	{
4077 		sourceRect.y0 = srcY1;
4078 		sourceRect.y1 = srcY0;
4079 	}
4080 
4081 	if(dstY0 < dstY1)
4082 	{
4083 		destRect.y0 = dstY0;
4084 		destRect.y1 = dstY1;
4085 	}
4086 	else
4087 	{
4088 		destRect.y0 = dstY1;
4089 		destRect.y1 = dstY0;
4090 	}
4091 
4092 	sw::RectF sourceScissoredRect(static_cast<float>(sourceRect.x0), static_cast<float>(sourceRect.y0),
4093 	                              static_cast<float>(sourceRect.x1), static_cast<float>(sourceRect.y1));
4094 	sw::Rect destScissoredRect = destRect;
4095 
4096 	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
4097 	{
4098 		sw::Rect scissorRect(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
4099 		Device::ClipDstRect(sourceScissoredRect, destScissoredRect, scissorRect, flipX, flipY);
4100 	}
4101 
4102 	sw::SliceRectF sourceTrimmedRect = sourceScissoredRect;
4103 	sw::SliceRect destTrimmedRect = destScissoredRect;
4104 
4105 	// The source & destination rectangles also may need to be trimmed if
4106 	// they fall out of the bounds of the actual draw and read surfaces.
4107 	sw::Rect sourceTrimRect(0, 0, readBufferWidth, readBufferHeight);
4108 	Device::ClipSrcRect(sourceTrimmedRect, destTrimmedRect, sourceTrimRect, flipX, flipY);
4109 
4110 	sw::Rect destTrimRect(0, 0, drawBufferWidth, drawBufferHeight);
4111 	Device::ClipDstRect(sourceTrimmedRect, destTrimmedRect, destTrimRect, flipX, flipY);
4112 
4113 	bool partialBufferCopy = false;
4114 
4115 	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
4116 	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
4117 	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
4118 	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
4119 	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
4120 	{
4121 		partialBufferCopy = true;
4122 	}
4123 
4124 	bool sameBounds = (srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1);
4125 	bool blitRenderTarget = false;
4126 	bool blitDepth = false;
4127 	bool blitStencil = false;
4128 
4129 	if(mask & GL_COLOR_BUFFER_BIT)
4130 	{
4131 		GLenum readColorbufferType = readFramebuffer->getReadBufferType();
4132 		GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
4133 		const bool validReadType = readColorbufferType == GL_TEXTURE_2D || readColorbufferType == GL_TEXTURE_RECTANGLE_ARB || Framebuffer::IsRenderbuffer(readColorbufferType);
4134 		const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || drawColorbufferType == GL_TEXTURE_RECTANGLE_ARB || Framebuffer::IsRenderbuffer(drawColorbufferType);
4135 		if(!validReadType || !validDrawType)
4136 		{
4137 			return error(GL_INVALID_OPERATION);
4138 		}
4139 
4140 		if(partialBufferCopy && readBufferSamples > 1 && !sameBounds)
4141 		{
4142 			return error(GL_INVALID_OPERATION);
4143 		}
4144 
4145 		// The GL ES 3.0.2 spec (pg 193) states that:
4146 		// 1) If the read buffer is fixed point format, the draw buffer must be as well
4147 		// 2) If the read buffer is an unsigned integer format, the draw buffer must be
4148 		// as well
4149 		// 3) If the read buffer is a signed integer format, the draw buffer must be as
4150 		// well
4151 		es2::Renderbuffer *readRenderbuffer = readFramebuffer->getReadColorbuffer();
4152 		es2::Renderbuffer *drawRenderbuffer = drawFramebuffer->getColorbuffer(0);
4153 		GLint readFormat = readRenderbuffer->getFormat();
4154 		GLint drawFormat = drawRenderbuffer->getFormat();
4155 		GLenum readComponentType = GetComponentType(readFormat, GL_COLOR_ATTACHMENT0);
4156 		GLenum drawComponentType = GetComponentType(drawFormat, GL_COLOR_ATTACHMENT0);
4157 		bool readFixedPoint = ((readComponentType == GL_UNSIGNED_NORMALIZED) ||
4158 		                       (readComponentType == GL_SIGNED_NORMALIZED));
4159 		bool drawFixedPoint = ((drawComponentType == GL_UNSIGNED_NORMALIZED) ||
4160 		                       (drawComponentType == GL_SIGNED_NORMALIZED));
4161 		bool readFixedOrFloat = (readFixedPoint || (readComponentType == GL_FLOAT));
4162 		bool drawFixedOrFloat = (drawFixedPoint || (drawComponentType == GL_FLOAT));
4163 
4164 		if(readFixedOrFloat != drawFixedOrFloat)
4165 		{
4166 			return error(GL_INVALID_OPERATION);
4167 		}
4168 
4169 		if((readComponentType == GL_UNSIGNED_INT) && (drawComponentType != GL_UNSIGNED_INT))
4170 		{
4171 			return error(GL_INVALID_OPERATION);
4172 		}
4173 
4174 		if((readComponentType == GL_INT) && (drawComponentType != GL_INT))
4175 		{
4176 			return error(GL_INVALID_OPERATION);
4177 		}
4178 
4179 		// Cannot filter integer data
4180 		if(((readComponentType == GL_UNSIGNED_INT) || (readComponentType == GL_INT)) && filter)
4181 		{
4182 			return error(GL_INVALID_OPERATION);
4183 		}
4184 
4185 		if((readRenderbuffer->getSamples() > 0) && (readFormat != drawFormat))
4186 		{
4187 			// RGBA8 and BGRA8 should be interchangeable here
4188 			if(!(((readFormat == GL_RGBA8) && (drawFormat == GL_BGRA8_EXT)) ||
4189 				 ((readFormat == GL_BGRA8_EXT) && (drawFormat == GL_RGBA8))))
4190 			{
4191 				return error(GL_INVALID_OPERATION);
4192 			}
4193 		}
4194 
4195 		blitRenderTarget = true;
4196 	}
4197 
4198 	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
4199 	{
4200 		Renderbuffer *readDSBuffer = nullptr;
4201 		Renderbuffer *drawDSBuffer = nullptr;
4202 
4203 		if(mask & GL_DEPTH_BUFFER_BIT)
4204 		{
4205 			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
4206 			{
4207 				GLenum readDepthBufferType = readFramebuffer->getDepthbufferType();
4208 				GLenum drawDepthBufferType = drawFramebuffer->getDepthbufferType();
4209 				if((readDepthBufferType != drawDepthBufferType) &&
4210 				   !(Framebuffer::IsRenderbuffer(readDepthBufferType) && Framebuffer::IsRenderbuffer(drawDepthBufferType)))
4211 				{
4212 					return error(GL_INVALID_OPERATION);
4213 				}
4214 
4215 				blitDepth = true;
4216 				readDSBuffer = readFramebuffer->getDepthbuffer();
4217 				drawDSBuffer = drawFramebuffer->getDepthbuffer();
4218 
4219 				if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4220 				{
4221 					return error(GL_INVALID_OPERATION);
4222 				}
4223 			}
4224 		}
4225 
4226 		if(mask & GL_STENCIL_BUFFER_BIT)
4227 		{
4228 			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
4229 			{
4230 				GLenum readStencilBufferType = readFramebuffer->getStencilbufferType();
4231 				GLenum drawStencilBufferType = drawFramebuffer->getStencilbufferType();
4232 				if((readStencilBufferType != drawStencilBufferType) &&
4233 				   !(Framebuffer::IsRenderbuffer(readStencilBufferType) && Framebuffer::IsRenderbuffer(drawStencilBufferType)))
4234 				{
4235 					return error(GL_INVALID_OPERATION);
4236 				}
4237 
4238 				blitStencil = true;
4239 				readDSBuffer = readFramebuffer->getStencilbuffer();
4240 				drawDSBuffer = drawFramebuffer->getStencilbuffer();
4241 
4242 				if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4243 				{
4244 					return error(GL_INVALID_OPERATION);
4245 				}
4246 			}
4247 		}
4248 
4249 		if(partialBufferCopy && !allowPartialDepthStencilBlit)
4250 		{
4251 			ERR("Only whole-buffer depth and stencil blits are supported by ANGLE_framebuffer_blit.");
4252 			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
4253 		}
4254 
4255 		// OpenGL ES 3.0.4 spec, p.199:
4256 		// ...an INVALID_OPERATION error is generated if the formats of the read
4257 		// and draw framebuffers are not identical or if the source and destination
4258 		// rectangles are not defined with the same(X0, Y 0) and (X1, Y 1) bounds.
4259 		// If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, an
4260 		// INVALID_OPERATION error is generated.
4261 		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
4262 		   ((readDSBuffer && readDSBuffer->getSamples() > 1) &&
4263 		    (!sameBounds || (drawDSBuffer->getFormat() != readDSBuffer->getFormat()))))
4264 		{
4265 			return error(GL_INVALID_OPERATION);
4266 		}
4267 	}
4268 
4269 	if(blitRenderTarget || blitDepth || blitStencil)
4270 	{
4271 		if(flipX)
4272 		{
4273 			swap(destTrimmedRect.x0, destTrimmedRect.x1);
4274 		}
4275 		if(flipY)
4276 		{
4277 			swap(destTrimmedRect.y0, destTrimmedRect.y1);
4278 		}
4279 
4280 		if(blitRenderTarget)
4281 		{
4282 			egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
4283 			egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
4284 
4285 			bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::COLOR_BUFFER);
4286 
4287 			readRenderTarget->release();
4288 			drawRenderTarget->release();
4289 
4290 			if(!success)
4291 			{
4292 				ERR("BlitFramebuffer failed.");
4293 				return;
4294 			}
4295 		}
4296 
4297 		if(blitDepth)
4298 		{
4299 			egl::Image *readRenderTarget = readFramebuffer->getDepthBuffer();
4300 			egl::Image *drawRenderTarget = drawFramebuffer->getDepthBuffer();
4301 
4302 			bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::DEPTH_BUFFER);
4303 
4304 			readRenderTarget->release();
4305 			drawRenderTarget->release();
4306 
4307 			if(!success)
4308 			{
4309 				ERR("BlitFramebuffer failed.");
4310 				return;
4311 			}
4312 		}
4313 
4314 		if(blitStencil)
4315 		{
4316 			egl::Image *readRenderTarget = readFramebuffer->getStencilBuffer();
4317 			egl::Image *drawRenderTarget = drawFramebuffer->getStencilBuffer();
4318 
4319 			bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::STENCIL_BUFFER);
4320 
4321 			readRenderTarget->release();
4322 			drawRenderTarget->release();
4323 
4324 			if(!success)
4325 			{
4326 				ERR("BlitFramebuffer failed.");
4327 				return;
4328 			}
4329 		}
4330 	}
4331 }
4332 
bindTexImage(gl::Surface * surface)4333 void Context::bindTexImage(gl::Surface *surface)
4334 {
4335 	bool isRect = (surface->getTextureTarget() == EGL_TEXTURE_RECTANGLE_ANGLE);
4336 	es2::Texture2D *textureObject = isRect ? getTexture2DRect() : getTexture2D();
4337 
4338 	if(textureObject)
4339 	{
4340 		textureObject->bindTexImage(surface);
4341 	}
4342 }
4343 
validateSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4344 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4345 {
4346 	GLenum textureTarget = GL_NONE;
4347 
4348 	switch(target)
4349 	{
4350 	case EGL_GL_TEXTURE_2D_KHR:
4351 		textureTarget = GL_TEXTURE_2D;
4352 		break;
4353 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
4354 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
4355 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
4356 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
4357 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
4358 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
4359 		textureTarget = GL_TEXTURE_CUBE_MAP;
4360 		break;
4361 	case EGL_GL_RENDERBUFFER_KHR:
4362 		break;
4363 	default:
4364 		return EGL_BAD_PARAMETER;
4365 	}
4366 
4367 	if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4368 	{
4369 		return EGL_BAD_MATCH;
4370 	}
4371 
4372 	if(textureTarget != GL_NONE)
4373 	{
4374 		es2::Texture *texture = getTexture(name);
4375 
4376 		if(!texture || texture->getTarget() != textureTarget)
4377 		{
4378 			return EGL_BAD_PARAMETER;
4379 		}
4380 
4381 		if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
4382 		{
4383 			return EGL_BAD_ACCESS;
4384 		}
4385 
4386 		if(textureLevel != 0 && !texture->isSamplerComplete(nullptr))
4387 		{
4388 			return EGL_BAD_PARAMETER;
4389 		}
4390 
4391 		if(textureLevel == 0 && !(texture->isSamplerComplete(nullptr) && texture->getTopLevel() == 0))
4392 		{
4393 			return EGL_BAD_PARAMETER;
4394 		}
4395 	}
4396 	else if(target == EGL_GL_RENDERBUFFER_KHR)
4397 	{
4398 		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4399 
4400 		if(!renderbuffer)
4401 		{
4402 			return EGL_BAD_PARAMETER;
4403 		}
4404 
4405 		if(renderbuffer->isShared())   // Already an EGLImage sibling
4406 		{
4407 			return EGL_BAD_ACCESS;
4408 		}
4409 	}
4410 	else UNREACHABLE(target);
4411 
4412 	return EGL_SUCCESS;
4413 }
4414 
createSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4415 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4416 {
4417 	GLenum textureTarget = GL_NONE;
4418 
4419 	switch(target)
4420 	{
4421 	case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
4422 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4423 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4424 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4425 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4426 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4427 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4428 	}
4429 
4430 	if(textureTarget != GL_NONE)
4431 	{
4432 		es2::Texture *texture = getTexture(name);
4433 
4434 		return texture->createSharedImage(textureTarget, textureLevel);
4435 	}
4436 	else if(target == EGL_GL_RENDERBUFFER_KHR)
4437 	{
4438 		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4439 
4440 		return renderbuffer->createSharedImage();
4441 	}
4442 	else UNREACHABLE(target);
4443 
4444 	return nullptr;
4445 }
4446 
getSharedImage(GLeglImageOES image)4447 egl::Image *Context::getSharedImage(GLeglImageOES image)
4448 {
4449 	return display->getSharedImage(image);
4450 }
4451 
getDevice()4452 Device *Context::getDevice()
4453 {
4454 	return device;
4455 }
4456 
getExtensions(GLuint index,GLuint * numExt) const4457 const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
4458 {
4459 	// Keep list sorted in following order:
4460 	// OES extensions
4461 	// EXT extensions
4462 	// Vendor extensions
4463 	static const char *extensions[] =
4464 	{
4465 		"GL_OES_compressed_ETC1_RGB8_texture",
4466 		"GL_OES_depth24",
4467 		"GL_OES_depth32",
4468 		"GL_OES_depth_texture",
4469 		"GL_OES_depth_texture_cube_map",
4470 		"GL_OES_EGL_image",
4471 		"GL_OES_EGL_image_external",
4472 		"GL_OES_EGL_image_external_essl3", // client version is always 3, so this is fine
4473 		"GL_OES_EGL_sync",
4474 		"GL_OES_element_index_uint",
4475 		"GL_OES_fbo_render_mipmap",
4476 		"GL_OES_framebuffer_object",
4477 		"GL_OES_packed_depth_stencil",
4478 		"GL_OES_rgb8_rgba8",
4479 		"GL_OES_standard_derivatives",
4480 		"GL_OES_surfaceless_context",
4481 		"GL_OES_texture_float",
4482 		"GL_OES_texture_float_linear",
4483 		"GL_OES_texture_half_float",
4484 		"GL_OES_texture_half_float_linear",
4485 		"GL_OES_texture_npot",
4486 		"GL_OES_texture_3D",
4487 		"GL_OES_vertex_array_object",
4488 		"GL_OES_vertex_half_float",
4489 		"GL_EXT_blend_minmax",
4490 		"GL_EXT_color_buffer_float",   // OpenGL ES 3.0 specific.
4491 		"GL_EXT_color_buffer_half_float",
4492 		"GL_EXT_draw_buffers",
4493 		"GL_EXT_instanced_arrays",
4494 		"GL_EXT_occlusion_query_boolean",
4495 		"GL_EXT_read_format_bgra",
4496 		"GL_EXT_texture_compression_dxt1",
4497 		"GL_EXT_texture_filter_anisotropic",
4498 		"GL_EXT_texture_format_BGRA8888",
4499 		"GL_EXT_texture_rg",
4500 #if (ASTC_SUPPORT)
4501 		"GL_KHR_texture_compression_astc_hdr",
4502 		"GL_KHR_texture_compression_astc_ldr",
4503 #endif
4504 		"GL_ARB_texture_rectangle",
4505 		"GL_ANGLE_framebuffer_blit",
4506 		"GL_ANGLE_framebuffer_multisample",
4507 		"GL_ANGLE_instanced_arrays",
4508 		"GL_ANGLE_texture_compression_dxt3",
4509 		"GL_ANGLE_texture_compression_dxt5",
4510 		"GL_APPLE_texture_format_BGRA8888",
4511 		"GL_CHROMIUM_color_buffer_float_rgba", // A subset of EXT_color_buffer_float on top of OpenGL ES 2.0
4512 		"GL_CHROMIUM_texture_filtering_hint",
4513 		"GL_NV_depth_buffer_float2",
4514 		"GL_NV_fence",
4515 		"GL_NV_framebuffer_blit",
4516 		"GL_NV_read_depth",
4517 		"GL_NV_read_depth_stencil",
4518 		"GL_NV_read_stencil",
4519 	};
4520 
4521 	GLuint numExtensions = sizeof(extensions) / sizeof(extensions[0]);
4522 
4523 	if(numExt)
4524 	{
4525 		*numExt = numExtensions;
4526 
4527 		return nullptr;
4528 	}
4529 
4530 	if(index == GL_INVALID_INDEX)
4531 	{
4532 		static std::string extensionsCat;
4533 
4534 		if(extensionsCat.empty() && (numExtensions > 0))
4535 		{
4536 			for(const char *extension : extensions)
4537 			{
4538 				extensionsCat += std::string(extension) + " ";
4539 			}
4540 		}
4541 
4542 		return (const GLubyte*)extensionsCat.c_str();
4543 	}
4544 
4545 	if(index >= numExtensions)
4546 	{
4547 		return nullptr;
4548 	}
4549 
4550 	return (const GLubyte*)extensions[index];
4551 }
4552 
4553 }
4554 
es2CreateContext(egl::Display * display,const egl::Context * shareContext,const egl::Config * config)4555 NO_SANITIZE_FUNCTION egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
4556 {
4557 	return new es2::Context(display, static_cast<const es2::Context*>(shareContext), config);
4558 }
4559