• Home
  • History
  • Annotate
  • 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 es1::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 "Framebuffer.h"
26 #include "Renderbuffer.h"
27 #include "Texture.h"
28 #include "VertexDataManager.h"
29 #include "IndexDataManager.h"
30 #include "libEGL/Display.h"
31 #include "libEGL/Surface.h"
32 #include "Common/Half.hpp"
33 
34 #include <EGL/eglext.h>
35 
36 using std::abs;
37 
38 namespace es1
39 {
Context(const egl::Config * config,const Context * shareContext)40 Context::Context(const egl::Config *config, const Context *shareContext)
41 	: modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
42 	  projectionStack(MAX_PROJECTION_STACK_DEPTH),
43 	  textureStack0(MAX_TEXTURE_STACK_DEPTH),
44 	  textureStack1(MAX_TEXTURE_STACK_DEPTH)
45 {
46 	sw::Context *context = new sw::Context();
47 	device = new es1::Device(context);
48 
49 	mVertexDataManager = new VertexDataManager(this);
50 	mIndexDataManager = new IndexDataManager();
51 
52 	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
53 
54 	mState.depthClearValue = 1.0f;
55 	mState.stencilClearValue = 0;
56 
57 	mState.cullFaceEnabled = false;
58 	mState.cullMode = GL_BACK;
59 	mState.frontFace = GL_CCW;
60 	mState.depthTestEnabled = false;
61 	mState.depthFunc = GL_LESS;
62 	mState.blendEnabled = false;
63 	mState.sourceBlendRGB = GL_ONE;
64 	mState.sourceBlendAlpha = GL_ONE;
65 	mState.destBlendRGB = GL_ZERO;
66 	mState.destBlendAlpha = GL_ZERO;
67 	mState.blendEquationRGB = GL_FUNC_ADD_OES;
68 	mState.blendEquationAlpha = GL_FUNC_ADD_OES;
69 	mState.stencilTestEnabled = false;
70 	mState.stencilFunc = GL_ALWAYS;
71 	mState.stencilRef = 0;
72 	mState.stencilMask = -1;
73 	mState.stencilWritemask = -1;
74 	mState.stencilFail = GL_KEEP;
75 	mState.stencilPassDepthFail = GL_KEEP;
76 	mState.stencilPassDepthPass = GL_KEEP;
77 	mState.polygonOffsetFillEnabled = false;
78 	mState.polygonOffsetFactor = 0.0f;
79 	mState.polygonOffsetUnits = 0.0f;
80 	mState.sampleAlphaToCoverageEnabled = false;
81 	mState.sampleCoverageEnabled = false;
82 	mState.sampleCoverageValue = 1.0f;
83 	mState.sampleCoverageInvert = false;
84 	mState.scissorTestEnabled = false;
85 	mState.ditherEnabled = true;
86 	mState.shadeModel = GL_SMOOTH;
87 	mState.generateMipmapHint = GL_DONT_CARE;
88 	mState.perspectiveCorrectionHint = GL_DONT_CARE;
89 	mState.fogHint = GL_DONT_CARE;
90 
91 	mState.lineWidth = 1.0f;
92 
93 	mState.viewportX = 0;
94 	mState.viewportY = 0;
95 	mState.viewportWidth = 0;
96 	mState.viewportHeight = 0;
97 	mState.zNear = 0.0f;
98 	mState.zFar = 1.0f;
99 
100 	mState.scissorX = 0;
101 	mState.scissorY = 0;
102 	mState.scissorWidth = 0;
103 	mState.scissorHeight = 0;
104 
105 	mState.colorMaskRed = true;
106 	mState.colorMaskGreen = true;
107 	mState.colorMaskBlue = true;
108 	mState.colorMaskAlpha = true;
109 	mState.depthMask = true;
110 
111 	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
112 	{
113 		mState.textureUnit[i].color = {0, 0, 0, 0};
114 		mState.textureUnit[i].environmentMode = GL_MODULATE;
115 		mState.textureUnit[i].combineRGB = GL_MODULATE;
116 		mState.textureUnit[i].combineAlpha = GL_MODULATE;
117 		mState.textureUnit[i].src0RGB = GL_TEXTURE;
118 		mState.textureUnit[i].src1RGB = GL_PREVIOUS;
119 		mState.textureUnit[i].src2RGB = GL_CONSTANT;
120 		mState.textureUnit[i].src0Alpha = GL_TEXTURE;
121 		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;
122 		mState.textureUnit[i].src2Alpha = GL_CONSTANT;
123 		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;
124 		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;
125 		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;
126 		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;
127 		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;
128 		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;
129 	}
130 
131 	if(shareContext)
132 	{
133 		mResourceManager = shareContext->mResourceManager;
134 		mResourceManager->addRef();
135 	}
136 	else
137 	{
138 		mResourceManager = new ResourceManager();
139 	}
140 
141 	// [OpenGL ES 2.0.24] section 3.7 page 83:
142 	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
143 	// and cube map texture state vectors respectively associated with them.
144 	// In order that access to these initial textures not be lost, they are treated as texture
145 	// objects all of whose names are 0.
146 
147 	mTexture2DZero = new Texture2D(0);
148 	mTextureExternalZero = new TextureExternal(0);
149 
150 	mState.activeSampler = 0;
151 	bindArrayBuffer(0);
152 	bindElementArrayBuffer(0);
153 	bindTexture2D(0);
154 	bindFramebuffer(0);
155 	bindRenderbuffer(0);
156 
157 	mState.packAlignment = 4;
158 	mState.unpackAlignment = 4;
159 
160 	mInvalidEnum = false;
161 	mInvalidValue = false;
162 	mInvalidOperation = false;
163 	mOutOfMemory = false;
164 	mInvalidFramebufferOperation = false;
165 	mMatrixStackOverflow = false;
166 	mMatrixStackUnderflow = false;
167 
168 	lightingEnabled = false;
169 
170 	for(int i = 0; i < MAX_LIGHTS; i++)
171 	{
172 		light[i].enabled = false;
173 		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
174 		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
175 		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
176 		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
177 		light[i].direction = {0.0f, 0.0f, -1.0f};
178 		light[i].attenuation = {1.0f, 0.0f, 0.0f};
179 		light[i].spotExponent = 0.0f;
180 		light[i].spotCutoffAngle = 180.0f;
181 	}
182 
183 	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
184 	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
185 
186 	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
187 	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
188 	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
189 	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
190 	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
191 	materialShininess = 0.0f;
192 	lightModelTwoSide = false;
193 
194 	matrixMode = GL_MODELVIEW;
195 
196 	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
197 	{
198 		texture2Denabled[i] = false;
199 		textureExternalEnabled[i] = false;
200 	}
201 
202 	clientTexture = GL_TEXTURE0;
203 
204 	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);
205 
206 	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
207 	{
208 		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);
209 	}
210 
211 	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);
212 	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);
213 
214 	clipFlags = 0;
215 
216 	alphaTestEnabled = false;
217 	alphaTestFunc = GL_ALWAYS;
218 	alphaTestRef = 0;
219 
220 	fogEnabled = false;
221 	fogMode = GL_EXP;
222 	fogDensity = 1.0f;
223 	fogStart = 0.0f;
224 	fogEnd = 1.0f;
225 	fogColor = {0, 0, 0, 0};
226 
227 	lineSmoothEnabled = false;
228 	colorMaterialEnabled = false;
229 	normalizeEnabled = false;
230 	rescaleNormalEnabled = false;
231 	multisampleEnabled = true;
232 	sampleAlphaToOneEnabled = false;
233 
234 	colorLogicOpEnabled = false;
235 	logicalOperation = GL_COPY;
236 
237 	pointSpriteEnabled = false;
238 	pointSmoothEnabled = false;
239 	pointSizeMin = 0.0f;
240 	pointSizeMax = 1.0f;
241 	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};
242 	pointFadeThresholdSize = 1.0f;
243 
244 	mHasBeenCurrent = false;
245 
246 	markAllStateDirty();
247 }
248 
~Context()249 Context::~Context()
250 {
251 	while(!mFramebufferNameSpace.empty())
252 	{
253 		deleteFramebuffer(mFramebufferNameSpace.firstName());
254 	}
255 
256 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
257 	{
258 		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
259 		{
260 			mState.samplerTexture[type][sampler] = nullptr;
261 		}
262 	}
263 
264 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
265 	{
266 		mState.vertexAttribute[i].mBoundBuffer = nullptr;
267 	}
268 
269 	mState.arrayBuffer = nullptr;
270 	mState.elementArrayBuffer = nullptr;
271 	mState.renderbuffer = nullptr;
272 
273 	mTexture2DZero = nullptr;
274 	mTextureExternalZero = nullptr;
275 
276 	delete mVertexDataManager;
277 	delete mIndexDataManager;
278 
279 	mResourceManager->release();
280 	delete device;
281 }
282 
makeCurrent(egl::Surface * surface)283 void Context::makeCurrent(egl::Surface *surface)
284 {
285 	if(!mHasBeenCurrent)
286 	{
287 		mState.viewportX = 0;
288 		mState.viewportY = 0;
289 		mState.viewportWidth = surface->getWidth();
290 		mState.viewportHeight = surface->getHeight();
291 
292 		mState.scissorX = 0;
293 		mState.scissorY = 0;
294 		mState.scissorWidth = surface->getWidth();
295 		mState.scissorHeight = surface->getHeight();
296 
297 		mHasBeenCurrent = true;
298 	}
299 
300 	// Wrap the existing resources into GL objects and assign them to the '0' names
301 	egl::Image *defaultRenderTarget = surface->getRenderTarget();
302 	egl::Image *depthStencil = surface->getDepthStencil();
303 
304 	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
305 	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
306 	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
307 
308 	setFramebufferZero(framebufferZero);
309 
310 	if(defaultRenderTarget)
311 	{
312 		defaultRenderTarget->release();
313 	}
314 
315 	if(depthStencil)
316 	{
317 		depthStencil->release();
318 	}
319 
320 	markAllStateDirty();
321 }
322 
getClientVersion() const323 int Context::getClientVersion() const
324 {
325 	return 1;
326 }
327 
328 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
markAllStateDirty()329 void Context::markAllStateDirty()
330 {
331 	mDepthStateDirty = true;
332 	mMaskStateDirty = true;
333 	mBlendStateDirty = true;
334 	mStencilStateDirty = true;
335 	mPolygonOffsetStateDirty = true;
336 	mSampleStateDirty = true;
337 	mDitherStateDirty = true;
338 	mFrontFaceDirty = true;
339 }
340 
setClearColor(float red,float green,float blue,float alpha)341 void Context::setClearColor(float red, float green, float blue, float alpha)
342 {
343 	mState.colorClearValue.red = red;
344 	mState.colorClearValue.green = green;
345 	mState.colorClearValue.blue = blue;
346 	mState.colorClearValue.alpha = alpha;
347 }
348 
setClearDepth(float depth)349 void Context::setClearDepth(float depth)
350 {
351 	mState.depthClearValue = depth;
352 }
353 
setClearStencil(int stencil)354 void Context::setClearStencil(int stencil)
355 {
356 	mState.stencilClearValue = stencil;
357 }
358 
setCullFaceEnabled(bool enabled)359 void Context::setCullFaceEnabled(bool enabled)
360 {
361 	mState.cullFaceEnabled = enabled;
362 }
363 
isCullFaceEnabled() const364 bool Context::isCullFaceEnabled() const
365 {
366 	return mState.cullFaceEnabled;
367 }
368 
setCullMode(GLenum mode)369 void Context::setCullMode(GLenum mode)
370 {
371    mState.cullMode = mode;
372 }
373 
setFrontFace(GLenum front)374 void Context::setFrontFace(GLenum front)
375 {
376 	if(mState.frontFace != front)
377 	{
378 		mState.frontFace = front;
379 		mFrontFaceDirty = true;
380 	}
381 }
382 
setDepthTestEnabled(bool enabled)383 void Context::setDepthTestEnabled(bool enabled)
384 {
385 	if(mState.depthTestEnabled != enabled)
386 	{
387 		mState.depthTestEnabled = enabled;
388 		mDepthStateDirty = true;
389 	}
390 }
391 
isDepthTestEnabled() const392 bool Context::isDepthTestEnabled() const
393 {
394 	return mState.depthTestEnabled;
395 }
396 
setDepthFunc(GLenum depthFunc)397 void Context::setDepthFunc(GLenum depthFunc)
398 {
399 	if(mState.depthFunc != depthFunc)
400 	{
401 		mState.depthFunc = depthFunc;
402 		mDepthStateDirty = true;
403 	}
404 }
405 
setDepthRange(float zNear,float zFar)406 void Context::setDepthRange(float zNear, float zFar)
407 {
408 	mState.zNear = zNear;
409 	mState.zFar = zFar;
410 }
411 
setAlphaTestEnabled(bool enabled)412 void Context::setAlphaTestEnabled(bool enabled)
413 {
414 	alphaTestEnabled = enabled;
415 }
416 
isAlphaTestEnabled() const417 bool Context::isAlphaTestEnabled() const
418 {
419 	return alphaTestEnabled;
420 }
421 
setAlphaFunc(GLenum alphaFunc,GLclampf reference)422 void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)
423 {
424 	alphaTestFunc = alphaFunc;
425 	alphaTestRef = reference;
426 }
427 
setBlendEnabled(bool enabled)428 void Context::setBlendEnabled(bool enabled)
429 {
430 	if(mState.blendEnabled != enabled)
431 	{
432 		mState.blendEnabled = enabled;
433 		mBlendStateDirty = true;
434 	}
435 }
436 
isBlendEnabled() const437 bool Context::isBlendEnabled() const
438 {
439 	return mState.blendEnabled;
440 }
441 
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)442 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
443 {
444 	if(mState.sourceBlendRGB != sourceRGB ||
445 	   mState.sourceBlendAlpha != sourceAlpha ||
446 	   mState.destBlendRGB != destRGB ||
447 	   mState.destBlendAlpha != destAlpha)
448 	{
449 		mState.sourceBlendRGB = sourceRGB;
450 		mState.destBlendRGB = destRGB;
451 		mState.sourceBlendAlpha = sourceAlpha;
452 		mState.destBlendAlpha = destAlpha;
453 		mBlendStateDirty = true;
454 	}
455 }
456 
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)457 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
458 {
459 	if(mState.blendEquationRGB != rgbEquation ||
460 	   mState.blendEquationAlpha != alphaEquation)
461 	{
462 		mState.blendEquationRGB = rgbEquation;
463 		mState.blendEquationAlpha = alphaEquation;
464 		mBlendStateDirty = true;
465 	}
466 }
467 
setStencilTestEnabled(bool enabled)468 void Context::setStencilTestEnabled(bool enabled)
469 {
470 	if(mState.stencilTestEnabled != enabled)
471 	{
472 		mState.stencilTestEnabled = enabled;
473 		mStencilStateDirty = true;
474 	}
475 }
476 
isStencilTestEnabled() const477 bool Context::isStencilTestEnabled() const
478 {
479 	return mState.stencilTestEnabled;
480 }
481 
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)482 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
483 {
484 	if(mState.stencilFunc != stencilFunc ||
485 	   mState.stencilRef != stencilRef ||
486 	   mState.stencilMask != stencilMask)
487 	{
488 		mState.stencilFunc = stencilFunc;
489 		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
490 		mState.stencilMask = stencilMask;
491 		mStencilStateDirty = true;
492 	}
493 }
494 
setStencilWritemask(GLuint stencilWritemask)495 void Context::setStencilWritemask(GLuint stencilWritemask)
496 {
497 	if(mState.stencilWritemask != stencilWritemask)
498 	{
499 		mState.stencilWritemask = stencilWritemask;
500 		mStencilStateDirty = true;
501 	}
502 }
503 
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)504 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
505 {
506 	if(mState.stencilFail != stencilFail ||
507 	   mState.stencilPassDepthFail != stencilPassDepthFail ||
508 	   mState.stencilPassDepthPass != stencilPassDepthPass)
509 	{
510 		mState.stencilFail = stencilFail;
511 		mState.stencilPassDepthFail = stencilPassDepthFail;
512 		mState.stencilPassDepthPass = stencilPassDepthPass;
513 		mStencilStateDirty = true;
514 	}
515 }
516 
setPolygonOffsetFillEnabled(bool enabled)517 void Context::setPolygonOffsetFillEnabled(bool enabled)
518 {
519 	if(mState.polygonOffsetFillEnabled != enabled)
520 	{
521 		mState.polygonOffsetFillEnabled = enabled;
522 		mPolygonOffsetStateDirty = true;
523 	}
524 }
525 
isPolygonOffsetFillEnabled() const526 bool Context::isPolygonOffsetFillEnabled() const
527 {
528 	return mState.polygonOffsetFillEnabled;
529 }
530 
setPolygonOffsetParams(GLfloat factor,GLfloat units)531 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
532 {
533 	if(mState.polygonOffsetFactor != factor ||
534 	   mState.polygonOffsetUnits != units)
535 	{
536 		mState.polygonOffsetFactor = factor;
537 		mState.polygonOffsetUnits = units;
538 		mPolygonOffsetStateDirty = true;
539 	}
540 }
541 
setSampleAlphaToCoverageEnabled(bool enabled)542 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
543 {
544 	if(mState.sampleAlphaToCoverageEnabled != enabled)
545 	{
546 		mState.sampleAlphaToCoverageEnabled = enabled;
547 		mSampleStateDirty = true;
548 	}
549 }
550 
isSampleAlphaToCoverageEnabled() const551 bool Context::isSampleAlphaToCoverageEnabled() const
552 {
553 	return mState.sampleAlphaToCoverageEnabled;
554 }
555 
setSampleCoverageEnabled(bool enabled)556 void Context::setSampleCoverageEnabled(bool enabled)
557 {
558 	if(mState.sampleCoverageEnabled != enabled)
559 	{
560 		mState.sampleCoverageEnabled = enabled;
561 		mSampleStateDirty = true;
562 	}
563 }
564 
isSampleCoverageEnabled() const565 bool Context::isSampleCoverageEnabled() const
566 {
567 	return mState.sampleCoverageEnabled;
568 }
569 
setSampleCoverageParams(GLclampf value,bool invert)570 void Context::setSampleCoverageParams(GLclampf value, bool invert)
571 {
572 	if(mState.sampleCoverageValue != value ||
573 	   mState.sampleCoverageInvert != invert)
574 	{
575 		mState.sampleCoverageValue = value;
576 		mState.sampleCoverageInvert = invert;
577 		mSampleStateDirty = true;
578 	}
579 }
580 
setScissorTestEnabled(bool enabled)581 void Context::setScissorTestEnabled(bool enabled)
582 {
583 	mState.scissorTestEnabled = enabled;
584 }
585 
isScissorTestEnabled() const586 bool Context::isScissorTestEnabled() const
587 {
588 	return mState.scissorTestEnabled;
589 }
590 
setShadeModel(GLenum mode)591 void Context::setShadeModel(GLenum mode)
592 {
593 	mState.shadeModel = mode;
594 }
595 
setDitherEnabled(bool enabled)596 void Context::setDitherEnabled(bool enabled)
597 {
598 	if(mState.ditherEnabled != enabled)
599 	{
600 		mState.ditherEnabled = enabled;
601 		mDitherStateDirty = true;
602 	}
603 }
604 
isDitherEnabled() const605 bool Context::isDitherEnabled() const
606 {
607 	return mState.ditherEnabled;
608 }
609 
setLightingEnabled(bool enable)610 void Context::setLightingEnabled(bool enable)
611 {
612 	lightingEnabled = enable;
613 }
614 
isLightingEnabled() const615 bool Context::isLightingEnabled() const
616 {
617 	return lightingEnabled;
618 }
619 
setLightEnabled(int index,bool enable)620 void Context::setLightEnabled(int index, bool enable)
621 {
622 	light[index].enabled = enable;
623 }
624 
isLightEnabled(int index) const625 bool Context::isLightEnabled(int index) const
626 {
627 	return light[index].enabled;
628 }
629 
setLightAmbient(int index,float r,float g,float b,float a)630 void Context::setLightAmbient(int index, float r, float g, float b, float a)
631 {
632 	light[index].ambient = {r, g, b, a};
633 }
634 
setLightDiffuse(int index,float r,float g,float b,float a)635 void Context::setLightDiffuse(int index, float r, float g, float b, float a)
636 {
637 	light[index].diffuse = {r, g, b, a};
638 }
639 
setLightSpecular(int index,float r,float g,float b,float a)640 void Context::setLightSpecular(int index, float r, float g, float b, float a)
641 {
642 	light[index].specular = {r, g, b, a};
643 }
644 
setLightPosition(int index,float x,float y,float z,float w)645 void Context::setLightPosition(int index, float x, float y, float z, float w)
646 {
647 	sw::float4 v = {x, y, z, w};
648 
649 	// Transform from object coordinates to eye coordinates
650 	v = modelViewStack.current() * v;
651 
652 	light[index].position = {v.x, v.y, v.z, v.w};
653 }
654 
setLightDirection(int index,float x,float y,float z)655 void Context::setLightDirection(int index, float x, float y, float z)
656 {
657 	// FIXME: Transform by inverse of 3x3 model-view matrix
658 	light[index].direction = {x, y, z};
659 }
660 
setLightAttenuationConstant(int index,float constant)661 void Context::setLightAttenuationConstant(int index, float constant)
662 {
663 	light[index].attenuation.constant = constant;
664 }
665 
setLightAttenuationLinear(int index,float linear)666 void Context::setLightAttenuationLinear(int index, float linear)
667 {
668 	light[index].attenuation.linear = linear;
669 }
670 
setLightAttenuationQuadratic(int index,float quadratic)671 void Context::setLightAttenuationQuadratic(int index, float quadratic)
672 {
673 	light[index].attenuation.quadratic = quadratic;
674 }
675 
setSpotLightExponent(int index,float exponent)676 void Context::setSpotLightExponent(int index, float exponent)
677 {
678 	light[index].spotExponent = exponent;
679 }
680 
setSpotLightCutoff(int index,float cutoff)681 void Context::setSpotLightCutoff(int index, float cutoff)
682 {
683 	light[index].spotCutoffAngle = cutoff;
684 }
685 
setGlobalAmbient(float red,float green,float blue,float alpha)686 void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
687 {
688 	globalAmbient.red = red;
689 	globalAmbient.green = green;
690 	globalAmbient.blue = blue;
691 	globalAmbient.alpha = alpha;
692 }
693 
setMaterialAmbient(float red,float green,float blue,float alpha)694 void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
695 {
696 	materialAmbient.red = red;
697 	materialAmbient.green = green;
698 	materialAmbient.blue = blue;
699 	materialAmbient.alpha = alpha;
700 }
701 
setMaterialDiffuse(float red,float green,float blue,float alpha)702 void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
703 {
704 	materialDiffuse.red = red;
705 	materialDiffuse.green = green;
706 	materialDiffuse.blue = blue;
707 	materialDiffuse.alpha = alpha;
708 }
709 
setMaterialSpecular(float red,float green,float blue,float alpha)710 void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
711 {
712 	materialSpecular.red = red;
713 	materialSpecular.green = green;
714 	materialSpecular.blue = blue;
715 	materialSpecular.alpha = alpha;
716 }
717 
setMaterialEmission(float red,float green,float blue,float alpha)718 void Context::setMaterialEmission(float red, float green, float blue, float alpha)
719 {
720 	materialEmission.red = red;
721 	materialEmission.green = green;
722 	materialEmission.blue = blue;
723 	materialEmission.alpha = alpha;
724 }
725 
setMaterialShininess(float shininess)726 void Context::setMaterialShininess(float shininess)
727 {
728 	materialShininess = shininess;
729 }
730 
setLightModelTwoSide(bool enable)731 void Context::setLightModelTwoSide(bool enable)
732 {
733 	lightModelTwoSide = enable;
734 }
735 
setFogEnabled(bool enable)736 void Context::setFogEnabled(bool enable)
737 {
738 	fogEnabled = enable;
739 }
740 
isFogEnabled() const741 bool Context::isFogEnabled() const
742 {
743 	return fogEnabled;
744 }
745 
setFogMode(GLenum mode)746 void Context::setFogMode(GLenum mode)
747 {
748 	fogMode = mode;
749 }
750 
setFogDensity(float fogDensity)751 void Context::setFogDensity(float fogDensity)
752 {
753 	this->fogDensity = fogDensity;
754 }
755 
setFogStart(float fogStart)756 void Context::setFogStart(float fogStart)
757 {
758 	this->fogStart = fogStart;
759 }
760 
setFogEnd(float fogEnd)761 void Context::setFogEnd(float fogEnd)
762 {
763 	this->fogEnd = fogEnd;
764 }
765 
setFogColor(float r,float g,float b,float a)766 void Context::setFogColor(float r, float g, float b, float a)
767 {
768 	this->fogColor = {r, g, b, a};
769 }
770 
setTexture2Denabled(bool enable)771 void Context::setTexture2Denabled(bool enable)
772 {
773 	texture2Denabled[mState.activeSampler] = enable;
774 }
775 
isTexture2Denabled() const776 bool Context::isTexture2Denabled() const
777 {
778 	return texture2Denabled[mState.activeSampler];
779 }
780 
setTextureExternalEnabled(bool enable)781 void Context::setTextureExternalEnabled(bool enable)
782 {
783 	textureExternalEnabled[mState.activeSampler] = enable;
784 }
785 
isTextureExternalEnabled() const786 bool Context::isTextureExternalEnabled() const
787 {
788 	return textureExternalEnabled[mState.activeSampler];
789 }
790 
setLineWidth(GLfloat width)791 void Context::setLineWidth(GLfloat width)
792 {
793 	mState.lineWidth = width;
794 	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
795 }
796 
setGenerateMipmapHint(GLenum hint)797 void Context::setGenerateMipmapHint(GLenum hint)
798 {
799 	mState.generateMipmapHint = hint;
800 }
801 
setPerspectiveCorrectionHint(GLenum hint)802 void Context::setPerspectiveCorrectionHint(GLenum hint)
803 {
804 	mState.perspectiveCorrectionHint = hint;
805 }
806 
setFogHint(GLenum hint)807 void Context::setFogHint(GLenum hint)
808 {
809 	mState.fogHint = hint;
810 }
811 
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)812 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
813 {
814 	mState.viewportX = x;
815 	mState.viewportY = y;
816 	mState.viewportWidth = width;
817 	mState.viewportHeight = height;
818 }
819 
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)820 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
821 {
822 	mState.scissorX = x;
823 	mState.scissorY = y;
824 	mState.scissorWidth = width;
825 	mState.scissorHeight = height;
826 }
827 
setColorMask(bool red,bool green,bool blue,bool alpha)828 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
829 {
830 	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
831 	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
832 	{
833 		mState.colorMaskRed = red;
834 		mState.colorMaskGreen = green;
835 		mState.colorMaskBlue = blue;
836 		mState.colorMaskAlpha = alpha;
837 		mMaskStateDirty = true;
838 	}
839 }
840 
setDepthMask(bool mask)841 void Context::setDepthMask(bool mask)
842 {
843 	if(mState.depthMask != mask)
844 	{
845 		mState.depthMask = mask;
846 		mMaskStateDirty = true;
847 	}
848 }
849 
setActiveSampler(unsigned int active)850 void Context::setActiveSampler(unsigned int active)
851 {
852 	mState.activeSampler = active;
853 }
854 
getFramebufferName() const855 GLuint Context::getFramebufferName() const
856 {
857 	return mState.framebuffer;
858 }
859 
getRenderbufferName() const860 GLuint Context::getRenderbufferName() const
861 {
862 	return mState.renderbuffer.name();
863 }
864 
getArrayBufferName() const865 GLuint Context::getArrayBufferName() const
866 {
867 	return mState.arrayBuffer.name();
868 }
869 
setVertexAttribArrayEnabled(unsigned int attribNum,bool enabled)870 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
871 {
872 	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
873 }
874 
getVertexAttribState(unsigned int attribNum)875 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
876 {
877 	return mState.vertexAttribute[attribNum];
878 }
879 
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,GLsizei stride,const void * pointer)880 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
881                                    GLsizei stride, const void *pointer)
882 {
883 	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
884 	mState.vertexAttribute[attribNum].mSize = size;
885 	mState.vertexAttribute[attribNum].mType = type;
886 	mState.vertexAttribute[attribNum].mNormalized = normalized;
887 	mState.vertexAttribute[attribNum].mStride = stride;
888 	mState.vertexAttribute[attribNum].mPointer = pointer;
889 }
890 
getVertexAttribPointer(unsigned int attribNum) const891 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
892 {
893 	return mState.vertexAttribute[attribNum].mPointer;
894 }
895 
getVertexAttributes()896 const VertexAttributeArray &Context::getVertexAttributes()
897 {
898 	return mState.vertexAttribute;
899 }
900 
setPackAlignment(GLint alignment)901 void Context::setPackAlignment(GLint alignment)
902 {
903 	mState.packAlignment = alignment;
904 }
905 
getPackAlignment() const906 GLint Context::getPackAlignment() const
907 {
908 	return mState.packAlignment;
909 }
910 
setUnpackAlignment(GLint alignment)911 void Context::setUnpackAlignment(GLint alignment)
912 {
913 	mState.unpackAlignment = alignment;
914 }
915 
getUnpackAlignment() const916 GLint Context::getUnpackAlignment() const
917 {
918 	return mState.unpackAlignment;
919 }
920 
createBuffer()921 GLuint Context::createBuffer()
922 {
923 	return mResourceManager->createBuffer();
924 }
925 
createTexture()926 GLuint Context::createTexture()
927 {
928 	return mResourceManager->createTexture();
929 }
930 
createRenderbuffer()931 GLuint Context::createRenderbuffer()
932 {
933 	return mResourceManager->createRenderbuffer();
934 }
935 
936 // Returns an unused framebuffer name
createFramebuffer()937 GLuint Context::createFramebuffer()
938 {
939 	return mFramebufferNameSpace.allocate();
940 }
941 
deleteBuffer(GLuint buffer)942 void Context::deleteBuffer(GLuint buffer)
943 {
944 	detachBuffer(buffer);
945 
946 	mResourceManager->deleteBuffer(buffer);
947 }
948 
deleteTexture(GLuint texture)949 void Context::deleteTexture(GLuint texture)
950 {
951 	detachTexture(texture);
952 
953 	mResourceManager->deleteTexture(texture);
954 }
955 
deleteRenderbuffer(GLuint renderbuffer)956 void Context::deleteRenderbuffer(GLuint renderbuffer)
957 {
958 	detachRenderbuffer(renderbuffer);
959 
960 	mResourceManager->deleteRenderbuffer(renderbuffer);
961 }
962 
deleteFramebuffer(GLuint framebuffer)963 void Context::deleteFramebuffer(GLuint framebuffer)
964 {
965 	detachFramebuffer(framebuffer);
966 
967 	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
968 
969 	if(framebufferObject)
970 	{
971 		delete framebufferObject;
972 	}
973 }
974 
getBuffer(GLuint handle)975 Buffer *Context::getBuffer(GLuint handle)
976 {
977 	return mResourceManager->getBuffer(handle);
978 }
979 
getTexture(GLuint handle)980 Texture *Context::getTexture(GLuint handle)
981 {
982 	return mResourceManager->getTexture(handle);
983 }
984 
getRenderbuffer(GLuint handle)985 Renderbuffer *Context::getRenderbuffer(GLuint handle)
986 {
987 	return mResourceManager->getRenderbuffer(handle);
988 }
989 
getFramebuffer()990 Framebuffer *Context::getFramebuffer()
991 {
992 	return getFramebuffer(mState.framebuffer);
993 }
994 
bindArrayBuffer(unsigned int buffer)995 void Context::bindArrayBuffer(unsigned int buffer)
996 {
997 	mResourceManager->checkBufferAllocation(buffer);
998 
999 	mState.arrayBuffer = getBuffer(buffer);
1000 }
1001 
bindElementArrayBuffer(unsigned int buffer)1002 void Context::bindElementArrayBuffer(unsigned int buffer)
1003 {
1004 	mResourceManager->checkBufferAllocation(buffer);
1005 
1006 	mState.elementArrayBuffer = getBuffer(buffer);
1007 }
1008 
bindTexture2D(GLuint texture)1009 void Context::bindTexture2D(GLuint texture)
1010 {
1011 	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
1012 
1013 	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
1014 }
1015 
bindTextureExternal(GLuint texture)1016 void Context::bindTextureExternal(GLuint texture)
1017 {
1018 	mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
1019 
1020 	mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
1021 }
1022 
bindFramebuffer(GLuint framebuffer)1023 void Context::bindFramebuffer(GLuint framebuffer)
1024 {
1025 	if(!getFramebuffer(framebuffer))
1026 	{
1027 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1028 	}
1029 
1030 	mState.framebuffer = framebuffer;
1031 }
1032 
bindRenderbuffer(GLuint renderbuffer)1033 void Context::bindRenderbuffer(GLuint renderbuffer)
1034 {
1035 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
1036 
1037 	mState.renderbuffer = getRenderbuffer(renderbuffer);
1038 }
1039 
setFramebufferZero(Framebuffer * buffer)1040 void Context::setFramebufferZero(Framebuffer *buffer)
1041 {
1042 	delete mFramebufferNameSpace.remove(0);
1043 	mFramebufferNameSpace.insert(0, buffer);
1044 }
1045 
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1046 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1047 {
1048 	Renderbuffer *renderbufferObject = mState.renderbuffer;
1049 	renderbufferObject->setStorage(renderbuffer);
1050 }
1051 
getFramebuffer(unsigned int handle)1052 Framebuffer *Context::getFramebuffer(unsigned int handle)
1053 {
1054 	return mFramebufferNameSpace.find(handle);
1055 }
1056 
getArrayBuffer()1057 Buffer *Context::getArrayBuffer()
1058 {
1059 	return mState.arrayBuffer;
1060 }
1061 
getElementArrayBuffer()1062 Buffer *Context::getElementArrayBuffer()
1063 {
1064 	return mState.elementArrayBuffer;
1065 }
1066 
getTexture2D()1067 Texture2D *Context::getTexture2D()
1068 {
1069 	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1070 }
1071 
getTextureExternal()1072 TextureExternal *Context::getTextureExternal()
1073 {
1074 	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1075 }
1076 
getSamplerTexture(unsigned int sampler,TextureType type)1077 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1078 {
1079 	GLuint texid = mState.samplerTexture[type][sampler].name();
1080 
1081 	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1082 	{
1083 		switch(type)
1084 		{
1085 		case TEXTURE_2D: return mTexture2DZero;
1086 		case TEXTURE_EXTERNAL: return mTextureExternalZero;
1087 		default: UNREACHABLE(type);
1088 		}
1089 	}
1090 
1091 	return mState.samplerTexture[type][sampler];
1092 }
1093 
getBooleanv(GLenum pname,GLboolean * params)1094 bool Context::getBooleanv(GLenum pname, GLboolean *params)
1095 {
1096 	switch(pname)
1097 	{
1098 	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
1099 	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
1100 	case GL_COLOR_WRITEMASK:
1101 		params[0] = mState.colorMaskRed;
1102 		params[1] = mState.colorMaskGreen;
1103 		params[2] = mState.colorMaskBlue;
1104 		params[3] = mState.colorMaskAlpha;
1105 		break;
1106 	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
1107 	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
1108 	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1109 	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
1110 	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
1111 	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
1112 	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
1113 	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
1114 	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
1115 	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;
1116 	default:
1117 		return false;
1118 	}
1119 
1120 	return true;
1121 }
1122 
getFloatv(GLenum pname,GLfloat * params)1123 bool Context::getFloatv(GLenum pname, GLfloat *params)
1124 {
1125 	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1126 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1127 	// GetIntegerv as its native query function. As it would require conversion in any
1128 	// case, this should make no difference to the calling application.
1129 	switch(pname)
1130 	{
1131 	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1132 	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1133 	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1134 	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1135 	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1136 	case GL_ALIASED_LINE_WIDTH_RANGE:
1137 		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1138 		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1139 		break;
1140 	case GL_ALIASED_POINT_SIZE_RANGE:
1141 		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1142 		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1143 		break;
1144 	case GL_SMOOTH_LINE_WIDTH_RANGE:
1145 		params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;
1146 		params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;
1147 		break;
1148 	case GL_SMOOTH_POINT_SIZE_RANGE:
1149 		params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;
1150 		params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;
1151 		break;
1152 	case GL_DEPTH_RANGE:
1153 		params[0] = mState.zNear;
1154 		params[1] = mState.zFar;
1155 		break;
1156 	case GL_COLOR_CLEAR_VALUE:
1157 		params[0] = mState.colorClearValue.red;
1158 		params[1] = mState.colorClearValue.green;
1159 		params[2] = mState.colorClearValue.blue;
1160 		params[3] = mState.colorClearValue.alpha;
1161 		break;
1162 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1163 		*params = MAX_TEXTURE_MAX_ANISOTROPY;
1164 		break;
1165 	case GL_MODELVIEW_MATRIX:
1166 		for(int i = 0; i < 16; i++)
1167 		{
1168 			params[i] = modelViewStack.current()[i % 4][i / 4];
1169 		}
1170 		break;
1171 	case GL_PROJECTION_MATRIX:
1172 		for(int i = 0; i < 16; i++)
1173 		{
1174 			params[i] = projectionStack.current()[i % 4][i / 4];
1175 		}
1176 		break;
1177 	default:
1178 		return false;
1179 	}
1180 
1181 	return true;
1182 }
1183 
getIntegerv(GLenum pname,GLint * params)1184 bool Context::getIntegerv(GLenum pname, GLint *params)
1185 {
1186 	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1187 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1188 	// GetIntegerv as its native query function. As it would require conversion in any
1189 	// case, this should make no difference to the calling application. You may find it in
1190 	// Context::getFloatv.
1191 	switch(pname)
1192 	{
1193 	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
1194 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
1195 	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;
1196 	case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;
1197 	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1198 	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1199 	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1200 	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;
1201 	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1202 	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
1203 	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
1204 	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
1205 	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
1206 	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
1207 	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
1208 	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
1209 	case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;
1210 	case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;
1211 	case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;
1212 	case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;
1213 	case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;
1214 	case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;
1215 	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
1216 	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1217 	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1218 	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
1219 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
1220 	case GL_SAMPLE_BUFFERS:
1221 	case GL_SAMPLES:
1222 		{
1223 			Framebuffer *framebuffer = getFramebuffer();
1224 			int width, height, samples;
1225 
1226 			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES)
1227 			{
1228 				switch(pname)
1229 				{
1230 				case GL_SAMPLE_BUFFERS:
1231 					if(samples > 1)
1232 					{
1233 						*params = 1;
1234 					}
1235 					else
1236 					{
1237 						*params = 0;
1238 					}
1239 					break;
1240 				case GL_SAMPLES:
1241 					*params = samples;
1242 					break;
1243 				}
1244 			}
1245 			else
1246 			{
1247 				*params = 0;
1248 			}
1249 		}
1250 		break;
1251 	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1252 		{
1253 			Framebuffer *framebuffer = getFramebuffer();
1254 			*params = framebuffer->getImplementationColorReadType();
1255 		}
1256 		break;
1257 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1258 		{
1259 			Framebuffer *framebuffer = getFramebuffer();
1260 			*params = framebuffer->getImplementationColorReadFormat();
1261 		}
1262 		break;
1263 	case GL_MAX_VIEWPORT_DIMS:
1264 		{
1265 			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1266 			params[0] = maxDimension;
1267 			params[1] = maxDimension;
1268 		}
1269 		break;
1270 	case GL_COMPRESSED_TEXTURE_FORMATS:
1271 		{
1272 			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1273 			{
1274 				params[i] = compressedTextureFormats[i];
1275 			}
1276 		}
1277 		break;
1278 	case GL_VIEWPORT:
1279 		params[0] = mState.viewportX;
1280 		params[1] = mState.viewportY;
1281 		params[2] = mState.viewportWidth;
1282 		params[3] = mState.viewportHeight;
1283 		break;
1284 	case GL_SCISSOR_BOX:
1285 		params[0] = mState.scissorX;
1286 		params[1] = mState.scissorY;
1287 		params[2] = mState.scissorWidth;
1288 		params[3] = mState.scissorHeight;
1289 		break;
1290 	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
1291 	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
1292 	case GL_RED_BITS:
1293 	case GL_GREEN_BITS:
1294 	case GL_BLUE_BITS:
1295 	case GL_ALPHA_BITS:
1296 		{
1297 			Framebuffer *framebuffer = getFramebuffer();
1298 			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1299 
1300 			if(colorbuffer)
1301 			{
1302 				switch(pname)
1303 				{
1304 				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
1305 				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1306 				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
1307 				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1308 				}
1309 			}
1310 			else
1311 			{
1312 				*params = 0;
1313 			}
1314 		}
1315 		break;
1316 	case GL_DEPTH_BITS:
1317 		{
1318 			Framebuffer *framebuffer = getFramebuffer();
1319 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1320 
1321 			if(depthbuffer)
1322 			{
1323 				*params = depthbuffer->getDepthSize();
1324 			}
1325 			else
1326 			{
1327 				*params = 0;
1328 			}
1329 		}
1330 		break;
1331 	case GL_STENCIL_BITS:
1332 		{
1333 			Framebuffer *framebuffer = getFramebuffer();
1334 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1335 
1336 			if(stencilbuffer)
1337 			{
1338 				*params = stencilbuffer->getStencilSize();
1339 			}
1340 			else
1341 			{
1342 				*params = 0;
1343 			}
1344 		}
1345 		break;
1346 	case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;
1347 	case GL_TEXTURE_BINDING_CUBE_MAP_OES:        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();                 break;
1348 	case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;
1349 	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;
1350 	case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;
1351 	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;
1352 	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;
1353 	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;
1354 	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;
1355 	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;
1356 	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;
1357 	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;
1358 	case GL_VERTEX_ARRAY_SIZE:                   *params = mState.vertexAttribute[sw::Position].mSize;                                       break;
1359 	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;
1360 	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;
1361 	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;
1362 	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;
1363 	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;
1364 	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;
1365 	case GL_COLOR_ARRAY_SIZE:                    *params = mState.vertexAttribute[sw::Color0].mSize;                                         break;
1366 	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;
1367 	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;
1368 	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;
1369 	case GL_TEXTURE_COORD_ARRAY_SIZE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize;               break;
1370 	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;
1371 	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;
1372 	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;
1373 	default:
1374 		return false;
1375 	}
1376 
1377 	return true;
1378 }
1379 
getPointerv(GLenum pname,const GLvoid ** params)1380 bool Context::getPointerv(GLenum pname, const GLvoid **params)
1381 {
1382 	switch(pname)
1383 	{
1384 	case GL_VERTEX_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Position].mPointer;                         break;
1385 	case GL_NORMAL_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Normal].mPointer;                           break;
1386 	case GL_COLOR_ARRAY_POINTER:          *params = mState.vertexAttribute[sw::Color0].mPointer;                           break;
1387 	case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer;                        break;
1388 	case GL_TEXTURE_COORD_ARRAY_POINTER:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;
1389 	default:
1390 		return false;
1391 	}
1392 
1393 	return true;
1394 }
1395 
getQueryParameterNum(GLenum pname)1396 int Context::getQueryParameterNum(GLenum pname)
1397 {
1398 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1399 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1400 	// to the fact that it is stored internally as a float, and so would require conversion
1401 	// if returned from Context::getIntegerv. Since this conversion is already implemented
1402 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1403 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1404 	// application.
1405 	switch(pname)
1406 	{
1407 	case GL_COMPRESSED_TEXTURE_FORMATS:
1408 		return NUM_COMPRESSED_TEXTURE_FORMATS;
1409 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1410 	case GL_ARRAY_BUFFER_BINDING:
1411 	case GL_FRAMEBUFFER_BINDING_OES:
1412 	case GL_RENDERBUFFER_BINDING_OES:
1413 	case GL_PACK_ALIGNMENT:
1414 	case GL_UNPACK_ALIGNMENT:
1415 	case GL_GENERATE_MIPMAP_HINT:
1416 	case GL_RED_BITS:
1417 	case GL_GREEN_BITS:
1418 	case GL_BLUE_BITS:
1419 	case GL_ALPHA_BITS:
1420 	case GL_DEPTH_BITS:
1421 	case GL_STENCIL_BITS:
1422 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1423 	case GL_CULL_FACE_MODE:
1424 	case GL_FRONT_FACE:
1425 	case GL_ACTIVE_TEXTURE:
1426 	case GL_STENCIL_FUNC:
1427 	case GL_STENCIL_VALUE_MASK:
1428 	case GL_STENCIL_REF:
1429 	case GL_STENCIL_FAIL:
1430 	case GL_STENCIL_PASS_DEPTH_FAIL:
1431 	case GL_STENCIL_PASS_DEPTH_PASS:
1432 	case GL_DEPTH_FUNC:
1433 	case GL_BLEND_SRC_RGB_OES:
1434 	case GL_BLEND_SRC_ALPHA_OES:
1435 	case GL_BLEND_DST_RGB_OES:
1436 	case GL_BLEND_DST_ALPHA_OES:
1437 	case GL_BLEND_EQUATION_RGB_OES:
1438 	case GL_BLEND_EQUATION_ALPHA_OES:
1439 	case GL_STENCIL_WRITEMASK:
1440 	case GL_STENCIL_CLEAR_VALUE:
1441 	case GL_SUBPIXEL_BITS:
1442 	case GL_MAX_TEXTURE_SIZE:
1443 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
1444 	case GL_SAMPLE_BUFFERS:
1445 	case GL_SAMPLES:
1446 	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1447 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1448 	case GL_TEXTURE_BINDING_2D:
1449 	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1450 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
1451 		return 1;
1452 	case GL_MAX_VIEWPORT_DIMS:
1453 		return 2;
1454 	case GL_VIEWPORT:
1455 	case GL_SCISSOR_BOX:
1456 		return 4;
1457 	case GL_SAMPLE_COVERAGE_INVERT:
1458 	case GL_DEPTH_WRITEMASK:
1459 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1460 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1461 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1462 	case GL_SAMPLE_COVERAGE:
1463 	case GL_SCISSOR_TEST:
1464 	case GL_STENCIL_TEST:
1465 	case GL_DEPTH_TEST:
1466 	case GL_BLEND:
1467 	case GL_DITHER:
1468 		return 1;
1469 	case GL_COLOR_WRITEMASK:
1470 		return 4;
1471 	case GL_POLYGON_OFFSET_FACTOR:
1472 	case GL_POLYGON_OFFSET_UNITS:
1473 	case GL_SAMPLE_COVERAGE_VALUE:
1474 	case GL_DEPTH_CLEAR_VALUE:
1475 	case GL_LINE_WIDTH:
1476 		return 1;
1477 	case GL_ALIASED_LINE_WIDTH_RANGE:
1478 	case GL_ALIASED_POINT_SIZE_RANGE:
1479 	case GL_DEPTH_RANGE:
1480 		return 2;
1481 	case GL_COLOR_CLEAR_VALUE:
1482 		return 4;
1483 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1484 	case GL_MAX_LIGHTS:
1485 	case GL_MAX_MODELVIEW_STACK_DEPTH:
1486 	case GL_MAX_PROJECTION_STACK_DEPTH:
1487 	case GL_MAX_TEXTURE_STACK_DEPTH:
1488 	case GL_MAX_TEXTURE_UNITS:
1489 	case GL_MAX_CLIP_PLANES:
1490 	case GL_POINT_SIZE_ARRAY_TYPE_OES:
1491 	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1492 	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1493 		return 1;
1494 	case GL_CURRENT_COLOR:
1495 		return 4;
1496 	case GL_CURRENT_NORMAL:
1497 		return 3;
1498 	case GL_CURRENT_TEXTURE_COORDS:
1499 		return 4;
1500 	case GL_POINT_SIZE:
1501 	case GL_POINT_SIZE_MIN:
1502 	case GL_POINT_SIZE_MAX:
1503 	case GL_POINT_FADE_THRESHOLD_SIZE:
1504 		return 1;
1505 	case GL_POINT_DISTANCE_ATTENUATION:
1506 		return 3;
1507 	case GL_SMOOTH_POINT_SIZE_RANGE:
1508 	case GL_SMOOTH_LINE_WIDTH_RANGE:
1509 		return 2;
1510 	case GL_SHADE_MODEL:
1511 	case GL_MATRIX_MODE:
1512 	case GL_MODELVIEW_STACK_DEPTH:
1513 	case GL_PROJECTION_STACK_DEPTH:
1514 	case GL_TEXTURE_STACK_DEPTH:
1515 		return 1;
1516 	case GL_MODELVIEW_MATRIX:
1517 	case GL_PROJECTION_MATRIX:
1518 	case GL_TEXTURE_MATRIX:
1519 		return 16;
1520 	case GL_ALPHA_TEST_FUNC:
1521 	case GL_ALPHA_TEST_REF:
1522 	case GL_BLEND_DST:
1523 	case GL_BLEND_SRC:
1524 	case GL_LOGIC_OP_MODE:
1525 	case GL_VERTEX_ARRAY_SIZE:
1526 	case GL_VERTEX_ARRAY_TYPE:
1527 	case GL_VERTEX_ARRAY_STRIDE:
1528 	case GL_NORMAL_ARRAY_TYPE:
1529 	case GL_NORMAL_ARRAY_STRIDE:
1530 	case GL_COLOR_ARRAY_SIZE:
1531 	case GL_COLOR_ARRAY_TYPE:
1532 	case GL_COLOR_ARRAY_STRIDE:
1533 	case GL_TEXTURE_COORD_ARRAY_SIZE:
1534 	case GL_TEXTURE_COORD_ARRAY_TYPE:
1535 	case GL_TEXTURE_COORD_ARRAY_STRIDE:
1536 	case GL_VERTEX_ARRAY_POINTER:
1537 	case GL_NORMAL_ARRAY_POINTER:
1538 	case GL_COLOR_ARRAY_POINTER:
1539 	case GL_TEXTURE_COORD_ARRAY_POINTER:
1540 	case GL_LIGHT_MODEL_TWO_SIDE:
1541 		return 1;
1542 	default:
1543 		UNREACHABLE(pname);
1544 	}
1545 
1546 	return -1;
1547 }
1548 
isQueryParameterInt(GLenum pname)1549 bool Context::isQueryParameterInt(GLenum pname)
1550 {
1551 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1552 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1553 	// to the fact that it is stored internally as a float, and so would require conversion
1554 	// if returned from Context::getIntegerv. Since this conversion is already implemented
1555 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1556 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1557 	// application.
1558 	switch(pname)
1559 	{
1560 	case GL_COMPRESSED_TEXTURE_FORMATS:
1561 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1562 	case GL_ARRAY_BUFFER_BINDING:
1563 	case GL_FRAMEBUFFER_BINDING_OES:
1564 	case GL_RENDERBUFFER_BINDING_OES:
1565 	case GL_PACK_ALIGNMENT:
1566 	case GL_UNPACK_ALIGNMENT:
1567 	case GL_GENERATE_MIPMAP_HINT:
1568 	case GL_RED_BITS:
1569 	case GL_GREEN_BITS:
1570 	case GL_BLUE_BITS:
1571 	case GL_ALPHA_BITS:
1572 	case GL_DEPTH_BITS:
1573 	case GL_STENCIL_BITS:
1574 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1575 	case GL_CULL_FACE_MODE:
1576 	case GL_FRONT_FACE:
1577 	case GL_ACTIVE_TEXTURE:
1578 	case GL_STENCIL_FUNC:
1579 	case GL_STENCIL_VALUE_MASK:
1580 	case GL_STENCIL_REF:
1581 	case GL_STENCIL_FAIL:
1582 	case GL_STENCIL_PASS_DEPTH_FAIL:
1583 	case GL_STENCIL_PASS_DEPTH_PASS:
1584 	case GL_DEPTH_FUNC:
1585 	case GL_BLEND_SRC_RGB_OES:
1586 	case GL_BLEND_SRC_ALPHA_OES:
1587 	case GL_BLEND_DST_RGB_OES:
1588 	case GL_BLEND_DST_ALPHA_OES:
1589 	case GL_BLEND_EQUATION_RGB_OES:
1590 	case GL_BLEND_EQUATION_ALPHA_OES:
1591 	case GL_STENCIL_WRITEMASK:
1592 	case GL_STENCIL_CLEAR_VALUE:
1593 	case GL_SUBPIXEL_BITS:
1594 	case GL_MAX_TEXTURE_SIZE:
1595 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
1596 	case GL_SAMPLE_BUFFERS:
1597 	case GL_SAMPLES:
1598 	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1599 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1600 	case GL_TEXTURE_BINDING_2D:
1601 	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1602 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
1603 	case GL_MAX_VIEWPORT_DIMS:
1604 	case GL_VIEWPORT:
1605 	case GL_SCISSOR_BOX:
1606 	case GL_MAX_LIGHTS:
1607 	case GL_MAX_MODELVIEW_STACK_DEPTH:
1608 	case GL_MAX_PROJECTION_STACK_DEPTH:
1609 	case GL_MAX_TEXTURE_STACK_DEPTH:
1610 	case GL_MAX_TEXTURE_UNITS:
1611 	case GL_MAX_CLIP_PLANES:
1612 	case GL_POINT_SIZE_ARRAY_TYPE_OES:
1613 	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1614 	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1615 		return true;
1616 	}
1617 
1618 	return false;
1619 }
1620 
isQueryParameterFloat(GLenum pname)1621 bool Context::isQueryParameterFloat(GLenum pname)
1622 {
1623 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1624 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1625 	// to the fact that it is stored internally as a float, and so would require conversion
1626 	// if returned from Context::getIntegerv. Since this conversion is already implemented
1627 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1628 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1629 	// application.
1630 	switch(pname)
1631 	{
1632 	case GL_POLYGON_OFFSET_FACTOR:
1633 	case GL_POLYGON_OFFSET_UNITS:
1634 	case GL_SAMPLE_COVERAGE_VALUE:
1635 	case GL_DEPTH_CLEAR_VALUE:
1636 	case GL_LINE_WIDTH:
1637 	case GL_ALIASED_LINE_WIDTH_RANGE:
1638 	case GL_ALIASED_POINT_SIZE_RANGE:
1639 	case GL_SMOOTH_LINE_WIDTH_RANGE:
1640 	case GL_SMOOTH_POINT_SIZE_RANGE:
1641 	case GL_DEPTH_RANGE:
1642 	case GL_COLOR_CLEAR_VALUE:
1643 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1644 	case GL_LIGHT_MODEL_AMBIENT:
1645 	case GL_POINT_SIZE_MIN:
1646 	case GL_POINT_SIZE_MAX:
1647 	case GL_POINT_DISTANCE_ATTENUATION:
1648 	case GL_POINT_FADE_THRESHOLD_SIZE:
1649 		return true;
1650 	}
1651 
1652 	return false;
1653 }
1654 
isQueryParameterBool(GLenum pname)1655 bool Context::isQueryParameterBool(GLenum pname)
1656 {
1657 	switch(pname)
1658 	{
1659 	case GL_SAMPLE_COVERAGE_INVERT:
1660 	case GL_DEPTH_WRITEMASK:
1661 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1662 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1663 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1664 	case GL_SAMPLE_COVERAGE:
1665 	case GL_SCISSOR_TEST:
1666 	case GL_STENCIL_TEST:
1667 	case GL_DEPTH_TEST:
1668 	case GL_BLEND:
1669 	case GL_DITHER:
1670 	case GL_COLOR_WRITEMASK:
1671 	case GL_LIGHT_MODEL_TWO_SIDE:
1672 		return true;
1673 	}
1674 
1675 	return false;
1676 }
1677 
isQueryParameterPointer(GLenum pname)1678 bool Context::isQueryParameterPointer(GLenum pname)
1679 {
1680 	switch(pname)
1681 	{
1682 	case GL_VERTEX_ARRAY_POINTER:
1683 	case GL_NORMAL_ARRAY_POINTER:
1684 	case GL_COLOR_ARRAY_POINTER:
1685 	case GL_TEXTURE_COORD_ARRAY_POINTER:
1686 	case GL_POINT_SIZE_ARRAY_POINTER_OES:
1687 		return true;
1688 	}
1689 
1690 	return false;
1691 }
1692 
1693 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()1694 bool Context::applyRenderTarget()
1695 {
1696 	Framebuffer *framebuffer = getFramebuffer();
1697 	int width, height, samples;
1698 
1699 	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)
1700 	{
1701 		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);
1702 	}
1703 
1704 	egl::Image *renderTarget = framebuffer->getRenderTarget();
1705 	device->setRenderTarget(0, renderTarget);
1706 	if(renderTarget) renderTarget->release();
1707 
1708 	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
1709 	device->setDepthBuffer(depthBuffer);
1710 	if(depthBuffer) depthBuffer->release();
1711 
1712 	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
1713 	device->setStencilBuffer(stencilBuffer);
1714 	if(stencilBuffer) stencilBuffer->release();
1715 
1716 	Viewport viewport;
1717 	float zNear = clamp01(mState.zNear);
1718 	float zFar = clamp01(mState.zFar);
1719 
1720 	viewport.x0 = mState.viewportX;
1721 	viewport.y0 = mState.viewportY;
1722 	viewport.width = mState.viewportWidth;
1723 	viewport.height = mState.viewportHeight;
1724 	viewport.minZ = zNear;
1725 	viewport.maxZ = zFar;
1726 
1727 	device->setViewport(viewport);
1728 
1729 	if(mState.scissorTestEnabled)
1730 	{
1731 		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1732 		scissor.clip(0, 0, width, height);
1733 
1734 		device->setScissorRect(scissor);
1735 		device->setScissorEnable(true);
1736 	}
1737 	else
1738 	{
1739 		device->setScissorEnable(false);
1740 	}
1741 
1742 	return true;
1743 }
1744 
1745 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)1746 void Context::applyState(GLenum drawMode)
1747 {
1748 	Framebuffer *framebuffer = getFramebuffer();
1749 
1750 	if(mState.cullFaceEnabled)
1751 	{
1752 		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
1753 	}
1754 	else
1755 	{
1756 		device->setCullMode(sw::CULL_NONE);
1757 	}
1758 
1759 	if(mDepthStateDirty)
1760 	{
1761 		if(mState.depthTestEnabled)
1762 		{
1763 			device->setDepthBufferEnable(true);
1764 			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1765 		}
1766 		else
1767 		{
1768 			device->setDepthBufferEnable(false);
1769 		}
1770 
1771 		mDepthStateDirty = false;
1772 	}
1773 
1774 	if(mBlendStateDirty)
1775 	{
1776 		if(mState.blendEnabled)
1777 		{
1778 			device->setAlphaBlendEnable(true);
1779 			device->setSeparateAlphaBlendEnable(true);
1780 
1781 			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1782 			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1783 			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1784 
1785 			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1786 			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1787 			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1788 		}
1789 		else
1790 		{
1791 			device->setAlphaBlendEnable(false);
1792 		}
1793 
1794 		mBlendStateDirty = false;
1795 	}
1796 
1797 	if(mStencilStateDirty || mFrontFaceDirty)
1798 	{
1799 		if(mState.stencilTestEnabled && framebuffer->hasStencil())
1800 		{
1801 			device->setStencilEnable(true);
1802 			device->setTwoSidedStencil(true);
1803 
1804 			// get the maximum size of the stencil ref
1805 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1806 			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1807 
1808 			device->setStencilWriteMask(mState.stencilWritemask);
1809 			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1810 
1811 			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1812 			device->setStencilMask(mState.stencilMask);
1813 
1814 			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1815 			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1816 			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1817 
1818 			device->setStencilWriteMaskCCW(mState.stencilWritemask);
1819 			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1820 
1821 			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1822 			device->setStencilMaskCCW(mState.stencilMask);
1823 
1824 			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1825 			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1826 			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1827 		}
1828 		else
1829 		{
1830 			device->setStencilEnable(false);
1831 		}
1832 
1833 		mStencilStateDirty = false;
1834 		mFrontFaceDirty = false;
1835 	}
1836 
1837 	if(mMaskStateDirty)
1838 	{
1839 		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1840 		device->setDepthWriteEnable(mState.depthMask);
1841 
1842 		mMaskStateDirty = false;
1843 	}
1844 
1845 	if(mPolygonOffsetStateDirty)
1846 	{
1847 		if(mState.polygonOffsetFillEnabled)
1848 		{
1849 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1850 			if(depthbuffer)
1851 			{
1852 				device->setSlopeDepthBias(mState.polygonOffsetFactor);
1853 				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1854 				device->setDepthBias(depthBias);
1855 			}
1856 		}
1857 		else
1858 		{
1859 			device->setSlopeDepthBias(0);
1860 			device->setDepthBias(0);
1861 		}
1862 
1863 		mPolygonOffsetStateDirty = false;
1864 	}
1865 
1866 	if(mSampleStateDirty)
1867 	{
1868 		if(mState.sampleAlphaToCoverageEnabled)
1869 		{
1870 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1871 		}
1872 		else
1873 		{
1874 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1875 		}
1876 
1877 		if(mState.sampleCoverageEnabled)
1878 		{
1879 			unsigned int mask = 0;
1880 			if(mState.sampleCoverageValue != 0)
1881 			{
1882 				int width, height, samples;
1883 				framebuffer->completeness(width, height, samples);
1884 
1885 				float threshold = 0.5f;
1886 
1887 				for(int i = 0; i < samples; i++)
1888 				{
1889 					mask <<= 1;
1890 
1891 					if((i + 1) * mState.sampleCoverageValue >= threshold)
1892 					{
1893 						threshold += 1.0f;
1894 						mask |= 1;
1895 					}
1896 				}
1897 			}
1898 
1899 			if(mState.sampleCoverageInvert)
1900 			{
1901 				mask = ~mask;
1902 			}
1903 
1904 			device->setMultiSampleMask(mask);
1905 		}
1906 		else
1907 		{
1908 			device->setMultiSampleMask(0xFFFFFFFF);
1909 		}
1910 
1911 		mSampleStateDirty = false;
1912 	}
1913 
1914 	if(mDitherStateDirty)
1915 	{
1916 	//	UNIMPLEMENTED();   // FIXME
1917 
1918 		mDitherStateDirty = false;
1919 	}
1920 
1921 	switch(mState.shadeModel)
1922 	{
1923 	default: UNREACHABLE(mState.shadeModel);
1924 	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
1925 	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
1926 	}
1927 
1928 	device->setLightingEnable(lightingEnabled);
1929 	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
1930 
1931 	for(int i = 0; i < MAX_LIGHTS; i++)
1932 	{
1933 		device->setLightEnable(i, light[i].enabled);
1934 		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
1935 		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
1936 		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
1937 		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
1938 
1939 		if(light[i].position.w != 0.0f)
1940 		{
1941 			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
1942 		}
1943 		else   // Directional light
1944 		{
1945 			// Hack: set the position far way
1946 			float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));
1947 			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
1948 		}
1949 	}
1950 
1951 	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
1952 	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
1953 	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
1954 	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
1955 	device->setMaterialShininess(materialShininess);
1956 
1957 	device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
1958 	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
1959 	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
1960 	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
1961 
1962 	device->setProjectionMatrix(projectionStack.current());
1963 	device->setModelMatrix(modelViewStack.current());
1964 	device->setTextureMatrix(0, textureStack0.current());
1965 	device->setTextureMatrix(1, textureStack1.current());
1966 	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);
1967 	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);
1968 	device->setTexGen(0, sw::TEXGEN_NONE);
1969 	device->setTexGen(1, sw::TEXGEN_NONE);
1970 
1971 	device->setAlphaTestEnable(alphaTestEnabled);
1972 	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));
1973 	device->setAlphaReference(alphaTestRef * 0xFF);
1974 
1975 	device->setFogEnable(fogEnabled);
1976 	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));
1977 	device->setFogDensity(fogDensity);
1978 	device->setFogStart(fogStart);
1979 	device->setFogEnd(fogEnd);
1980 
1981 	switch(fogMode)
1982 	{
1983 	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
1984 	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;
1985 	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;
1986 	default: UNREACHABLE(fogMode);
1987 	}
1988 
1989 	device->setColorLogicOpEnabled(colorLogicOpEnabled);
1990 	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));
1991 
1992 	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);
1993 }
1994 
applyVertexBuffer(GLint base,GLint first,GLsizei count)1995 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
1996 {
1997 	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
1998 
1999 	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
2000 	if(err != GL_NO_ERROR)
2001 	{
2002 		return err;
2003 	}
2004 
2005 	device->resetInputStreams(false);
2006 
2007 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2008 	{
2009 		sw::Resource *resource = attributes[i].vertexBuffer;
2010 		const void *buffer = (char*)resource->data() + attributes[i].offset;
2011 
2012 		int stride = attributes[i].stride;
2013 
2014 		buffer = (char*)buffer + stride * base;
2015 
2016 		sw::Stream attribute(resource, buffer, stride);
2017 
2018 		attribute.type = attributes[i].type;
2019 		attribute.count = attributes[i].count;
2020 		attribute.normalized = attributes[i].normalized;
2021 
2022 		device->setInputStream(i, attribute);
2023 	}
2024 
2025 	return GL_NO_ERROR;
2026 }
2027 
2028 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)2029 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
2030 {
2031 	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
2032 
2033 	if(err == GL_NO_ERROR)
2034 	{
2035 		device->setIndexBuffer(indexInfo->indexBuffer);
2036 	}
2037 
2038 	return err;
2039 }
2040 
applyTextures()2041 void Context::applyTextures()
2042 {
2043 	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
2044 	{
2045 		Texture *texture = nullptr;
2046 
2047 		if(textureExternalEnabled[unit])
2048 		{
2049 			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);
2050 		}
2051 		else if(texture2Denabled[unit])
2052 		{
2053 			texture = getSamplerTexture(unit, TEXTURE_2D);
2054 		}
2055 
2056 		if(texture && texture->isSamplerComplete())
2057 		{
2058 			texture->autoGenerateMipmaps();
2059 
2060 			GLenum wrapS = texture->getWrapS();
2061 			GLenum wrapT = texture->getWrapT();
2062 			GLenum minFilter = texture->getMinFilter();
2063 			GLenum magFilter = texture->getMagFilter();
2064 			GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2065 
2066 			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));
2067 			device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));
2068 
2069 			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
2070 			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));
2071 			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);
2072 
2073 			applyTexture(unit, texture);
2074 
2075 			device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));
2076 
2077 			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)
2078 			{
2079 				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs
2080 				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2081 				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp
2082 				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2083 				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc
2084 				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2085 
2086 				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As
2087 				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2088 				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap
2089 				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2090 				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac
2091 				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2092 
2093 				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);
2094 
2095 				switch(mState.textureUnit[unit].environmentMode)
2096 				{
2097 				case GL_REPLACE:
2098 					if(IsAlpha(texFormat))   // GL_ALPHA
2099 					{
2100 						// Cv = Cp, Av = As
2101 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2102 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2103 					}
2104 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2105 					{
2106 						// Cv = Cs, Av = Ap
2107 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2108 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2109 					}
2110 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2111 					{
2112 						// Cv = Cs, Av = As
2113 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2114 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2115 					}
2116 					else UNREACHABLE(texFormat);
2117 					break;
2118 				case GL_MODULATE:
2119 					if(IsAlpha(texFormat))   // GL_ALPHA
2120 					{
2121 						// Cv = Cp, Av = ApAs
2122 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2123 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2124 					}
2125 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2126 					{
2127 						// Cv = CpCs, Av = Ap
2128 						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
2129 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2130 					}
2131 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2132 					{
2133 						// Cv = CpCs, Av = ApAs
2134 						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
2135 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2136 					}
2137 					else UNREACHABLE(texFormat);
2138 					break;
2139 				case GL_DECAL:
2140 					if(texFormat == GL_ALPHA ||
2141 					   texFormat == GL_LUMINANCE ||
2142 					   texFormat == GL_LUMINANCE_ALPHA)
2143 					{
2144 						// undefined   // FIXME: Log
2145 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2146 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2147 					}
2148 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2149 					{
2150 						// Cv = Cs, Av = Ap
2151 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2152 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2153 					}
2154 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2155 					{
2156 						// Cv = Cp(1 - As) + CsAs, Av = Ap
2157 						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2
2158 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2159 					}
2160 					else UNREACHABLE(texFormat);
2161 					break;
2162 				case GL_BLEND:
2163 					if(IsAlpha(texFormat))   // GL_ALPHA
2164 					{
2165 						// Cv = Cp, Av = ApAs
2166 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2167 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2168 					}
2169 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2170 					{
2171 						// Cv = Cp(1 - Cs) + CcCs, Av = Ap
2172 						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
2173 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2174 					}
2175 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2176 					{
2177 						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs
2178 						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
2179 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2180 					}
2181 					else UNREACHABLE(texFormat);
2182 					break;
2183 				case GL_ADD:
2184 					if(IsAlpha(texFormat))   // GL_ALPHA
2185 					{
2186 						// Cv = Cp, Av = ApAs
2187 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2188 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2189 					}
2190 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2191 					{
2192 						// Cv = Cp + Cs, Av = Ap
2193 						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
2194 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2195 					}
2196 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2197 					{
2198 						// Cv = Cp + Cs, Av = ApAs
2199 						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
2200 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2201 					}
2202 					else UNREACHABLE(texFormat);
2203 					break;
2204 				default:
2205 					UNREACHABLE(mState.textureUnit[unit].environmentMode);
2206 				}
2207 			}
2208 			else   // GL_COMBINE
2209 			{
2210 				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));
2211 				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));
2212 				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));
2213 				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));
2214 				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));
2215 				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));
2216 
2217 				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));
2218 
2219 				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));
2220 				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));
2221 				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));
2222 				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));
2223 				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));
2224 				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));
2225 
2226 				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));
2227 			}
2228 		}
2229 		else
2230 		{
2231 			applyTexture(unit, nullptr);
2232 
2233 			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);
2234 			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2235 			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2236 
2237 			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);
2238 			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2239 			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2240 		}
2241 	}
2242 }
2243 
setTextureEnvMode(GLenum texEnvMode)2244 void Context::setTextureEnvMode(GLenum texEnvMode)
2245 {
2246 	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;
2247 }
2248 
setTextureEnvColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)2249 void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2250 {
2251 	mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};
2252 }
2253 
setCombineRGB(GLenum combineRGB)2254 void Context::setCombineRGB(GLenum combineRGB)
2255 {
2256 	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;
2257 }
2258 
setCombineAlpha(GLenum combineAlpha)2259 void Context::setCombineAlpha(GLenum combineAlpha)
2260 {
2261 	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;
2262 }
2263 
setOperand0RGB(GLenum operand)2264 void Context::setOperand0RGB(GLenum operand)
2265 {
2266 	mState.textureUnit[mState.activeSampler].operand0RGB = operand;
2267 }
2268 
setOperand1RGB(GLenum operand)2269 void Context::setOperand1RGB(GLenum operand)
2270 {
2271 	mState.textureUnit[mState.activeSampler].operand1RGB = operand;
2272 }
2273 
setOperand2RGB(GLenum operand)2274 void Context::setOperand2RGB(GLenum operand)
2275 {
2276 	mState.textureUnit[mState.activeSampler].operand2RGB = operand;
2277 }
2278 
setOperand0Alpha(GLenum operand)2279 void Context::setOperand0Alpha(GLenum operand)
2280 {
2281 	mState.textureUnit[mState.activeSampler].operand0Alpha = operand;
2282 }
2283 
setOperand1Alpha(GLenum operand)2284 void Context::setOperand1Alpha(GLenum operand)
2285 {
2286 	mState.textureUnit[mState.activeSampler].operand1Alpha = operand;
2287 }
2288 
setOperand2Alpha(GLenum operand)2289 void Context::setOperand2Alpha(GLenum operand)
2290 {
2291 	mState.textureUnit[mState.activeSampler].operand2Alpha = operand;
2292 }
2293 
setSrc0RGB(GLenum src)2294 void Context::setSrc0RGB(GLenum src)
2295 {
2296 	mState.textureUnit[mState.activeSampler].src0RGB = src;
2297 }
2298 
setSrc1RGB(GLenum src)2299 void Context::setSrc1RGB(GLenum src)
2300 {
2301 	mState.textureUnit[mState.activeSampler].src1RGB = src;
2302 }
2303 
setSrc2RGB(GLenum src)2304 void Context::setSrc2RGB(GLenum src)
2305 {
2306 	mState.textureUnit[mState.activeSampler].src2RGB = src;
2307 }
2308 
setSrc0Alpha(GLenum src)2309 void Context::setSrc0Alpha(GLenum src)
2310 {
2311 	mState.textureUnit[mState.activeSampler].src0Alpha = src;
2312 }
2313 
setSrc1Alpha(GLenum src)2314 void Context::setSrc1Alpha(GLenum src)
2315 {
2316 	mState.textureUnit[mState.activeSampler].src1Alpha = src;
2317 }
2318 
setSrc2Alpha(GLenum src)2319 void Context::setSrc2Alpha(GLenum src)
2320 {
2321 	mState.textureUnit[mState.activeSampler].src2Alpha = src;
2322 }
2323 
applyTexture(int index,Texture * baseTexture)2324 void Context::applyTexture(int index, Texture *baseTexture)
2325 {
2326 	sw::Resource *resource = 0;
2327 
2328 	if(baseTexture)
2329 	{
2330 		resource = baseTexture->getResource();
2331 	}
2332 
2333 	device->setTextureResource(index, resource);
2334 
2335 	if(baseTexture)
2336 	{
2337 		int levelCount = baseTexture->getLevelCount();
2338 
2339 		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
2340 		{
2341 			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2342 
2343 			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2344 			{
2345 				int surfaceLevel = mipmapLevel;
2346 
2347 				if(surfaceLevel < 0)
2348 				{
2349 					surfaceLevel = 0;
2350 				}
2351 				else if(surfaceLevel >= levelCount)
2352 				{
2353 					surfaceLevel = levelCount - 1;
2354 				}
2355 
2356 				egl::Image *surface = texture->getImage(surfaceLevel);
2357 				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2358 			}
2359 		}
2360 		else UNIMPLEMENTED();
2361 	}
2362 	else
2363 	{
2364 		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);
2365 	}
2366 }
2367 
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)2368 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2369                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2370 {
2371 	Framebuffer *framebuffer = getFramebuffer();
2372 	int framebufferWidth, framebufferHeight, framebufferSamples;
2373 
2374 	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES)
2375 	{
2376 		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
2377 	}
2378 
2379 	if(getFramebufferName() != 0 && framebufferSamples != 0)
2380 	{
2381 		return error(GL_INVALID_OPERATION);
2382 	}
2383 
2384 	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
2385 	{
2386 		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
2387 		{
2388 			return error(GL_INVALID_OPERATION);
2389 		}
2390 	}
2391 
2392 	GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);
2393 
2394 	// Sized query sanity check
2395 	if(bufSize)
2396 	{
2397 		int requiredSize = outputPitch * height;
2398 		if(requiredSize > *bufSize)
2399 		{
2400 			return error(GL_INVALID_OPERATION);
2401 		}
2402 	}
2403 
2404 	egl::Image *renderTarget = framebuffer->getRenderTarget();
2405 
2406 	if(!renderTarget)
2407 	{
2408 		return error(GL_OUT_OF_MEMORY);
2409 	}
2410 
2411 	sw::Rect rect = {x, y, x + width, y + height};
2412 	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2413 
2414 	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2415 	unsigned char *dest = (unsigned char*)pixels;
2416 	int inputPitch = (int)renderTarget->getPitch();
2417 
2418 	for(int j = 0; j < rect.y1 - rect.y0; j++)
2419 	{
2420 		unsigned short *dest16 = (unsigned short*)dest;
2421 		unsigned int *dest32 = (unsigned int*)dest;
2422 
2423 		if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
2424 		   format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2425 		{
2426 			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2427 		}
2428 		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2429 				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2430 		{
2431 			for(int i = 0; i < rect.x1 - rect.x0; i++)
2432 			{
2433 				unsigned int argb = *(unsigned int*)(source + 4 * i);
2434 
2435 				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
2436 			}
2437 		}
2438 		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2439 				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2440 		{
2441 			for(int i = 0; i < rect.x1 - rect.x0; i++)
2442 			{
2443 				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2444 
2445 				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
2446 			}
2447 		}
2448 		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2449 				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2450 		{
2451 			for(int i = 0; i < rect.x1 - rect.x0; i++)
2452 			{
2453 				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2454 
2455 				dest32[i] = xrgb | 0xFF000000;
2456 			}
2457 		}
2458 		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2459 				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2460 		{
2461 			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2462 		}
2463 		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
2464 				format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
2465 		{
2466 			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2467 		}
2468 		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
2469 				format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
2470 		{
2471 			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2472 		}
2473 		else
2474 		{
2475 			for(int i = 0; i < rect.x1 - rect.x0; i++)
2476 			{
2477 				float r;
2478 				float g;
2479 				float b;
2480 				float a;
2481 
2482 				switch(renderTarget->getInternalFormat())
2483 				{
2484 				case sw::FORMAT_R5G6B5:
2485 					{
2486 						unsigned short rgb = *(unsigned short*)(source + 2 * i);
2487 
2488 						a = 1.0f;
2489 						b = (rgb & 0x001F) * (1.0f / 0x001F);
2490 						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2491 						r = (rgb & 0xF800) * (1.0f / 0xF800);
2492 					}
2493 					break;
2494 				case sw::FORMAT_A1R5G5B5:
2495 					{
2496 						unsigned short argb = *(unsigned short*)(source + 2 * i);
2497 
2498 						a = (argb & 0x8000) ? 1.0f : 0.0f;
2499 						b = (argb & 0x001F) * (1.0f / 0x001F);
2500 						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2501 						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2502 					}
2503 					break;
2504 				case sw::FORMAT_A8R8G8B8:
2505 					{
2506 						unsigned int argb = *(unsigned int*)(source + 4 * i);
2507 
2508 						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2509 						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2510 						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2511 						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2512 					}
2513 					break;
2514 				case sw::FORMAT_A8B8G8R8:
2515 					{
2516 						unsigned int abgr = *(unsigned int*)(source + 4 * i);
2517 
2518 						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
2519 						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2520 						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2521 						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
2522 					}
2523 					break;
2524 				case sw::FORMAT_X8R8G8B8:
2525 					{
2526 						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2527 
2528 						a = 1.0f;
2529 						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2530 						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2531 						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2532 					}
2533 					break;
2534 				case sw::FORMAT_X8B8G8R8:
2535 					{
2536 						unsigned int xbgr = *(unsigned int*)(source + 4 * i);
2537 
2538 						a = 1.0f;
2539 						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2540 						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2541 						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
2542 					}
2543 					break;
2544 				case sw::FORMAT_A2R10G10B10:
2545 					{
2546 						unsigned int argb = *(unsigned int*)(source + 4 * i);
2547 
2548 						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2549 						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2550 						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2551 						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2552 					}
2553 					break;
2554 				default:
2555 					UNIMPLEMENTED();   // FIXME
2556 					UNREACHABLE(renderTarget->getInternalFormat());
2557 				}
2558 
2559 				switch(format)
2560 				{
2561 				case GL_RGBA:
2562 					switch(type)
2563 					{
2564 					case GL_UNSIGNED_BYTE:
2565 						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
2566 						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2567 						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
2568 						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2569 						break;
2570 					default: UNREACHABLE(type);
2571 					}
2572 					break;
2573 				case GL_BGRA_EXT:
2574 					switch(type)
2575 					{
2576 					case GL_UNSIGNED_BYTE:
2577 						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
2578 						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2579 						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
2580 						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2581 						break;
2582 					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
2583 						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2584 						// this type is packed as follows:
2585 						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2586 						//  --------------------------------------------------------------------------------
2587 						// |       4th         |        3rd         |        2nd        |   1st component   |
2588 						//  --------------------------------------------------------------------------------
2589 						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2590 						dest16[i] =
2591 							((unsigned short)(15 * a + 0.5f) << 12)|
2592 							((unsigned short)(15 * r + 0.5f) << 8) |
2593 							((unsigned short)(15 * g + 0.5f) << 4) |
2594 							((unsigned short)(15 * b + 0.5f) << 0);
2595 						break;
2596 					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
2597 						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2598 						// this type is packed as follows:
2599 						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2600 						//  --------------------------------------------------------------------------------
2601 						// | 4th |          3rd           |           2nd          |      1st component     |
2602 						//  --------------------------------------------------------------------------------
2603 						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2604 						dest16[i] =
2605 							((unsigned short)(     a + 0.5f) << 15) |
2606 							((unsigned short)(31 * r + 0.5f) << 10) |
2607 							((unsigned short)(31 * g + 0.5f) << 5) |
2608 							((unsigned short)(31 * b + 0.5f) << 0);
2609 						break;
2610 					default: UNREACHABLE(type);
2611 					}
2612 					break;
2613 				case GL_RGB:
2614 					switch(type)
2615 					{
2616 					case GL_UNSIGNED_SHORT_5_6_5:
2617 						dest16[i] =
2618 							((unsigned short)(31 * b + 0.5f) << 0) |
2619 							((unsigned short)(63 * g + 0.5f) << 5) |
2620 							((unsigned short)(31 * r + 0.5f) << 11);
2621 						break;
2622 					default: UNREACHABLE(type);
2623 					}
2624 					break;
2625 				default: UNREACHABLE(format);
2626 				}
2627 			}
2628 		}
2629 
2630 		source += inputPitch;
2631 		dest += outputPitch;
2632 	}
2633 
2634 	renderTarget->unlock();
2635 	renderTarget->release();
2636 }
2637 
clear(GLbitfield mask)2638 void Context::clear(GLbitfield mask)
2639 {
2640 	Framebuffer *framebuffer = getFramebuffer();
2641 
2642 	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
2643 	{
2644 		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
2645 	}
2646 
2647 	if(!applyRenderTarget())
2648 	{
2649 		return;
2650 	}
2651 
2652 	float depth = clamp01(mState.depthClearValue);
2653 	int stencil = mState.stencilClearValue & 0x000000FF;
2654 
2655 	if(mask & GL_COLOR_BUFFER_BIT)
2656 	{
2657 		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2658 		                        (mState.colorMaskGreen ? 0x2 : 0) |
2659 		                        (mState.colorMaskBlue ? 0x4 : 0) |
2660 		                        (mState.colorMaskAlpha ? 0x8 : 0);
2661 
2662 		if(rgbaMask != 0)
2663 		{
2664 			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
2665 		}
2666 	}
2667 
2668 	if(mask & GL_DEPTH_BUFFER_BIT)
2669 	{
2670 		if(mState.depthMask != 0)
2671 		{
2672 			device->clearDepth(depth);
2673 		}
2674 	}
2675 
2676 	if(mask & GL_STENCIL_BUFFER_BIT)
2677 	{
2678 		if(mState.stencilWritemask != 0)
2679 		{
2680 			device->clearStencil(stencil, mState.stencilWritemask);
2681 		}
2682 	}
2683 }
2684 
drawArrays(GLenum mode,GLint first,GLsizei count)2685 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2686 {
2687 	sw::DrawType primitiveType;
2688 	int primitiveCount;
2689 
2690 	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
2691 		return error(GL_INVALID_ENUM);
2692 
2693 	if(primitiveCount <= 0)
2694 	{
2695 		return;
2696 	}
2697 
2698 	if(!applyRenderTarget())
2699 	{
2700 		return;
2701 	}
2702 
2703 	applyState(mode);
2704 
2705 	GLenum err = applyVertexBuffer(0, first, count);
2706 	if(err != GL_NO_ERROR)
2707 	{
2708 		return error(err);
2709 	}
2710 
2711 	applyTextures();
2712 
2713 	if(!cullSkipsDraw(mode))
2714 	{
2715 		device->drawPrimitive(primitiveType, primitiveCount);
2716 	}
2717 }
2718 
drawElements(GLenum mode,GLsizei count,GLenum type,const void * indices)2719 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2720 {
2721 	if(!indices && !mState.elementArrayBuffer)
2722 	{
2723 		return error(GL_INVALID_OPERATION);
2724 	}
2725 
2726 	sw::DrawType primitiveType;
2727 	int primitiveCount;
2728 
2729 	if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
2730 		return error(GL_INVALID_ENUM);
2731 
2732 	if(primitiveCount <= 0)
2733 	{
2734 		return;
2735 	}
2736 
2737 	if(!applyRenderTarget())
2738 	{
2739 		return;
2740 	}
2741 
2742 	applyState(mode);
2743 
2744 	TranslatedIndexData indexInfo;
2745 	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2746 	if(err != GL_NO_ERROR)
2747 	{
2748 		return error(err);
2749 	}
2750 
2751 	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2752 	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2753 	if(err != GL_NO_ERROR)
2754 	{
2755 		return error(err);
2756 	}
2757 
2758 	applyTextures();
2759 
2760 	if(!cullSkipsDraw(mode))
2761 	{
2762 		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
2763 	}
2764 }
2765 
drawTexture(GLfloat x,GLfloat y,GLfloat z,GLfloat width,GLfloat height)2766 void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
2767 {
2768 	es1::Framebuffer *framebuffer = getFramebuffer();
2769 	es1::Renderbuffer *renderbuffer = framebuffer->getColorbuffer();
2770 	float targetWidth = (float)renderbuffer->getWidth();
2771 	float targetHeight = (float)renderbuffer->getHeight();
2772 	float x0 = 2.0f * x / targetWidth - 1.0f;
2773 	float y0 = 2.0f * y / targetHeight - 1.0f;
2774 	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;
2775 	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;
2776 	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);
2777 
2778 	float vertices[][3] = {{x0, y0, Zw},
2779 	                       {x0, y1, Zw},
2780 	                       {x1, y0, Zw},
2781 	                       {x1, y1, Zw}};
2782 
2783 	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented
2784 	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);
2785 	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);
2786 	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);
2787 	int Ucr = texture->getCropRectU();
2788 	int Vcr = texture->getCropRectV();
2789 	int Wcr = texture->getCropRectW();
2790 	int Hcr = texture->getCropRectH();
2791 
2792 	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},
2793 	                        {Ucr / textureWidth, (Vcr + Hcr) / textureHeight},
2794 	                        {(Ucr + Wcr) / textureWidth, Vcr / textureHeight},
2795 	                        {(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};
2796 
2797 	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];
2798 	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];
2799 	gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;
2800 	mState.arrayBuffer = nullptr;
2801 
2802 	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);
2803 	glEnableClientState(GL_VERTEX_ARRAY);
2804 	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);
2805 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2806 
2807 	sw::Matrix P = projectionStack.current();
2808 	sw::Matrix M = modelViewStack.current();
2809 	sw::Matrix T = textureStack0.current();
2810 
2811 	projectionStack.identity();
2812 	modelViewStack.identity();
2813 	textureStack0.identity();
2814 
2815 	drawArrays(GL_TRIANGLE_STRIP, 0, 4);
2816 
2817 	// Restore state
2818 	mState.vertexAttribute[sw::Position] = oldPositionAttribute;
2819 	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;
2820 	mState.arrayBuffer = oldArrayBuffer;
2821 	oldArrayBuffer = nullptr;
2822 	oldPositionAttribute.mBoundBuffer = nullptr;
2823 	oldTexCoord0Attribute.mBoundBuffer = nullptr;
2824 	textureStack0.load(T);
2825 	modelViewStack.load(M);
2826 	projectionStack.load(P);
2827 }
2828 
finish()2829 void Context::finish()
2830 {
2831 	device->finish();
2832 }
2833 
flush()2834 void Context::flush()
2835 {
2836 	// We don't queue anything without processing it as fast as possible
2837 }
2838 
recordInvalidEnum()2839 void Context::recordInvalidEnum()
2840 {
2841 	mInvalidEnum = true;
2842 }
2843 
recordInvalidValue()2844 void Context::recordInvalidValue()
2845 {
2846 	mInvalidValue = true;
2847 }
2848 
recordInvalidOperation()2849 void Context::recordInvalidOperation()
2850 {
2851 	mInvalidOperation = true;
2852 }
2853 
recordOutOfMemory()2854 void Context::recordOutOfMemory()
2855 {
2856 	mOutOfMemory = true;
2857 }
2858 
recordInvalidFramebufferOperation()2859 void Context::recordInvalidFramebufferOperation()
2860 {
2861 	mInvalidFramebufferOperation = true;
2862 }
2863 
recordMatrixStackOverflow()2864 void Context::recordMatrixStackOverflow()
2865 {
2866 	mMatrixStackOverflow = true;
2867 }
2868 
recordMatrixStackUnderflow()2869 void Context::recordMatrixStackUnderflow()
2870 {
2871 	mMatrixStackUnderflow = true;
2872 }
2873 
2874 // Get one of the recorded errors and clear its flag, if any.
2875 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()2876 GLenum Context::getError()
2877 {
2878 	if(mInvalidEnum)
2879 	{
2880 		mInvalidEnum = false;
2881 
2882 		return GL_INVALID_ENUM;
2883 	}
2884 
2885 	if(mInvalidValue)
2886 	{
2887 		mInvalidValue = false;
2888 
2889 		return GL_INVALID_VALUE;
2890 	}
2891 
2892 	if(mInvalidOperation)
2893 	{
2894 		mInvalidOperation = false;
2895 
2896 		return GL_INVALID_OPERATION;
2897 	}
2898 
2899 	if(mOutOfMemory)
2900 	{
2901 		mOutOfMemory = false;
2902 
2903 		return GL_OUT_OF_MEMORY;
2904 	}
2905 
2906 	if(mInvalidFramebufferOperation)
2907 	{
2908 		mInvalidFramebufferOperation = false;
2909 
2910 		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2911 	}
2912 
2913 	if(mMatrixStackOverflow)
2914 	{
2915 		mMatrixStackOverflow = false;
2916 
2917 		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2918 	}
2919 
2920 	if(mMatrixStackUnderflow)
2921 	{
2922 		mMatrixStackUnderflow = false;
2923 
2924 		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2925 	}
2926 
2927 	return GL_NO_ERROR;
2928 }
2929 
getSupportedMultisampleCount(int requested)2930 int Context::getSupportedMultisampleCount(int requested)
2931 {
2932 	int supported = 0;
2933 
2934 	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
2935 	{
2936 		if(supported >= requested)
2937 		{
2938 			return supported;
2939 		}
2940 
2941 		supported = multisampleCount[i];
2942 	}
2943 
2944 	return supported;
2945 }
2946 
detachBuffer(GLuint buffer)2947 void Context::detachBuffer(GLuint buffer)
2948 {
2949 	// [OpenGL ES 2.0.24] section 2.9 page 22:
2950 	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
2951 	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
2952 
2953 	if(mState.arrayBuffer.name() == buffer)
2954 	{
2955 		mState.arrayBuffer = nullptr;
2956 	}
2957 
2958 	if(mState.elementArrayBuffer.name() == buffer)
2959 	{
2960 		mState.elementArrayBuffer = nullptr;
2961 	}
2962 
2963 	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2964 	{
2965 		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
2966 		{
2967 			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
2968 		}
2969 	}
2970 }
2971 
detachTexture(GLuint texture)2972 void Context::detachTexture(GLuint texture)
2973 {
2974 	// [OpenGL ES 2.0.24] section 3.8 page 84:
2975 	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2976 	// rebound to texture object zero
2977 
2978 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2979 	{
2980 		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
2981 		{
2982 			if(mState.samplerTexture[type][sampler].name() == texture)
2983 			{
2984 				mState.samplerTexture[type][sampler] = nullptr;
2985 			}
2986 		}
2987 	}
2988 
2989 	// [OpenGL ES 2.0.24] section 4.4 page 112:
2990 	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2991 	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2992 	// image was attached in the currently bound framebuffer.
2993 
2994 	Framebuffer *framebuffer = getFramebuffer();
2995 
2996 	if(framebuffer)
2997 	{
2998 		framebuffer->detachTexture(texture);
2999 	}
3000 }
3001 
detachFramebuffer(GLuint framebuffer)3002 void Context::detachFramebuffer(GLuint framebuffer)
3003 {
3004 	// [OpenGL ES 2.0.24] section 4.4 page 107:
3005 	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3006 	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3007 
3008 	if(mState.framebuffer == framebuffer)
3009 	{
3010 		bindFramebuffer(0);
3011 	}
3012 }
3013 
detachRenderbuffer(GLuint renderbuffer)3014 void Context::detachRenderbuffer(GLuint renderbuffer)
3015 {
3016 	// [OpenGL ES 2.0.24] section 4.4 page 109:
3017 	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3018 	// had been executed with the target RENDERBUFFER and name of zero.
3019 
3020 	if(mState.renderbuffer.name() == renderbuffer)
3021 	{
3022 		bindRenderbuffer(0);
3023 	}
3024 
3025 	// [OpenGL ES 2.0.24] section 4.4 page 111:
3026 	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3027 	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3028 	// point to which this image was attached in the currently bound framebuffer.
3029 
3030 	Framebuffer *framebuffer = getFramebuffer();
3031 
3032 	if(framebuffer)
3033 	{
3034 		framebuffer->detachRenderbuffer(renderbuffer);
3035 	}
3036 }
3037 
cullSkipsDraw(GLenum drawMode)3038 bool Context::cullSkipsDraw(GLenum drawMode)
3039 {
3040 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3041 }
3042 
isTriangleMode(GLenum drawMode)3043 bool Context::isTriangleMode(GLenum drawMode)
3044 {
3045 	switch(drawMode)
3046 	{
3047 	case GL_TRIANGLES:
3048 	case GL_TRIANGLE_FAN:
3049 	case GL_TRIANGLE_STRIP:
3050 		return true;
3051 	case GL_POINTS:
3052 	case GL_LINES:
3053 	case GL_LINE_LOOP:
3054 	case GL_LINE_STRIP:
3055 		return false;
3056 	default: UNREACHABLE(drawMode);
3057 	}
3058 
3059 	return false;
3060 }
3061 
setVertexAttrib(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)3062 void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3063 {
3064 	ASSERT(index < MAX_VERTEX_ATTRIBS);
3065 
3066 	mState.vertexAttribute[index].mCurrentValue[0] = x;
3067 	mState.vertexAttribute[index].mCurrentValue[1] = y;
3068 	mState.vertexAttribute[index].mCurrentValue[2] = z;
3069 	mState.vertexAttribute[index].mCurrentValue[3] = w;
3070 
3071 	mVertexDataManager->dirtyCurrentValue(index);
3072 }
3073 
bindTexImage(egl::Surface * surface)3074 void Context::bindTexImage(egl::Surface *surface)
3075 {
3076 	es1::Texture2D *textureObject = getTexture2D();
3077 
3078 	if(textureObject)
3079 	{
3080 		textureObject->bindTexImage(surface);
3081 	}
3082 }
3083 
validateSharedImage(EGLenum target,GLuint name,GLuint textureLevel)3084 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3085 {
3086 	switch(target)
3087 	{
3088 	case EGL_GL_TEXTURE_2D_KHR:
3089 		break;
3090 	case EGL_GL_RENDERBUFFER_KHR:
3091 		break;
3092 	default:
3093 		return EGL_BAD_PARAMETER;
3094 	}
3095 
3096 	if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
3097 	{
3098 		return EGL_BAD_MATCH;
3099 	}
3100 
3101 	if(target == EGL_GL_TEXTURE_2D_KHR)
3102 	{
3103 		Texture *texture = getTexture(name);
3104 
3105 		if(!texture || texture->getTarget() != GL_TEXTURE_2D)
3106 		{
3107 			return EGL_BAD_PARAMETER;
3108 		}
3109 
3110 		if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
3111 		{
3112 			return EGL_BAD_ACCESS;
3113 		}
3114 
3115 		if(textureLevel != 0 && !texture->isSamplerComplete())
3116 		{
3117 			return EGL_BAD_PARAMETER;
3118 		}
3119 
3120 		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
3121 		{
3122 			return EGL_BAD_PARAMETER;
3123 		}
3124 	}
3125 	else if(target == EGL_GL_RENDERBUFFER_KHR)
3126 	{
3127 		Renderbuffer *renderbuffer = getRenderbuffer(name);
3128 
3129 		if(!renderbuffer)
3130 		{
3131 			return EGL_BAD_PARAMETER;
3132 		}
3133 
3134 		if(renderbuffer->isShared())   // Already an EGLImage sibling
3135 		{
3136 			return EGL_BAD_ACCESS;
3137 		}
3138 	}
3139 	else UNREACHABLE(target);
3140 
3141 	return EGL_SUCCESS;
3142 }
3143 
createSharedImage(EGLenum target,GLuint name,GLuint textureLevel)3144 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3145 {
3146 	if(target == EGL_GL_TEXTURE_2D_KHR)
3147 	{
3148 		es1::Texture *texture = getTexture(name);
3149 
3150 		return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
3151 	}
3152 	else if(target == EGL_GL_RENDERBUFFER_KHR)
3153 	{
3154 		es1::Renderbuffer *renderbuffer = getRenderbuffer(name);
3155 
3156 		return renderbuffer->createSharedImage();
3157 	}
3158 	else UNREACHABLE(target);
3159 
3160 	return 0;
3161 }
3162 
getDevice()3163 Device *Context::getDevice()
3164 {
3165 	return device;
3166 }
3167 
setMatrixMode(GLenum mode)3168 void Context::setMatrixMode(GLenum mode)
3169 {
3170 	matrixMode = mode;
3171 }
3172 
currentMatrixStack()3173 sw::MatrixStack &Context::currentMatrixStack()
3174 {
3175 	switch(matrixMode)
3176 	{
3177 	case GL_MODELVIEW:
3178 		return modelViewStack;
3179 	case GL_PROJECTION:
3180 		return projectionStack;
3181 	case GL_TEXTURE:
3182 		switch(mState.activeSampler)
3183 		{
3184 		case 0: return textureStack0;
3185 		case 1: return textureStack1;
3186 		}
3187 		break;
3188 	}
3189 
3190 	UNREACHABLE(matrixMode);
3191 	return textureStack0;
3192 }
3193 
loadIdentity()3194 void Context::loadIdentity()
3195 {
3196 	currentMatrixStack().identity();
3197 }
3198 
load(const GLfloat * m)3199 void Context::load(const GLfloat *m)
3200 {
3201 	currentMatrixStack().load(m);
3202 }
3203 
pushMatrix()3204 void Context::pushMatrix()
3205 {
3206 	if(!currentMatrixStack().push())
3207 	{
3208 		return error(GL_STACK_OVERFLOW);
3209 	}
3210 }
3211 
popMatrix()3212 void Context::popMatrix()
3213 {
3214 	if(!currentMatrixStack().pop())
3215 	{
3216 		return error(GL_STACK_OVERFLOW);
3217 	}
3218 }
3219 
rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3220 void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3221 {
3222 	currentMatrixStack().rotate(angle, x, y, z);
3223 }
3224 
translate(GLfloat x,GLfloat y,GLfloat z)3225 void Context::translate(GLfloat x, GLfloat y, GLfloat z)
3226 {
3227 	currentMatrixStack().translate(x, y, z);
3228 }
3229 
scale(GLfloat x,GLfloat y,GLfloat z)3230 void Context::scale(GLfloat x, GLfloat y, GLfloat z)
3231 {
3232 	currentMatrixStack().scale(x, y, z);
3233 }
3234 
multiply(const GLfloat * m)3235 void Context::multiply(const GLfloat *m)
3236 {
3237 	currentMatrixStack().multiply(m);
3238 }
3239 
frustum(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3240 void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3241 {
3242 	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
3243 }
3244 
ortho(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3245 void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3246 {
3247 	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
3248 }
3249 
setClipPlane(int index,const float plane[4])3250 void Context::setClipPlane(int index, const float plane[4])
3251 {
3252 	sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);
3253 	device->setClipPlane(index, &clipPlane.A);
3254 }
3255 
setClipPlaneEnabled(int index,bool enable)3256 void Context::setClipPlaneEnabled(int index, bool enable)
3257 {
3258 	clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);
3259 	device->setClipFlags(clipFlags);
3260 }
3261 
isClipPlaneEnabled(int index) const3262 bool Context::isClipPlaneEnabled(int index) const
3263 {
3264 	return (clipFlags & (1 << index)) != 0;
3265 }
3266 
setColorLogicOpEnabled(bool enable)3267 void Context::setColorLogicOpEnabled(bool enable)
3268 {
3269 	colorLogicOpEnabled = enable;
3270 }
3271 
isColorLogicOpEnabled() const3272 bool Context::isColorLogicOpEnabled() const
3273 {
3274 	return colorLogicOpEnabled;
3275 }
3276 
setLogicalOperation(GLenum logicOp)3277 void Context::setLogicalOperation(GLenum logicOp)
3278 {
3279 	logicalOperation = logicOp;
3280 }
3281 
setLineSmoothEnabled(bool enable)3282 void Context::setLineSmoothEnabled(bool enable)
3283 {
3284 	lineSmoothEnabled = enable;
3285 }
3286 
isLineSmoothEnabled() const3287 bool Context::isLineSmoothEnabled() const
3288 {
3289 	return lineSmoothEnabled;
3290 }
3291 
setColorMaterialEnabled(bool enable)3292 void Context::setColorMaterialEnabled(bool enable)
3293 {
3294 	colorMaterialEnabled = enable;
3295 }
3296 
isColorMaterialEnabled() const3297 bool Context::isColorMaterialEnabled() const
3298 {
3299 	return colorMaterialEnabled;
3300 }
3301 
setNormalizeEnabled(bool enable)3302 void Context::setNormalizeEnabled(bool enable)
3303 {
3304 	normalizeEnabled = enable;
3305 }
3306 
isNormalizeEnabled() const3307 bool Context::isNormalizeEnabled() const
3308 {
3309 	return normalizeEnabled;
3310 }
3311 
setRescaleNormalEnabled(bool enable)3312 void Context::setRescaleNormalEnabled(bool enable)
3313 {
3314 	rescaleNormalEnabled = enable;
3315 }
3316 
isRescaleNormalEnabled() const3317 bool Context::isRescaleNormalEnabled() const
3318 {
3319 	return rescaleNormalEnabled;
3320 }
3321 
setVertexArrayEnabled(bool enable)3322 void Context::setVertexArrayEnabled(bool enable)
3323 {
3324 	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;
3325 }
3326 
isVertexArrayEnabled() const3327 bool Context::isVertexArrayEnabled() const
3328 {
3329 	return mState.vertexAttribute[sw::Position].mArrayEnabled;
3330 }
3331 
setNormalArrayEnabled(bool enable)3332 void Context::setNormalArrayEnabled(bool enable)
3333 {
3334 	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;
3335 }
3336 
isNormalArrayEnabled() const3337 bool Context::isNormalArrayEnabled() const
3338 {
3339 	return mState.vertexAttribute[sw::Normal].mArrayEnabled;
3340 }
3341 
setColorArrayEnabled(bool enable)3342 void Context::setColorArrayEnabled(bool enable)
3343 {
3344 	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;
3345 }
3346 
isColorArrayEnabled() const3347 bool Context::isColorArrayEnabled() const
3348 {
3349 	return mState.vertexAttribute[sw::Color0].mArrayEnabled;
3350 }
3351 
setPointSizeArrayEnabled(bool enable)3352 void Context::setPointSizeArrayEnabled(bool enable)
3353 {
3354 	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;
3355 }
3356 
isPointSizeArrayEnabled() const3357 bool Context::isPointSizeArrayEnabled() const
3358 {
3359 	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;
3360 }
3361 
setTextureCoordArrayEnabled(bool enable)3362 void Context::setTextureCoordArrayEnabled(bool enable)
3363 {
3364 	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;
3365 }
3366 
isTextureCoordArrayEnabled() const3367 bool Context::isTextureCoordArrayEnabled() const
3368 {
3369 	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;
3370 }
3371 
setMultisampleEnabled(bool enable)3372 void Context::setMultisampleEnabled(bool enable)
3373 {
3374 	multisampleEnabled = enable;
3375 }
3376 
isMultisampleEnabled() const3377 bool Context::isMultisampleEnabled() const
3378 {
3379 	return multisampleEnabled;
3380 }
3381 
setSampleAlphaToOneEnabled(bool enable)3382 void Context::setSampleAlphaToOneEnabled(bool enable)
3383 {
3384 	sampleAlphaToOneEnabled = enable;
3385 }
3386 
isSampleAlphaToOneEnabled() const3387 bool Context::isSampleAlphaToOneEnabled() const
3388 {
3389 	return sampleAlphaToOneEnabled;
3390 }
3391 
setPointSpriteEnabled(bool enable)3392 void Context::setPointSpriteEnabled(bool enable)
3393 {
3394 	pointSpriteEnabled = enable;
3395 }
3396 
isPointSpriteEnabled() const3397 bool Context::isPointSpriteEnabled() const
3398 {
3399 	return pointSpriteEnabled;
3400 }
3401 
setPointSmoothEnabled(bool enable)3402 void Context::setPointSmoothEnabled(bool enable)
3403 {
3404 	pointSmoothEnabled = enable;
3405 }
3406 
isPointSmoothEnabled() const3407 bool Context::isPointSmoothEnabled() const
3408 {
3409 	return pointSmoothEnabled;
3410 }
3411 
setPointSizeMin(float min)3412 void Context::setPointSizeMin(float min)
3413 {
3414 	pointSizeMin = min;
3415 }
3416 
setPointSizeMax(float max)3417 void Context::setPointSizeMax(float max)
3418 {
3419 	pointSizeMax = max;
3420 }
3421 
setPointDistanceAttenuation(float a,float b,float c)3422 void Context::setPointDistanceAttenuation(float a, float b, float c)
3423 {
3424 	pointDistanceAttenuation = {a, b, c};
3425 }
3426 
setPointFadeThresholdSize(float threshold)3427 void Context::setPointFadeThresholdSize(float threshold)
3428 {
3429 	pointFadeThresholdSize = threshold;
3430 }
3431 
clientActiveTexture(GLenum texture)3432 void Context::clientActiveTexture(GLenum texture)
3433 {
3434 	clientTexture = texture;
3435 }
3436 
getClientActiveTexture() const3437 GLenum Context::getClientActiveTexture() const
3438 {
3439 	return clientTexture;
3440 }
3441 
getActiveTexture() const3442 unsigned int Context::getActiveTexture() const
3443 {
3444 	return mState.activeSampler;
3445 }
3446 
3447 }
3448 
es1CreateContext(const egl::Config * config,const egl::Context * shareContext)3449 egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)
3450 {
3451 	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext
3452 	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));
3453 }
3454