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