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