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