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