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