• 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 gl::Context class, managing all GL state and performing
16 // rendering operations.
17 
18 #include "Context.h"
19 
20 #include "main.h"
21 #include "mathutil.h"
22 #include "utilities.h"
23 #include "ResourceManager.h"
24 #include "Buffer.h"
25 #include "Fence.h"
26 #include "Framebuffer.h"
27 #include "Program.h"
28 #include "Query.h"
29 #include "Renderbuffer.h"
30 #include "Shader.h"
31 #include "Texture.h"
32 #include "VertexDataManager.h"
33 #include "IndexDataManager.h"
34 #include "Display.h"
35 #include "Surface.h"
36 #include "Common/Half.hpp"
37 
38 #define _GDI32_
39 #include <windows.h>
40 #include <GL/GL.h>
41 #include <GL/glext.h>
42 
43 namespace gl
44 {
Context(const Context * shareContext)45 Context::Context(const Context *shareContext)
46 	: modelView(32),
47 	  projection(2)
48 {
49 	sw::Context *context = new sw::Context();
50 	device = new gl::Device(context);
51 
52 	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
53 
54 	mState.depthClearValue = 1.0f;
55 	mState.stencilClearValue = 0;
56 
57 	mState.cullFaceEnabled = false;
58 	mState.cullMode = GL_BACK;
59 	mState.frontFace = GL_CCW;
60 	mState.depthTestEnabled = false;
61 	mState.depthFunc = GL_LESS;
62 	mState.blendEnabled = false;
63 	mState.sourceBlendRGB = GL_ONE;
64 	mState.sourceBlendAlpha = GL_ONE;
65 	mState.destBlendRGB = GL_ZERO;
66 	mState.destBlendAlpha = GL_ZERO;
67 	mState.blendEquationRGB = GL_FUNC_ADD;
68 	mState.blendEquationAlpha = GL_FUNC_ADD;
69 	mState.blendColor.red = 0;
70 	mState.blendColor.green = 0;
71 	mState.blendColor.blue = 0;
72 	mState.blendColor.alpha = 0;
73 	mState.stencilTestEnabled = false;
74 	mState.stencilFunc = GL_ALWAYS;
75 	mState.stencilRef = 0;
76 	mState.stencilMask = -1;
77 	mState.stencilWritemask = -1;
78 	mState.stencilBackFunc = GL_ALWAYS;
79 	mState.stencilBackRef = 0;
80 	mState.stencilBackMask = - 1;
81 	mState.stencilBackWritemask = -1;
82 	mState.stencilFail = GL_KEEP;
83 	mState.stencilPassDepthFail = GL_KEEP;
84 	mState.stencilPassDepthPass = GL_KEEP;
85 	mState.stencilBackFail = GL_KEEP;
86 	mState.stencilBackPassDepthFail = GL_KEEP;
87 	mState.stencilBackPassDepthPass = GL_KEEP;
88 	mState.polygonOffsetFillEnabled = false;
89 	mState.polygonOffsetFactor = 0.0f;
90 	mState.polygonOffsetUnits = 0.0f;
91 	mState.sampleAlphaToCoverageEnabled = false;
92 	mState.sampleCoverageEnabled = false;
93 	mState.sampleCoverageValue = 1.0f;
94 	mState.sampleCoverageInvert = false;
95 	mState.scissorTestEnabled = false;
96 	mState.ditherEnabled = true;
97 	mState.generateMipmapHint = GL_DONT_CARE;
98 	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
99 	mState.colorLogicOpEnabled = false;
100 	mState.logicalOperation = GL_COPY;
101 
102 	mState.lineWidth = 1.0f;
103 
104 	mState.viewportX = 0;
105 	mState.viewportY = 0;
106 	mState.viewportWidth = 0;
107 	mState.viewportHeight = 0;
108 	mState.zNear = 0.0f;
109 	mState.zFar = 1.0f;
110 
111 	mState.scissorX = 0;
112 	mState.scissorY = 0;
113 	mState.scissorWidth = 0;
114 	mState.scissorHeight = 0;
115 
116 	mState.colorMaskRed = true;
117 	mState.colorMaskGreen = true;
118 	mState.colorMaskBlue = true;
119 	mState.colorMaskAlpha = true;
120 	mState.depthMask = true;
121 
122 	if(shareContext)
123 	{
124 		mResourceManager = shareContext->mResourceManager;
125 		mResourceManager->addRef();
126 	}
127 	else
128 	{
129 		mResourceManager = new ResourceManager();
130 	}
131 
132 	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
133 	// and cube map texture state vectors respectively associated with them.
134 	// In order that access to these initial textures not be lost, they are treated as texture
135 	// objects all of whose names are 0.
136 
137 	mTexture2DZero = new Texture2D(0);
138 	mProxyTexture2DZero = new Texture2D(0);
139 	mTextureCubeMapZero = new TextureCubeMap(0);
140 
141 	mState.activeSampler = 0;
142 	bindArrayBuffer(0);
143 	bindElementArrayBuffer(0);
144 	bindTextureCubeMap(0);
145 	bindTexture2D(0);
146 	bindReadFramebuffer(0);
147 	bindDrawFramebuffer(0);
148 	bindRenderbuffer(0);
149 
150 	mState.currentProgram = 0;
151 
152 	mState.packAlignment = 4;
153 	mState.unpackAlignment = 4;
154 
155 	mVertexDataManager = nullptr;
156 	mIndexDataManager = nullptr;
157 
158 	mInvalidEnum = false;
159 	mInvalidValue = false;
160 	mInvalidOperation = false;
161 	mOutOfMemory = false;
162 	mInvalidFramebufferOperation = false;
163 
164 	mHasBeenCurrent = false;
165 
166 	markAllStateDirty();
167 
168 	matrixMode = GL_MODELVIEW;
169 
170 	listMode = 0;
171 	//memset(displayList, 0, sizeof(displayList));
172 	listIndex = 0;
173 	list = 0;
174 	firstFreeIndex = 1;
175 
176 	clientTexture = GL_TEXTURE0;
177 
178 	drawing = false;
179 	drawMode = 0;   // FIXME
180 
181 	mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f;
182 	mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f;
183 	mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f;
184 	mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f;
185 	mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f;
186 	mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f;
187 	mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f;
188 	mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f;
189 	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f;
190 	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f;
191 	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f;
192 	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f;
193 	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f;
194 	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f;
195 	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f;
196 	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f;
197 
198 	for(int i = 0; i < 8; i++)
199 	{
200 		envEnable[i] = true;
201 	}
202 }
203 
~Context()204 Context::~Context()
205 {
206 	if(mState.currentProgram != 0)
207 	{
208 		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
209 		if(programObject)
210 		{
211 			programObject->release();
212 		}
213 		mState.currentProgram = 0;
214 	}
215 
216 	while(!mFramebufferNameSpace.empty())
217 	{
218 		deleteFramebuffer(mFramebufferNameSpace.firstName());
219 	}
220 
221 	while(!mFenceNameSpace.empty())
222 	{
223 		deleteFence(mFenceNameSpace.firstName());
224 	}
225 
226 	while(!mQueryNameSpace.empty())
227 	{
228 		deleteQuery(mQueryNameSpace.firstName());
229 	}
230 
231 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
232 	{
233 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
234 		{
235 			mState.samplerTexture[type][sampler] = nullptr;
236 		}
237 	}
238 
239 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
240 	{
241 		mState.vertexAttribute[i].mBoundBuffer = nullptr;
242 	}
243 
244 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
245 	{
246 		mState.activeQuery[i] = nullptr;
247 	}
248 
249 	mState.arrayBuffer = nullptr;
250 	mState.elementArrayBuffer = nullptr;
251 	mState.renderbuffer = nullptr;
252 
253 	mTexture2DZero = nullptr;
254 	mProxyTexture2DZero = nullptr;
255 	mTextureCubeMapZero = nullptr;
256 
257 	delete mVertexDataManager;
258 	delete mIndexDataManager;
259 
260 	mResourceManager->release();
261 	delete device;
262 }
263 
makeCurrent(Surface * surface)264 void Context::makeCurrent(Surface *surface)
265 {
266 	if(!mHasBeenCurrent)
267 	{
268 		mVertexDataManager = new VertexDataManager(this);
269 		mIndexDataManager = new IndexDataManager();
270 
271 		mState.viewportX = 0;
272 		mState.viewportY = 0;
273 		mState.viewportWidth = surface->getWidth();
274 		mState.viewportHeight = surface->getHeight();
275 
276 		mState.scissorX = 0;
277 		mState.scissorY = 0;
278 		mState.scissorWidth = surface->getWidth();
279 		mState.scissorHeight = surface->getHeight();
280 
281 		mHasBeenCurrent = true;
282 	}
283 
284 	// Wrap the existing resources into GL objects and assign them to the '0' names
285 	Image *defaultRenderTarget = surface->getRenderTarget();
286 	Image *depthStencil = surface->getDepthStencil();
287 
288 	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
289 	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
290 	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
291 
292 	setFramebufferZero(framebufferZero);
293 
294 	if(defaultRenderTarget)
295 	{
296 		defaultRenderTarget->release();
297 	}
298 
299 	if(depthStencil)
300 	{
301 		depthStencil->release();
302 	}
303 
304 	markAllStateDirty();
305 }
306 
307 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
markAllStateDirty()308 void Context::markAllStateDirty()
309 {
310 	mAppliedProgramSerial = 0;
311 
312 	mDepthStateDirty = true;
313 	mMaskStateDirty = true;
314 	mBlendStateDirty = true;
315 	mStencilStateDirty = true;
316 	mPolygonOffsetStateDirty = true;
317 	mSampleStateDirty = true;
318 	mDitherStateDirty = true;
319 	mFrontFaceDirty = true;
320 	mColorLogicOperatorDirty = true;
321 }
322 
setClearColor(float red,float green,float blue,float alpha)323 void Context::setClearColor(float red, float green, float blue, float alpha)
324 {
325 	mState.colorClearValue.red = red;
326 	mState.colorClearValue.green = green;
327 	mState.colorClearValue.blue = blue;
328 	mState.colorClearValue.alpha = alpha;
329 }
330 
setClearDepth(float depth)331 void Context::setClearDepth(float depth)
332 {
333 	mState.depthClearValue = depth;
334 }
335 
setClearStencil(int stencil)336 void Context::setClearStencil(int stencil)
337 {
338 	mState.stencilClearValue = stencil;
339 }
340 
setCullFaceEnabled(bool enabled)341 void Context::setCullFaceEnabled(bool enabled)
342 {
343 	mState.cullFaceEnabled = enabled;
344 }
345 
isCullFaceEnabled() const346 bool Context::isCullFaceEnabled() const
347 {
348 	return mState.cullFaceEnabled;
349 }
350 
setCullMode(GLenum mode)351 void Context::setCullMode(GLenum mode)
352 {
353    mState.cullMode = mode;
354 }
355 
setFrontFace(GLenum front)356 void Context::setFrontFace(GLenum front)
357 {
358 	if(mState.frontFace != front)
359 	{
360 		mState.frontFace = front;
361 		mFrontFaceDirty = true;
362 	}
363 }
364 
setDepthTestEnabled(bool enabled)365 void Context::setDepthTestEnabled(bool enabled)
366 {
367 	if(mState.depthTestEnabled != enabled)
368 	{
369 		mState.depthTestEnabled = enabled;
370 		mDepthStateDirty = true;
371 	}
372 }
373 
isDepthTestEnabled() const374 bool Context::isDepthTestEnabled() const
375 {
376 	return mState.depthTestEnabled;
377 }
378 
setDepthFunc(GLenum depthFunc)379 void Context::setDepthFunc(GLenum depthFunc)
380 {
381 	if(mState.depthFunc != depthFunc)
382 	{
383 		mState.depthFunc = depthFunc;
384 		mDepthStateDirty = true;
385 	}
386 }
387 
setDepthRange(float zNear,float zFar)388 void Context::setDepthRange(float zNear, float zFar)
389 {
390 	mState.zNear = zNear;
391 	mState.zFar = zFar;
392 }
393 
setBlendEnabled(bool enabled)394 void Context::setBlendEnabled(bool enabled)
395 {
396 	if(mState.blendEnabled != enabled)
397 	{
398 		mState.blendEnabled = enabled;
399 		mBlendStateDirty = true;
400 	}
401 }
402 
isBlendEnabled() const403 bool Context::isBlendEnabled() const
404 {
405 	return mState.blendEnabled;
406 }
407 
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)408 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
409 {
410 	if(mState.sourceBlendRGB != sourceRGB ||
411 	   mState.sourceBlendAlpha != sourceAlpha ||
412 	   mState.destBlendRGB != destRGB ||
413 	   mState.destBlendAlpha != destAlpha)
414 	{
415 		mState.sourceBlendRGB = sourceRGB;
416 		mState.destBlendRGB = destRGB;
417 		mState.sourceBlendAlpha = sourceAlpha;
418 		mState.destBlendAlpha = destAlpha;
419 		mBlendStateDirty = true;
420 	}
421 }
422 
setBlendColor(float red,float green,float blue,float alpha)423 void Context::setBlendColor(float red, float green, float blue, float alpha)
424 {
425 	if(mState.blendColor.red != red ||
426 	   mState.blendColor.green != green ||
427 	   mState.blendColor.blue != blue ||
428 	   mState.blendColor.alpha != alpha)
429 	{
430 		mState.blendColor.red = red;
431 		mState.blendColor.green = green;
432 		mState.blendColor.blue = blue;
433 		mState.blendColor.alpha = alpha;
434 		mBlendStateDirty = true;
435 	}
436 }
437 
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)438 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
439 {
440 	if(mState.blendEquationRGB != rgbEquation ||
441 	   mState.blendEquationAlpha != alphaEquation)
442 	{
443 		mState.blendEquationRGB = rgbEquation;
444 		mState.blendEquationAlpha = alphaEquation;
445 		mBlendStateDirty = true;
446 	}
447 }
448 
setStencilTestEnabled(bool enabled)449 void Context::setStencilTestEnabled(bool enabled)
450 {
451 	if(mState.stencilTestEnabled != enabled)
452 	{
453 		mState.stencilTestEnabled = enabled;
454 		mStencilStateDirty = true;
455 	}
456 }
457 
isStencilTestEnabled() const458 bool Context::isStencilTestEnabled() const
459 {
460 	return mState.stencilTestEnabled;
461 }
462 
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)463 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
464 {
465 	if(mState.stencilFunc != stencilFunc ||
466 	   mState.stencilRef != stencilRef ||
467 	   mState.stencilMask != stencilMask)
468 	{
469 		mState.stencilFunc = stencilFunc;
470 		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
471 		mState.stencilMask = stencilMask;
472 		mStencilStateDirty = true;
473 	}
474 }
475 
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)476 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
477 {
478 	if(mState.stencilBackFunc != stencilBackFunc ||
479 	   mState.stencilBackRef != stencilBackRef ||
480 	   mState.stencilBackMask != stencilBackMask)
481 	{
482 		mState.stencilBackFunc = stencilBackFunc;
483 		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
484 		mState.stencilBackMask = stencilBackMask;
485 		mStencilStateDirty = true;
486 	}
487 }
488 
setStencilWritemask(GLuint stencilWritemask)489 void Context::setStencilWritemask(GLuint stencilWritemask)
490 {
491 	if(mState.stencilWritemask != stencilWritemask)
492 	{
493 		mState.stencilWritemask = stencilWritemask;
494 		mStencilStateDirty = true;
495 	}
496 }
497 
setStencilBackWritemask(GLuint stencilBackWritemask)498 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
499 {
500 	if(mState.stencilBackWritemask != stencilBackWritemask)
501 	{
502 		mState.stencilBackWritemask = stencilBackWritemask;
503 		mStencilStateDirty = true;
504 	}
505 }
506 
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)507 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
508 {
509 	if(mState.stencilFail != stencilFail ||
510 	   mState.stencilPassDepthFail != stencilPassDepthFail ||
511 	   mState.stencilPassDepthPass != stencilPassDepthPass)
512 	{
513 		mState.stencilFail = stencilFail;
514 		mState.stencilPassDepthFail = stencilPassDepthFail;
515 		mState.stencilPassDepthPass = stencilPassDepthPass;
516 		mStencilStateDirty = true;
517 	}
518 }
519 
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)520 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
521 {
522 	if(mState.stencilBackFail != stencilBackFail ||
523 	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
524 	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
525 	{
526 		mState.stencilBackFail = stencilBackFail;
527 		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
528 		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
529 		mStencilStateDirty = true;
530 	}
531 }
532 
setPolygonOffsetFillEnabled(bool enabled)533 void Context::setPolygonOffsetFillEnabled(bool enabled)
534 {
535 	if(mState.polygonOffsetFillEnabled != enabled)
536 	{
537 		mState.polygonOffsetFillEnabled = enabled;
538 		mPolygonOffsetStateDirty = true;
539 	}
540 }
541 
isPolygonOffsetFillEnabled() const542 bool Context::isPolygonOffsetFillEnabled() const
543 {
544 	return mState.polygonOffsetFillEnabled;
545 }
546 
setPolygonOffsetParams(GLfloat factor,GLfloat units)547 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
548 {
549 	if(mState.polygonOffsetFactor != factor ||
550 	   mState.polygonOffsetUnits != units)
551 	{
552 		mState.polygonOffsetFactor = factor;
553 		mState.polygonOffsetUnits = units;
554 		mPolygonOffsetStateDirty = true;
555 	}
556 }
557 
setSampleAlphaToCoverageEnabled(bool enabled)558 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
559 {
560 	if(mState.sampleAlphaToCoverageEnabled != enabled)
561 	{
562 		mState.sampleAlphaToCoverageEnabled = enabled;
563 		mSampleStateDirty = true;
564 	}
565 }
566 
isSampleAlphaToCoverageEnabled() const567 bool Context::isSampleAlphaToCoverageEnabled() const
568 {
569 	return mState.sampleAlphaToCoverageEnabled;
570 }
571 
setSampleCoverageEnabled(bool enabled)572 void Context::setSampleCoverageEnabled(bool enabled)
573 {
574 	if(mState.sampleCoverageEnabled != enabled)
575 	{
576 		mState.sampleCoverageEnabled = enabled;
577 		mSampleStateDirty = true;
578 	}
579 }
580 
isSampleCoverageEnabled() const581 bool Context::isSampleCoverageEnabled() const
582 {
583 	return mState.sampleCoverageEnabled;
584 }
585 
setSampleCoverageParams(GLclampf value,bool invert)586 void Context::setSampleCoverageParams(GLclampf value, bool invert)
587 {
588 	if(mState.sampleCoverageValue != value ||
589 		mState.sampleCoverageInvert != invert)
590 	{
591 		mState.sampleCoverageValue = value;
592 		mState.sampleCoverageInvert = invert;
593 		mSampleStateDirty = true;
594 	}
595 }
596 
setScissorTestEnabled(bool enabled)597 void Context::setScissorTestEnabled(bool enabled)
598 {
599 	mState.scissorTestEnabled = enabled;
600 }
601 
isScissorTestEnabled() const602 bool Context::isScissorTestEnabled() const
603 {
604 	return mState.scissorTestEnabled;
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 
setLineWidth(GLfloat width)621 void Context::setLineWidth(GLfloat width)
622 {
623 	mState.lineWidth = width;
624 	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
625 }
626 
setGenerateMipmapHint(GLenum hint)627 void Context::setGenerateMipmapHint(GLenum hint)
628 {
629 	mState.generateMipmapHint = hint;
630 }
631 
setFragmentShaderDerivativeHint(GLenum hint)632 void Context::setFragmentShaderDerivativeHint(GLenum hint)
633 {
634 	mState.fragmentShaderDerivativeHint = hint;
635 	// TODO: Propagate the hint to shader translator so we can write
636 	// ddx, ddx_coarse, or ddx_fine depending on the hint.
637 	// Ignore for now. It is valid for implementations to ignore hint.
638 }
639 
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)640 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
641 {
642 	mState.viewportX = x;
643 	mState.viewportY = y;
644 	mState.viewportWidth = width;
645 	mState.viewportHeight = height;
646 }
647 
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)648 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
649 {
650 	mState.scissorX = x;
651 	mState.scissorY = y;
652 	mState.scissorWidth = width;
653 	mState.scissorHeight = height;
654 }
655 
setColorMask(bool red,bool green,bool blue,bool alpha)656 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
657 {
658 	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
659 	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
660 	{
661 		mState.colorMaskRed = red;
662 		mState.colorMaskGreen = green;
663 		mState.colorMaskBlue = blue;
664 		mState.colorMaskAlpha = alpha;
665 		mMaskStateDirty = true;
666 	}
667 }
668 
setDepthMask(bool mask)669 void Context::setDepthMask(bool mask)
670 {
671 	if(mState.depthMask != mask)
672 	{
673 		mState.depthMask = mask;
674 		mMaskStateDirty = true;
675 	}
676 }
677 
setActiveSampler(unsigned int active)678 void Context::setActiveSampler(unsigned int active)
679 {
680 	mState.activeSampler = active;
681 }
682 
getReadFramebufferName() const683 GLuint Context::getReadFramebufferName() const
684 {
685 	return mState.readFramebuffer;
686 }
687 
getDrawFramebufferName() const688 GLuint Context::getDrawFramebufferName() const
689 {
690 	return mState.drawFramebuffer;
691 }
692 
getRenderbufferName() const693 GLuint Context::getRenderbufferName() const
694 {
695 	return mState.renderbuffer.name();
696 }
697 
getArrayBufferName() const698 GLuint Context::getArrayBufferName() const
699 {
700 	return mState.arrayBuffer.name();
701 }
702 
getActiveQuery(GLenum target) const703 GLuint Context::getActiveQuery(GLenum target) const
704 {
705 	Query *queryObject = nullptr;
706 
707 	switch(target)
708 	{
709 	case GL_ANY_SAMPLES_PASSED:
710 		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
711 		break;
712 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
713 		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
714 		break;
715 	default:
716 		ASSERT(false);
717 	}
718 
719 	if(queryObject)
720 	{
721 		return queryObject->name;
722 	}
723 
724 	return 0;
725 }
726 
setVertexAttribArrayEnabled(unsigned int attribNum,bool enabled)727 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
728 {
729 	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
730 }
731 
getVertexAttribState(unsigned int attribNum)732 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
733 {
734 	return mState.vertexAttribute[attribNum];
735 }
736 
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,GLsizei stride,const void * pointer)737 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
738                                    GLsizei stride, const void *pointer)
739 {
740 	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
741 	mState.vertexAttribute[attribNum].mSize = size;
742 	mState.vertexAttribute[attribNum].mType = type;
743 	mState.vertexAttribute[attribNum].mNormalized = normalized;
744 	mState.vertexAttribute[attribNum].mStride = stride;
745 	mState.vertexAttribute[attribNum].mPointer = pointer;
746 }
747 
getVertexAttribPointer(unsigned int attribNum) const748 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
749 {
750 	return mState.vertexAttribute[attribNum].mPointer;
751 }
752 
getVertexAttributes()753 const VertexAttributeArray &Context::getVertexAttributes()
754 {
755 	return mState.vertexAttribute;
756 }
757 
setPackAlignment(GLint alignment)758 void Context::setPackAlignment(GLint alignment)
759 {
760 	mState.packAlignment = alignment;
761 }
762 
getPackAlignment() const763 GLint Context::getPackAlignment() const
764 {
765 	return mState.packAlignment;
766 }
767 
setUnpackAlignment(GLint alignment)768 void Context::setUnpackAlignment(GLint alignment)
769 {
770 	mState.unpackAlignment = alignment;
771 }
772 
getUnpackAlignment() const773 GLint Context::getUnpackAlignment() const
774 {
775 	return mState.unpackAlignment;
776 }
777 
createBuffer()778 GLuint Context::createBuffer()
779 {
780 	return mResourceManager->createBuffer();
781 }
782 
createProgram()783 GLuint Context::createProgram()
784 {
785 	return mResourceManager->createProgram();
786 }
787 
createShader(GLenum type)788 GLuint Context::createShader(GLenum type)
789 {
790 	return mResourceManager->createShader(type);
791 }
792 
createTexture()793 GLuint Context::createTexture()
794 {
795 	return mResourceManager->createTexture();
796 }
797 
createRenderbuffer()798 GLuint Context::createRenderbuffer()
799 {
800 	return mResourceManager->createRenderbuffer();
801 }
802 
803 // Returns an unused framebuffer name
createFramebuffer()804 GLuint Context::createFramebuffer()
805 {
806 	return mFramebufferNameSpace.allocate();
807 }
808 
createFence()809 GLuint Context::createFence()
810 {
811 	return mFenceNameSpace.allocate(new Fence());
812 }
813 
814 // Returns an unused query name
createQuery()815 GLuint Context::createQuery()
816 {
817 	return mQueryNameSpace.allocate();
818 }
819 
deleteBuffer(GLuint buffer)820 void Context::deleteBuffer(GLuint buffer)
821 {
822 	if(mResourceManager->getBuffer(buffer))
823 	{
824 		detachBuffer(buffer);
825 	}
826 
827 	mResourceManager->deleteBuffer(buffer);
828 }
829 
deleteShader(GLuint shader)830 void Context::deleteShader(GLuint shader)
831 {
832 	mResourceManager->deleteShader(shader);
833 }
834 
deleteProgram(GLuint program)835 void Context::deleteProgram(GLuint program)
836 {
837 	mResourceManager->deleteProgram(program);
838 }
839 
deleteTexture(GLuint texture)840 void Context::deleteTexture(GLuint texture)
841 {
842 	if(mResourceManager->getTexture(texture))
843 	{
844 		detachTexture(texture);
845 	}
846 
847 	mResourceManager->deleteTexture(texture);
848 }
849 
deleteRenderbuffer(GLuint renderbuffer)850 void Context::deleteRenderbuffer(GLuint renderbuffer)
851 {
852 	if(mResourceManager->getRenderbuffer(renderbuffer))
853 	{
854 		detachRenderbuffer(renderbuffer);
855 	}
856 
857 	mResourceManager->deleteRenderbuffer(renderbuffer);
858 }
859 
deleteFramebuffer(GLuint framebuffer)860 void Context::deleteFramebuffer(GLuint framebuffer)
861 {
862 	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
863 
864 	if(framebufferObject)
865 	{
866 		detachFramebuffer(framebuffer);
867 
868 		delete framebufferObject;
869 	}
870 }
871 
deleteFence(GLuint fence)872 void Context::deleteFence(GLuint fence)
873 {
874 	Fence *fenceObject = mFenceNameSpace.remove(fence);
875 
876 	if(fenceObject)
877 	{
878 		delete fenceObject;
879 	}
880 }
881 
deleteQuery(GLuint query)882 void Context::deleteQuery(GLuint query)
883 {
884 	Query *queryObject = mQueryNameSpace.remove(query);
885 
886 	if(queryObject)
887 	{
888 		queryObject->release();
889 	}
890 }
891 
getBuffer(GLuint handle)892 Buffer *Context::getBuffer(GLuint handle)
893 {
894 	return mResourceManager->getBuffer(handle);
895 }
896 
getShader(GLuint handle)897 Shader *Context::getShader(GLuint handle)
898 {
899 	return mResourceManager->getShader(handle);
900 }
901 
getProgram(GLuint handle)902 Program *Context::getProgram(GLuint handle)
903 {
904 	return mResourceManager->getProgram(handle);
905 }
906 
getTexture(GLuint handle)907 Texture *Context::getTexture(GLuint handle)
908 {
909 	return mResourceManager->getTexture(handle);
910 }
911 
getRenderbuffer(GLuint handle)912 Renderbuffer *Context::getRenderbuffer(GLuint handle)
913 {
914 	return mResourceManager->getRenderbuffer(handle);
915 }
916 
getReadFramebuffer()917 Framebuffer *Context::getReadFramebuffer()
918 {
919 	return getFramebuffer(mState.readFramebuffer);
920 }
921 
getDrawFramebuffer()922 Framebuffer *Context::getDrawFramebuffer()
923 {
924 	return getFramebuffer(mState.drawFramebuffer);
925 }
926 
bindArrayBuffer(unsigned int buffer)927 void Context::bindArrayBuffer(unsigned int buffer)
928 {
929 	mResourceManager->checkBufferAllocation(buffer);
930 
931 	mState.arrayBuffer = getBuffer(buffer);
932 }
933 
bindElementArrayBuffer(unsigned int buffer)934 void Context::bindElementArrayBuffer(unsigned int buffer)
935 {
936 	mResourceManager->checkBufferAllocation(buffer);
937 
938 	mState.elementArrayBuffer = getBuffer(buffer);
939 }
940 
bindTexture2D(GLuint texture)941 void Context::bindTexture2D(GLuint texture)
942 {
943 	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
944 
945 	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
946 }
947 
bindTextureCubeMap(GLuint texture)948 void Context::bindTextureCubeMap(GLuint texture)
949 {
950 	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
951 
952 	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
953 }
954 
bindReadFramebuffer(GLuint framebuffer)955 void Context::bindReadFramebuffer(GLuint framebuffer)
956 {
957 	if(!getFramebuffer(framebuffer))
958 	{
959 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
960 	}
961 
962 	mState.readFramebuffer = framebuffer;
963 }
964 
bindDrawFramebuffer(GLuint framebuffer)965 void Context::bindDrawFramebuffer(GLuint framebuffer)
966 {
967 	if(!getFramebuffer(framebuffer))
968 	{
969 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
970 	}
971 
972 	mState.drawFramebuffer = framebuffer;
973 }
974 
bindRenderbuffer(GLuint renderbuffer)975 void Context::bindRenderbuffer(GLuint renderbuffer)
976 {
977 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
978 
979 	mState.renderbuffer = getRenderbuffer(renderbuffer);
980 }
981 
useProgram(GLuint program)982 void Context::useProgram(GLuint program)
983 {
984 	GLuint priorProgram = mState.currentProgram;
985 	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
986 
987 	if(priorProgram != program)
988 	{
989 		Program *newProgram = mResourceManager->getProgram(program);
990 		Program *oldProgram = mResourceManager->getProgram(priorProgram);
991 
992 		if(newProgram)
993 		{
994 			newProgram->addRef();
995 		}
996 
997 		if(oldProgram)
998 		{
999 			oldProgram->release();
1000 		}
1001 	}
1002 }
1003 
beginQuery(GLenum target,GLuint query)1004 void Context::beginQuery(GLenum target, GLuint query)
1005 {
1006 	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1007 	// of zero, if the active query object name for <target> is non-zero (for the
1008 	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1009 	// the active query for either target is non-zero), if <id> is the name of an
1010 	// existing query object whose type does not match <target>, or if <id> is the
1011 	// active query object name for any query type, the error INVALID_OPERATION is
1012 	// generated.
1013 
1014 	// Ensure no other queries are active
1015 	// NOTE: If other queries than occlusion are supported, we will need to check
1016 	// separately that:
1017 	//    a) The query ID passed is not the current active query for any target/type
1018 	//    b) There are no active queries for the requested target (and in the case
1019 	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1020 	//       no query may be active for either if glBeginQuery targets either.
1021 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1022 	{
1023 		if(mState.activeQuery[i])
1024 		{
1025 			return error(GL_INVALID_OPERATION);
1026 		}
1027 	}
1028 
1029 	QueryType qType;
1030 	switch(target)
1031 	{
1032 	case GL_ANY_SAMPLES_PASSED:
1033 		qType = QUERY_ANY_SAMPLES_PASSED;
1034 		break;
1035 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
1036 		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1037 		break;
1038 	default:
1039 		ASSERT(false);
1040 	}
1041 
1042 	Query *queryObject = getQuery(query, true, target);
1043 
1044 	// Check that name was obtained with glGenQueries
1045 	if(!queryObject)
1046 	{
1047 		return error(GL_INVALID_OPERATION);
1048 	}
1049 
1050 	// Check for type mismatch
1051 	if(queryObject->getType() != target)
1052 	{
1053 		return error(GL_INVALID_OPERATION);
1054 	}
1055 
1056 	// Set query as active for specified target
1057 	mState.activeQuery[qType] = queryObject;
1058 
1059 	// Begin query
1060 	queryObject->begin();
1061 }
1062 
endQuery(GLenum target)1063 void Context::endQuery(GLenum target)
1064 {
1065 	QueryType qType;
1066 
1067 	switch(target)
1068 	{
1069 	case GL_ANY_SAMPLES_PASSED:
1070 		qType = QUERY_ANY_SAMPLES_PASSED;
1071 		break;
1072 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
1073 		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1074 		break;
1075 	default:
1076 		ASSERT(false);
1077 	}
1078 
1079 	Query *queryObject = mState.activeQuery[qType];
1080 
1081 	if(!queryObject)
1082 	{
1083 		return error(GL_INVALID_OPERATION);
1084 	}
1085 
1086 	queryObject->end();
1087 
1088 	mState.activeQuery[qType] = nullptr;
1089 }
1090 
setFramebufferZero(Framebuffer * buffer)1091 void Context::setFramebufferZero(Framebuffer *buffer)
1092 {
1093 	delete mFramebufferNameSpace.remove(0);
1094 	mFramebufferNameSpace.insert(0, buffer);
1095 }
1096 
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1097 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1098 {
1099 	Renderbuffer *renderbufferObject = mState.renderbuffer;
1100 	renderbufferObject->setStorage(renderbuffer);
1101 }
1102 
getFramebuffer(unsigned int handle)1103 Framebuffer *Context::getFramebuffer(unsigned int handle)
1104 {
1105 	return mFramebufferNameSpace.find(handle);
1106 }
1107 
getFence(unsigned int handle)1108 Fence *Context::getFence(unsigned int handle)
1109 {
1110 	return mFenceNameSpace.find(handle);
1111 }
1112 
getQuery(unsigned int handle,bool create,GLenum type)1113 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1114 {
1115 	if(!mQueryNameSpace.isReserved(handle))
1116 	{
1117 		return nullptr;
1118 	}
1119 	else
1120 	{
1121 		Query *query = mQueryNameSpace.find(handle);
1122 		if(!query && create)
1123 		{
1124 			query = new Query(handle, type);
1125 			query->addRef();
1126 			mQueryNameSpace.insert(handle, query);
1127 		}
1128 
1129 		return query;
1130 	}
1131 }
1132 
getArrayBuffer()1133 Buffer *Context::getArrayBuffer()
1134 {
1135 	return mState.arrayBuffer;
1136 }
1137 
getElementArrayBuffer()1138 Buffer *Context::getElementArrayBuffer()
1139 {
1140 	return mState.elementArrayBuffer;
1141 }
1142 
getCurrentProgram()1143 Program *Context::getCurrentProgram()
1144 {
1145 	return mResourceManager->getProgram(mState.currentProgram);
1146 }
1147 
getTexture2D(GLenum target)1148 Texture2D *Context::getTexture2D(GLenum target)
1149 {
1150 	if(target == GL_TEXTURE_2D)
1151 	{
1152 		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1153 	}
1154 	else if(target == GL_PROXY_TEXTURE_2D)
1155 	{
1156 		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D));
1157 	}
1158 	else UNREACHABLE(target);
1159 
1160 	return nullptr;
1161 }
1162 
getTextureCubeMap()1163 TextureCubeMap *Context::getTextureCubeMap()
1164 {
1165 	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1166 }
1167 
getSamplerTexture(unsigned int sampler,TextureType type)1168 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1169 {
1170 	GLuint texid = mState.samplerTexture[type][sampler].name();
1171 
1172 	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1173 	{
1174 		switch(type)
1175 		{
1176 		case TEXTURE_2D:       return mTexture2DZero;
1177 		case PROXY_TEXTURE_2D: return mProxyTexture2DZero;
1178 		case TEXTURE_CUBE:     return mTextureCubeMapZero;
1179 		default: UNREACHABLE(type);
1180 		}
1181 	}
1182 
1183 	return mState.samplerTexture[type][sampler];
1184 }
1185 
getBooleanv(GLenum pname,GLboolean * params)1186 bool Context::getBooleanv(GLenum pname, GLboolean *params)
1187 {
1188 	switch(pname)
1189 	{
1190 	case GL_SHADER_COMPILER:          *params = GL_TRUE;                             break;
1191 	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
1192 	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
1193 	case GL_COLOR_WRITEMASK:
1194 		params[0] = mState.colorMaskRed;
1195 		params[1] = mState.colorMaskGreen;
1196 		params[2] = mState.colorMaskBlue;
1197 		params[3] = mState.colorMaskAlpha;
1198 		break;
1199 	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
1200 	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
1201 	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1202 	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
1203 	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
1204 	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
1205 	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
1206 	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
1207 	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
1208 	default:
1209 		return false;
1210 	}
1211 
1212 	return true;
1213 }
1214 
getFloatv(GLenum pname,GLfloat * params)1215 bool Context::getFloatv(GLenum pname, GLfloat *params)
1216 {
1217 	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1218 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1219 	// GetIntegerv as its native query function. As it would require conversion in any
1220 	// case, this should make no difference to the calling application.
1221 	switch(pname)
1222 	{
1223 	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1224 	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1225 	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1226 	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1227 	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1228 	case GL_ALIASED_LINE_WIDTH_RANGE:
1229 		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1230 		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1231 		break;
1232 	case GL_ALIASED_POINT_SIZE_RANGE:
1233 		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1234 		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1235 		break;
1236 	case GL_DEPTH_RANGE:
1237 		params[0] = mState.zNear;
1238 		params[1] = mState.zFar;
1239 		break;
1240 	case GL_COLOR_CLEAR_VALUE:
1241 		params[0] = mState.colorClearValue.red;
1242 		params[1] = mState.colorClearValue.green;
1243 		params[2] = mState.colorClearValue.blue;
1244 		params[3] = mState.colorClearValue.alpha;
1245 		break;
1246 	case GL_BLEND_COLOR:
1247 		params[0] = mState.blendColor.red;
1248 		params[1] = mState.blendColor.green;
1249 		params[2] = mState.blendColor.blue;
1250 		params[3] = mState.blendColor.alpha;
1251 		break;
1252 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1253 		*params = MAX_TEXTURE_MAX_ANISOTROPY;
1254 		break;
1255 	case GL_MODELVIEW_MATRIX:
1256 		for(int i = 0; i < 16; i++)
1257 		{
1258 			params[i] = modelView.current()[i % 4][i / 4];
1259 		}
1260 		break;
1261 	case GL_PROJECTION_MATRIX:
1262 		for(int i = 0; i < 16; i++)
1263 		{
1264 			params[i] = projection.current()[i % 4][i / 4];
1265 		}
1266 		break;
1267 	default:
1268 		return false;
1269 	}
1270 
1271 	return true;
1272 }
1273 
getIntegerv(GLenum pname,GLint * params)1274 bool Context::getIntegerv(GLenum pname, GLint *params)
1275 {
1276 	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1277 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1278 	// GetIntegerv as its native query function. As it would require conversion in any
1279 	// case, this should make no difference to the calling application. You may find it in
1280 	// Context::getFloatv.
1281 	switch(pname)
1282 	{
1283 	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
1284 	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
1285 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:    *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
1286 	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
1287 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
1288 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
1289 	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
1290 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
1291 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:  *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
1292 	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
1293 	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
1294 	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
1295 	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
1296 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
1297 //	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1298 	case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               break;
1299 	case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               break;
1300 	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
1301 	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
1302 	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1303 	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1304 	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1305 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:  *params = mState.fragmentShaderDerivativeHint; break;
1306 	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1307 	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
1308 	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
1309 	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
1310 	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
1311 	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
1312 	case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.stencilBackMask;               break;
1313 	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
1314 	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
1315 	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
1316 	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
1317 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
1318 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
1319 	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
1320 	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
1321 	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
1322 	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
1323 	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
1324 	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
1325 	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
1326 	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
1327 	case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;
1328 	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1329 	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1330 	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
1331 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
1332 	case GL_MAX_ARRAY_TEXTURE_LAYERS:         *params = 0;                                    break;
1333 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
1334 	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;           break;
1335 	case GL_SAMPLE_BUFFERS:
1336 	case GL_SAMPLES:
1337 		{
1338 			Framebuffer *framebuffer = getDrawFramebuffer();
1339 			int width, height, samples;
1340 
1341 			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
1342 			{
1343 				switch(pname)
1344 				{
1345 				case GL_SAMPLE_BUFFERS:
1346 					if(samples > 1)
1347 					{
1348 						*params = 1;
1349 					}
1350 					else
1351 					{
1352 						*params = 0;
1353 					}
1354 					break;
1355 				case GL_SAMPLES:
1356 					*params = samples;
1357 					break;
1358 				}
1359 			}
1360 			else
1361 			{
1362 				*params = 0;
1363 			}
1364 		}
1365 		break;
1366 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = IMPLEMENTATION_COLOR_READ_TYPE;   break;
1367 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
1368 	case GL_MAX_VIEWPORT_DIMS:
1369 		{
1370 			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1371 			params[0] = maxDimension;
1372 			params[1] = maxDimension;
1373 		}
1374 		break;
1375 	case GL_COMPRESSED_TEXTURE_FORMATS:
1376 		{
1377 			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1378 			{
1379 				params[i] = compressedTextureFormats[i];
1380 			}
1381 		}
1382 		break;
1383 	case GL_VIEWPORT:
1384 		params[0] = mState.viewportX;
1385 		params[1] = mState.viewportY;
1386 		params[2] = mState.viewportWidth;
1387 		params[3] = mState.viewportHeight;
1388 		break;
1389 	case GL_SCISSOR_BOX:
1390 		params[0] = mState.scissorX;
1391 		params[1] = mState.scissorY;
1392 		params[2] = mState.scissorWidth;
1393 		params[3] = mState.scissorHeight;
1394 		break;
1395 	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
1396 	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
1397 	case GL_RED_BITS:
1398 	case GL_GREEN_BITS:
1399 	case GL_BLUE_BITS:
1400 	case GL_ALPHA_BITS:
1401 		{
1402 			Framebuffer *framebuffer = getDrawFramebuffer();
1403 			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1404 
1405 			if(colorbuffer)
1406 			{
1407 				switch(pname)
1408 				{
1409 				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
1410 				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1411 				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
1412 				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1413 				}
1414 			}
1415 			else
1416 			{
1417 				*params = 0;
1418 			}
1419 		}
1420 		break;
1421 	case GL_DEPTH_BITS:
1422 		{
1423 			Framebuffer *framebuffer = getDrawFramebuffer();
1424 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1425 
1426 			if(depthbuffer)
1427 			{
1428 				*params = depthbuffer->getDepthSize();
1429 			}
1430 			else
1431 			{
1432 				*params = 0;
1433 			}
1434 		}
1435 		break;
1436 	case GL_STENCIL_BITS:
1437 		{
1438 			Framebuffer *framebuffer = getDrawFramebuffer();
1439 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1440 
1441 			if(stencilbuffer)
1442 			{
1443 				*params = stencilbuffer->getStencilSize();
1444 			}
1445 			else
1446 			{
1447 				*params = 0;
1448 			}
1449 		}
1450 		break;
1451 	case GL_TEXTURE_BINDING_2D:
1452 		{
1453 			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1454 			{
1455 				error(GL_INVALID_OPERATION);
1456 				return false;
1457 			}
1458 
1459 			*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
1460 		}
1461 		break;
1462 	case GL_TEXTURE_BINDING_CUBE_MAP:
1463 		{
1464 			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1465 			{
1466 				error(GL_INVALID_OPERATION);
1467 				return false;
1468 			}
1469 
1470 			*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
1471 		}
1472 		break;
1473 	default:
1474 		return false;
1475 	}
1476 
1477 	return true;
1478 }
1479 
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams)1480 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1481 {
1482 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1483 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1484 	// to the fact that it is stored internally as a float, and so would require conversion
1485 	// if returned from Context::getIntegerv. Since this conversion is already implemented
1486 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1487 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1488 	// application.
1489 	switch(pname)
1490 	{
1491 	case GL_COMPRESSED_TEXTURE_FORMATS:
1492 		{
1493 			*type = GL_INT;
1494 			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
1495 		}
1496 		break;
1497 	case GL_SHADER_BINARY_FORMATS:
1498 		{
1499 			*type = GL_INT;
1500 			*numParams = 0;
1501 		}
1502 		break;
1503 	case GL_MAX_VERTEX_ATTRIBS:
1504 	case GL_MAX_VERTEX_UNIFORM_VECTORS:
1505 	case GL_MAX_VARYING_VECTORS:
1506 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1507 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1508 	case GL_MAX_TEXTURE_IMAGE_UNITS:
1509 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1510 	case GL_MAX_RENDERBUFFER_SIZE:
1511 	case GL_NUM_SHADER_BINARY_FORMATS:
1512 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1513 	case GL_ARRAY_BUFFER_BINDING:
1514 	case GL_FRAMEBUFFER_BINDING:
1515 	case GL_RENDERBUFFER_BINDING:
1516 	case GL_CURRENT_PROGRAM:
1517 	case GL_PACK_ALIGNMENT:
1518 	case GL_UNPACK_ALIGNMENT:
1519 	case GL_GENERATE_MIPMAP_HINT:
1520 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
1521 	case GL_RED_BITS:
1522 	case GL_GREEN_BITS:
1523 	case GL_BLUE_BITS:
1524 	case GL_ALPHA_BITS:
1525 	case GL_DEPTH_BITS:
1526 	case GL_STENCIL_BITS:
1527 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1528 	case GL_CULL_FACE_MODE:
1529 	case GL_FRONT_FACE:
1530 	case GL_ACTIVE_TEXTURE:
1531 	case GL_STENCIL_FUNC:
1532 	case GL_STENCIL_VALUE_MASK:
1533 	case GL_STENCIL_REF:
1534 	case GL_STENCIL_FAIL:
1535 	case GL_STENCIL_PASS_DEPTH_FAIL:
1536 	case GL_STENCIL_PASS_DEPTH_PASS:
1537 	case GL_STENCIL_BACK_FUNC:
1538 	case GL_STENCIL_BACK_VALUE_MASK:
1539 	case GL_STENCIL_BACK_REF:
1540 	case GL_STENCIL_BACK_FAIL:
1541 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1542 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1543 	case GL_DEPTH_FUNC:
1544 	case GL_BLEND_SRC_RGB:
1545 	case GL_BLEND_SRC_ALPHA:
1546 	case GL_BLEND_DST_RGB:
1547 	case GL_BLEND_DST_ALPHA:
1548 	case GL_BLEND_EQUATION_RGB:
1549 	case GL_BLEND_EQUATION_ALPHA:
1550 	case GL_STENCIL_WRITEMASK:
1551 	case GL_STENCIL_BACK_WRITEMASK:
1552 	case GL_STENCIL_CLEAR_VALUE:
1553 	case GL_SUBPIXEL_BITS:
1554 	case GL_MAX_TEXTURE_SIZE:
1555 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1556 	case GL_SAMPLE_BUFFERS:
1557 	case GL_SAMPLES:
1558 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1559 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1560 	case GL_TEXTURE_BINDING_2D:
1561 	case GL_TEXTURE_BINDING_CUBE_MAP:
1562 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1563 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1564 	case GL_MAX_ARRAY_TEXTURE_LAYERS:
1565 		{
1566 			*type = GL_INT;
1567 			*numParams = 1;
1568 		}
1569 		break;
1570 	case GL_MAX_SAMPLES:
1571 		{
1572 			*type = GL_INT;
1573 			*numParams = 1;
1574 		}
1575 		break;
1576 	case GL_MAX_VIEWPORT_DIMS:
1577 		{
1578 			*type = GL_INT;
1579 			*numParams = 2;
1580 		}
1581 		break;
1582 	case GL_VIEWPORT:
1583 	case GL_SCISSOR_BOX:
1584 		{
1585 			*type = GL_INT;
1586 			*numParams = 4;
1587 		}
1588 		break;
1589 	case GL_SHADER_COMPILER:
1590 	case GL_SAMPLE_COVERAGE_INVERT:
1591 	case GL_DEPTH_WRITEMASK:
1592 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1593 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1594 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1595 	case GL_SAMPLE_COVERAGE:
1596 	case GL_SCISSOR_TEST:
1597 	case GL_STENCIL_TEST:
1598 	case GL_DEPTH_TEST:
1599 	case GL_BLEND:
1600 	case GL_DITHER:
1601 		{
1602 			*type = GL_BOOL;
1603 			*numParams = 1;
1604 		}
1605 		break;
1606 	case GL_COLOR_WRITEMASK:
1607 		{
1608 			*type = GL_BOOL;
1609 			*numParams = 4;
1610 		}
1611 		break;
1612 	case GL_POLYGON_OFFSET_FACTOR:
1613 	case GL_POLYGON_OFFSET_UNITS:
1614 	case GL_SAMPLE_COVERAGE_VALUE:
1615 	case GL_DEPTH_CLEAR_VALUE:
1616 	case GL_LINE_WIDTH:
1617 		{
1618 			*type = GL_FLOAT;
1619 			*numParams = 1;
1620 		}
1621 		break;
1622 	case GL_ALIASED_LINE_WIDTH_RANGE:
1623 	case GL_ALIASED_POINT_SIZE_RANGE:
1624 	case GL_DEPTH_RANGE:
1625 		{
1626 			*type = GL_FLOAT;
1627 			*numParams = 2;
1628 		}
1629 		break;
1630 	case GL_COLOR_CLEAR_VALUE:
1631 	case GL_BLEND_COLOR:
1632 		{
1633 			*type = GL_FLOAT;
1634 			*numParams = 4;
1635 		}
1636 		break;
1637 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1638 		*type = GL_FLOAT;
1639 		*numParams = 1;
1640 		break;
1641 	default:
1642 		return false;
1643 	}
1644 
1645 	return true;
1646 }
1647 
1648 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()1649 bool Context::applyRenderTarget()
1650 {
1651 	Framebuffer *framebuffer = getDrawFramebuffer();
1652 	int width, height, samples;
1653 
1654 	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
1655 	{
1656 		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
1657 	}
1658 
1659 	Image *renderTarget = framebuffer->getRenderTarget();
1660 	device->setRenderTarget(0, renderTarget);
1661 	if(renderTarget) renderTarget->release();
1662 
1663 	Image *depthStencil = framebuffer->getDepthStencil();
1664 	device->setDepthStencilSurface(depthStencil);
1665 	if(depthStencil) depthStencil->release();
1666 
1667 	Viewport viewport;
1668 	float zNear = clamp01(mState.zNear);
1669 	float zFar = clamp01(mState.zFar);
1670 
1671 	viewport.x0 = mState.viewportX;
1672 	viewport.y0 = mState.viewportY;
1673 	viewport.width = mState.viewportWidth;
1674 	viewport.height = mState.viewportHeight;
1675 	viewport.minZ = zNear;
1676 	viewport.maxZ = zFar;
1677 
1678 	device->setViewport(viewport);
1679 
1680 	if(mState.scissorTestEnabled)
1681 	{
1682 		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1683 		scissor.clip(0, 0, width, height);
1684 
1685 		device->setScissorRect(scissor);
1686 		device->setScissorEnable(true);
1687 	}
1688 	else
1689 	{
1690 		device->setScissorEnable(false);
1691 	}
1692 
1693 	Program *program = getCurrentProgram();
1694 
1695 	if(program)
1696 	{
1697 		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
1698 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
1699 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
1700 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
1701 	}
1702 
1703 	return true;
1704 }
1705 
1706 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)1707 void Context::applyState(GLenum drawMode)
1708 {
1709 	Framebuffer *framebuffer = getDrawFramebuffer();
1710 
1711 	if(mState.cullFaceEnabled)
1712 	{
1713 		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
1714 	}
1715 	else
1716 	{
1717 		device->setCullMode(sw::CULL_NONE);
1718 	}
1719 
1720 	if(mDepthStateDirty)
1721 	{
1722 		if(mState.depthTestEnabled)
1723 		{
1724 			device->setDepthBufferEnable(true);
1725 			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1726 		}
1727 		else
1728 		{
1729 			device->setDepthBufferEnable(false);
1730 		}
1731 
1732 		mDepthStateDirty = false;
1733 	}
1734 
1735 	if(mBlendStateDirty)
1736 	{
1737 		if(mState.blendEnabled)
1738 		{
1739 			device->setAlphaBlendEnable(true);
1740 			device->setSeparateAlphaBlendEnable(true);
1741 
1742 			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
1743 
1744 			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1745 			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1746 			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1747 
1748 			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1749 			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1750 			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1751 		}
1752 		else
1753 		{
1754 			device->setAlphaBlendEnable(false);
1755 		}
1756 
1757 		mBlendStateDirty = false;
1758 	}
1759 
1760 	if(mColorLogicOperatorDirty)
1761 	{
1762 		if(mState.colorLogicOpEnabled)
1763 		{
1764 			device->setColorLogicOpEnabled(true);
1765 			device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));
1766 		}
1767 		else
1768 		{
1769 			device->setColorLogicOpEnabled(false);
1770 		}
1771 
1772 		mColorLogicOperatorDirty = false;
1773 	}
1774 
1775 	if(mStencilStateDirty || mFrontFaceDirty)
1776 	{
1777 		if(mState.stencilTestEnabled && framebuffer->hasStencil())
1778 		{
1779 			device->setStencilEnable(true);
1780 			device->setTwoSidedStencil(true);
1781 
1782 			if(mState.stencilWritemask != mState.stencilBackWritemask ||
1783 			   mState.stencilRef != mState.stencilBackRef ||
1784 			   mState.stencilMask != mState.stencilBackMask)
1785 			{
1786 				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
1787 				return error(GL_INVALID_OPERATION);
1788 			}
1789 
1790 			// get the maximum size of the stencil ref
1791 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1792 			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1793 
1794 			if(mState.frontFace == GL_CCW)
1795 			{
1796 				device->setStencilWriteMask(mState.stencilWritemask);
1797 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1798 
1799 				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1800 				device->setStencilMask(mState.stencilMask);
1801 
1802 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1803 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1804 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1805 
1806 				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
1807 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1808 
1809 				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1810 				device->setStencilMaskCCW(mState.stencilBackMask);
1811 
1812 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
1813 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1814 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1815 			}
1816 			else
1817 			{
1818 				device->setStencilWriteMaskCCW(mState.stencilWritemask);
1819 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1820 
1821 				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1822 				device->setStencilMaskCCW(mState.stencilMask);
1823 
1824 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1825 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1826 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1827 
1828 				device->setStencilWriteMask(mState.stencilBackWritemask);
1829 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1830 
1831 				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1832 				device->setStencilMask(mState.stencilBackMask);
1833 
1834 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
1835 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1836 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1837 			}
1838 		}
1839 		else
1840 		{
1841 			device->setStencilEnable(false);
1842 		}
1843 
1844 		mStencilStateDirty = false;
1845 		mFrontFaceDirty = false;
1846 	}
1847 
1848 	if(mMaskStateDirty)
1849 	{
1850 		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1851 		device->setDepthWriteEnable(mState.depthMask);
1852 
1853 		mMaskStateDirty = false;
1854 	}
1855 
1856 	if(mPolygonOffsetStateDirty)
1857 	{
1858 		if(mState.polygonOffsetFillEnabled)
1859 		{
1860 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1861 			if(depthbuffer)
1862 			{
1863 				device->setSlopeDepthBias(mState.polygonOffsetFactor);
1864 				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1865 				device->setDepthBias(depthBias);
1866 			}
1867 		}
1868 		else
1869 		{
1870 			device->setSlopeDepthBias(0);
1871 			device->setDepthBias(0);
1872 		}
1873 
1874 		mPolygonOffsetStateDirty = false;
1875 	}
1876 
1877 	if(mSampleStateDirty)
1878 	{
1879 		if(mState.sampleAlphaToCoverageEnabled)
1880 		{
1881 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1882 		}
1883 		else
1884 		{
1885 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1886 		}
1887 
1888 		if(mState.sampleCoverageEnabled)
1889 		{
1890 			unsigned int mask = 0;
1891 			if(mState.sampleCoverageValue != 0)
1892 			{
1893 				int width, height, samples;
1894 				framebuffer->completeness(width, height, samples);
1895 
1896 				float threshold = 0.5f;
1897 
1898 				for(int i = 0; i < samples; i++)
1899 				{
1900 					mask <<= 1;
1901 
1902 					if((i + 1) * mState.sampleCoverageValue >= threshold)
1903 					{
1904 						threshold += 1.0f;
1905 						mask |= 1;
1906 					}
1907 				}
1908 			}
1909 
1910 			if(mState.sampleCoverageInvert)
1911 			{
1912 				mask = ~mask;
1913 			}
1914 
1915 			device->setMultiSampleMask(mask);
1916 		}
1917 		else
1918 		{
1919 			device->setMultiSampleMask(0xFFFFFFFF);
1920 		}
1921 
1922 		mSampleStateDirty = false;
1923 	}
1924 
1925 	if(mDitherStateDirty)
1926 	{
1927 	//	UNIMPLEMENTED();   // FIXME
1928 
1929 		mDitherStateDirty = false;
1930 	}
1931 }
1932 
applyVertexBuffer(GLint base,GLint first,GLsizei count)1933 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
1934 {
1935 	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
1936 
1937 	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
1938 	if(err != GL_NO_ERROR)
1939 	{
1940 		return err;
1941 	}
1942 
1943 	Program *program = getCurrentProgram();
1944 
1945 	device->resetInputStreams(false);
1946 
1947 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
1948 	{
1949 		if(program && program->getAttributeStream(i) == -1)
1950 		{
1951 			continue;
1952 		}
1953 
1954 		sw::Resource *resource = attributes[i].vertexBuffer;
1955 		const void *buffer = (char*)resource->data() + attributes[i].offset;
1956 
1957 		int stride = attributes[i].stride;
1958 
1959 		buffer = (char*)buffer + stride * base;
1960 
1961 		sw::Stream attribute(resource, buffer, stride);
1962 
1963 		attribute.type = attributes[i].type;
1964 		attribute.count = attributes[i].count;
1965 		attribute.normalized = attributes[i].normalized;
1966 
1967 		int stream = program ? program->getAttributeStream(i) : i;
1968 		device->setInputStream(stream, attribute);
1969 	}
1970 
1971 	return GL_NO_ERROR;
1972 }
1973 
1974 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)1975 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
1976 {
1977 	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
1978 
1979 	if(err == GL_NO_ERROR)
1980 	{
1981 		device->setIndexBuffer(indexInfo->indexBuffer);
1982 	}
1983 
1984 	return err;
1985 }
1986 
1987 // Applies the shaders and shader constants
applyShaders()1988 void Context::applyShaders()
1989 {
1990 	Program *programObject = getCurrentProgram();
1991 	if(!programObject)
1992 	{
1993 		device->setVertexShader(0);
1994 		device->setPixelShader(0);
1995 		return;
1996 	}
1997 	sw::VertexShader *vertexShader = programObject->getVertexShader();
1998 	sw::PixelShader *pixelShader = programObject->getPixelShader();
1999 
2000 	device->setVertexShader(vertexShader);
2001 	device->setPixelShader(pixelShader);
2002 
2003 	if(programObject->getSerial() != mAppliedProgramSerial)
2004 	{
2005 		programObject->dirtyAllUniforms();
2006 		mAppliedProgramSerial = programObject->getSerial();
2007 	}
2008 
2009 	programObject->applyUniforms();
2010 }
2011 
applyTextures()2012 void Context::applyTextures()
2013 {
2014 	applyTextures(sw::SAMPLER_PIXEL);
2015 	//applyTextures(sw::SAMPLER_VERTEX);
2016 }
2017 
applyTextures(sw::SamplerType samplerType)2018 void Context::applyTextures(sw::SamplerType samplerType)
2019 {
2020 	Program *programObject = getCurrentProgram();
2021 
2022 	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
2023 
2024 	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
2025 	{
2026 		int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex;   // OpenGL texture image unit index
2027 
2028 		if(textureUnit != -1)
2029 		{
2030 			TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D;
2031 
2032 			Texture *texture = getSamplerTexture(textureUnit, textureType);
2033 
2034 			if(envEnable[samplerIndex] && texture->isSamplerComplete())
2035 			{
2036 				GLenum wrapS = texture->getWrapS();
2037 				GLenum wrapT = texture->getWrapT();
2038 				GLenum minFilter = texture->getMinFilter();
2039 				GLenum magFilter = texture->getMagFilter();
2040 				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2041 
2042 				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
2043 				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
2044 
2045 				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
2046 				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
2047 				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
2048 
2049 				applyTexture(samplerType, samplerIndex, texture);
2050 
2051 				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE);
2052 				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
2053 				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2054 				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2055 
2056 				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE);
2057 				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
2058 				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2059 				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2060 
2061 				//device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f));
2062 			}
2063 			else
2064 			{
2065 				applyTexture(samplerType, samplerIndex, nullptr);
2066 
2067 				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
2068 				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2069 				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2070 				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2071 
2072 				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
2073 				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2074 				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2075 				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2076 			}
2077 		}
2078 		else
2079 		{
2080 			applyTexture(samplerType, samplerIndex, nullptr);
2081 		}
2082 	}
2083 }
2084 
applyTexture(sw::SamplerType type,int index,Texture * baseTexture)2085 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
2086 {
2087 	Program *program = getCurrentProgram();
2088 	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
2089 	bool textureUsed = false;
2090 
2091 	if(type == sw::SAMPLER_PIXEL)
2092 	{
2093 		textureUsed = program ? program->getPixelShader()->usesSampler(index) : true;
2094 	}
2095 	else if(type == sw::SAMPLER_VERTEX)
2096 	{
2097 		textureUsed = program ? program->getVertexShader()->usesSampler(index) : false;
2098 	}
2099 	else UNREACHABLE(type);
2100 
2101 	sw::Resource *resource = nullptr;
2102 
2103 	if(baseTexture && textureUsed)
2104 	{
2105 		resource = baseTexture->getResource();
2106 	}
2107 
2108 	device->setTextureResource(sampler, resource);
2109 
2110 	if(baseTexture && textureUsed)
2111 	{
2112 		int levelCount = baseTexture->getLevelCount();
2113 
2114 		if(baseTexture->getTarget() == GL_TEXTURE_2D)
2115 		{
2116 			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2117 
2118 			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2119 			{
2120 				int surfaceLevel = mipmapLevel;
2121 
2122 				if(surfaceLevel < 0)
2123 				{
2124 					surfaceLevel = 0;
2125 				}
2126 				else if(surfaceLevel >= levelCount)
2127 				{
2128 					surfaceLevel = levelCount - 1;
2129 				}
2130 
2131 				Image *surface = texture->getImage(surfaceLevel);
2132 				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2133 			}
2134 		}
2135 		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
2136 		{
2137 			for(int face = 0; face < 6; face++)
2138 			{
2139 				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
2140 
2141 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2142 				{
2143 					int surfaceLevel = mipmapLevel;
2144 
2145 					if(surfaceLevel < 0)
2146 					{
2147 						surfaceLevel = 0;
2148 					}
2149 					else if(surfaceLevel >= levelCount)
2150 					{
2151 						surfaceLevel = levelCount - 1;
2152 					}
2153 
2154 					Image *surface = cubeTexture->getImage(face, surfaceLevel);
2155 					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
2156 				}
2157 			}
2158 		}
2159 		else UNIMPLEMENTED();
2160 	}
2161 	else
2162 	{
2163 		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
2164 	}
2165 }
2166 
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)2167 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2168                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2169 {
2170 	Framebuffer *framebuffer = getReadFramebuffer();
2171 	int framebufferWidth, framebufferHeight, framebufferSamples;
2172 
2173 	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2174 	{
2175 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2176 	}
2177 
2178 	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
2179 	{
2180 		return error(GL_INVALID_OPERATION);
2181 	}
2182 
2183 	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
2184 
2185 	// Sized query sanity check
2186 	if(bufSize)
2187 	{
2188 		int requiredSize = outputPitch * height;
2189 		if(requiredSize > *bufSize)
2190 		{
2191 			return error(GL_INVALID_OPERATION);
2192 		}
2193 	}
2194 
2195 	Image *renderTarget = framebuffer->getRenderTarget();
2196 
2197 	if(!renderTarget)
2198 	{
2199 		return error(GL_OUT_OF_MEMORY);
2200 	}
2201 
2202 	sw::Rect rect = {x, y, x + width, y + height};
2203 	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2204 
2205 	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2206 	unsigned char *dest = (unsigned char*)pixels;
2207 	unsigned short *dest16 = (unsigned short*)pixels;
2208 	int inputPitch = (int)renderTarget->getPitch();
2209 
2210 	for(int j = 0; j < rect.y1 - rect.y0; j++)
2211 	{
2212 		if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2213 		   format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2214 		{
2215 			// Fast path for EXT_read_format_bgra, given an RGBA source buffer
2216 			// Note that buffers with no alpha go through the slow path below
2217 			memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
2218 		}
2219 		else
2220 		{
2221 			for(int i = 0; i < rect.x1 - rect.x0; i++)
2222 			{
2223 				float r;
2224 				float g;
2225 				float b;
2226 				float a;
2227 
2228 				switch(renderTarget->getInternalFormat())
2229 				{
2230 				case sw::FORMAT_R5G6B5:
2231 					{
2232 						unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2233 
2234 						a = 1.0f;
2235 						b = (rgb & 0x001F) * (1.0f / 0x001F);
2236 						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2237 						r = (rgb & 0xF800) * (1.0f / 0xF800);
2238 					}
2239 					break;
2240 				case sw::FORMAT_A1R5G5B5:
2241 					{
2242 						unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2243 
2244 						a = (argb & 0x8000) ? 1.0f : 0.0f;
2245 						b = (argb & 0x001F) * (1.0f / 0x001F);
2246 						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2247 						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2248 					}
2249 					break;
2250 				case sw::FORMAT_A8R8G8B8:
2251 					{
2252 						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2253 
2254 						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2255 						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2256 						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2257 						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2258 					}
2259 					break;
2260 				case sw::FORMAT_X8R8G8B8:
2261 					{
2262 						unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2263 
2264 						a = 1.0f;
2265 						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2266 						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2267 						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2268 					}
2269 					break;
2270 				case sw::FORMAT_A2R10G10B10:
2271 					{
2272 						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2273 
2274 						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2275 						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2276 						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2277 						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2278 					}
2279 					break;
2280 				case sw::FORMAT_A32B32G32R32F:
2281 					{
2282 						r = *((float*)(source + 16 * i + j * inputPitch) + 0);
2283 						g = *((float*)(source + 16 * i + j * inputPitch) + 1);
2284 						b = *((float*)(source + 16 * i + j * inputPitch) + 2);
2285 						a = *((float*)(source + 16 * i + j * inputPitch) + 3);
2286 					}
2287 					break;
2288 				case sw::FORMAT_A16B16G16R16F:
2289 					{
2290 						r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
2291 						g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
2292 						b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
2293 						a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
2294 					}
2295 					break;
2296 				default:
2297 					UNIMPLEMENTED();   // FIXME
2298 					UNREACHABLE(renderTarget->getInternalFormat());
2299 				}
2300 
2301 				switch(format)
2302 				{
2303 				case GL_RGBA:
2304 					switch(type)
2305 					{
2306 					case GL_UNSIGNED_BYTE:
2307 						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
2308 						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2309 						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
2310 						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2311 						break;
2312 					default: UNREACHABLE(type);
2313 					}
2314 					break;
2315 				case GL_BGRA_EXT:
2316 					switch(type)
2317 					{
2318 					case GL_UNSIGNED_BYTE:
2319 						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
2320 						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2321 						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
2322 						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2323 						break;
2324 					case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2325 						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2326 						// this type is packed as follows:
2327 						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2328 						//  --------------------------------------------------------------------------------
2329 						// |       4th         |        3rd         |        2nd        |   1st component   |
2330 						//  --------------------------------------------------------------------------------
2331 						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2332 						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2333 							((unsigned short)(15 * a + 0.5f) << 12)|
2334 							((unsigned short)(15 * r + 0.5f) << 8) |
2335 							((unsigned short)(15 * g + 0.5f) << 4) |
2336 							((unsigned short)(15 * b + 0.5f) << 0);
2337 						break;
2338 					case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2339 						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2340 						// this type is packed as follows:
2341 						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2342 						//  --------------------------------------------------------------------------------
2343 						// | 4th |          3rd           |           2nd          |      1st component     |
2344 						//  --------------------------------------------------------------------------------
2345 						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2346 						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2347 							((unsigned short)(     a + 0.5f) << 15) |
2348 							((unsigned short)(31 * r + 0.5f) << 10) |
2349 							((unsigned short)(31 * g + 0.5f) << 5) |
2350 							((unsigned short)(31 * b + 0.5f) << 0);
2351 						break;
2352 					default: UNREACHABLE(type);
2353 					}
2354 					break;
2355 				case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT
2356 					switch(type)
2357 					{
2358 					case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE
2359 						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2360 							((unsigned short)(31 * b + 0.5f) << 0) |
2361 							((unsigned short)(63 * g + 0.5f) << 5) |
2362 							((unsigned short)(31 * r + 0.5f) << 11);
2363 						break;
2364 					default: UNREACHABLE(type);
2365 					}
2366 					break;
2367 				default: UNREACHABLE(format);
2368 				}
2369 			}
2370 		}
2371 	}
2372 
2373 	renderTarget->unlock();
2374 	renderTarget->release();
2375 }
2376 
clear(GLbitfield mask)2377 void Context::clear(GLbitfield mask)
2378 {
2379 	Framebuffer *framebuffer = getDrawFramebuffer();
2380 
2381 	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2382 	{
2383 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2384 	}
2385 
2386 	if(!applyRenderTarget())
2387 	{
2388 		return;
2389 	}
2390 
2391 	float depth = clamp01(mState.depthClearValue);
2392 	int stencil = mState.stencilClearValue & 0x000000FF;
2393 
2394 	if(mask & GL_COLOR_BUFFER_BIT)
2395 	{
2396 		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2397 		                        (mState.colorMaskGreen ? 0x2 : 0) |
2398 		                        (mState.colorMaskBlue ? 0x4 : 0) |
2399 		                        (mState.colorMaskAlpha ? 0x8 : 0);
2400 
2401 		if(rgbaMask != 0)
2402 		{
2403 			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
2404 		}
2405 	}
2406 
2407 	if(mask & GL_DEPTH_BUFFER_BIT)
2408 	{
2409 		if(mState.depthMask != 0)
2410 		{
2411 			device->clearDepth(depth);
2412 		}
2413 	}
2414 
2415 	if(mask & GL_STENCIL_BUFFER_BIT)
2416 	{
2417 		if(mState.stencilWritemask != 0)
2418 		{
2419 			device->clearStencil(stencil, mState.stencilWritemask);
2420 		}
2421 	}
2422 }
2423 
drawArrays(GLenum mode,GLint first,GLsizei count)2424 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2425 {
2426 	if(!mState.currentProgram)
2427 	{
2428 		device->setProjectionMatrix(projection.current());
2429 		device->setViewMatrix(modelView.current());
2430 		device->setTextureMatrix(0, texture[0].current());
2431 		device->setTextureMatrix(1, texture[1].current());
2432 		device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
2433 		device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
2434 		device->setTexGen(0, sw::TEXGEN_NONE);
2435 		device->setTexGen(1, sw::TEXGEN_NONE);
2436 	}
2437 
2438 	PrimitiveType primitiveType;
2439 	int primitiveCount;
2440 
2441 	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2442 		return error(GL_INVALID_ENUM);
2443 
2444 	if(primitiveCount <= 0)
2445 	{
2446 		return;
2447 	}
2448 
2449 	if(!applyRenderTarget())
2450 	{
2451 		return;
2452 	}
2453 
2454 	applyState(mode);
2455 
2456 	GLenum err = applyVertexBuffer(0, first, count);
2457 	if(err != GL_NO_ERROR)
2458 	{
2459 		return error(err);
2460 	}
2461 
2462 	applyShaders();
2463 	applyTextures();
2464 
2465 	if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false))
2466 	{
2467 		return error(GL_INVALID_OPERATION);
2468 	}
2469 
2470 	if(!cullSkipsDraw(mode))
2471 	{
2472 		device->drawPrimitive(primitiveType, primitiveCount);
2473 	}
2474 }
2475 
drawElements(GLenum mode,GLsizei count,GLenum type,const void * indices)2476 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2477 {
2478 	if(!mState.currentProgram)
2479 	{
2480 		return error(GL_INVALID_OPERATION);
2481 	}
2482 
2483 	if(!indices && !mState.elementArrayBuffer)
2484 	{
2485 		return error(GL_INVALID_OPERATION);
2486 	}
2487 
2488 	PrimitiveType primitiveType;
2489 	int primitiveCount;
2490 
2491 	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2492 		return error(GL_INVALID_ENUM);
2493 
2494 	if(primitiveCount <= 0)
2495 	{
2496 		return;
2497 	}
2498 
2499 	if(!applyRenderTarget())
2500 	{
2501 		return;
2502 	}
2503 
2504 	applyState(mode);
2505 
2506 	TranslatedIndexData indexInfo;
2507 	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2508 	if(err != GL_NO_ERROR)
2509 	{
2510 		return error(err);
2511 	}
2512 
2513 	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2514 	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2515 	if(err != GL_NO_ERROR)
2516 	{
2517 		return error(err);
2518 	}
2519 
2520 	applyShaders();
2521 	applyTextures();
2522 
2523 	if(!getCurrentProgram()->validateSamplers(false))
2524 	{
2525 		return error(GL_INVALID_OPERATION);
2526 	}
2527 
2528 	if(!cullSkipsDraw(mode))
2529 	{
2530 		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2531 	}
2532 }
2533 
finish()2534 void Context::finish()
2535 {
2536 	device->finish();
2537 }
2538 
flush()2539 void Context::flush()
2540 {
2541 	// We don't queue anything without processing it as fast as possible
2542 }
2543 
recordInvalidEnum()2544 void Context::recordInvalidEnum()
2545 {
2546 	mInvalidEnum = true;
2547 }
2548 
recordInvalidValue()2549 void Context::recordInvalidValue()
2550 {
2551 	mInvalidValue = true;
2552 }
2553 
recordInvalidOperation()2554 void Context::recordInvalidOperation()
2555 {
2556 	mInvalidOperation = true;
2557 }
2558 
recordOutOfMemory()2559 void Context::recordOutOfMemory()
2560 {
2561 	mOutOfMemory = true;
2562 }
2563 
recordInvalidFramebufferOperation()2564 void Context::recordInvalidFramebufferOperation()
2565 {
2566 	mInvalidFramebufferOperation = true;
2567 }
2568 
2569 // Get one of the recorded errors and clear its flag, if any.
getError()2570 GLenum Context::getError()
2571 {
2572 	if(mInvalidEnum)
2573 	{
2574 		mInvalidEnum = false;
2575 
2576 		return GL_INVALID_ENUM;
2577 	}
2578 
2579 	if(mInvalidValue)
2580 	{
2581 		mInvalidValue = false;
2582 
2583 		return GL_INVALID_VALUE;
2584 	}
2585 
2586 	if(mInvalidOperation)
2587 	{
2588 		mInvalidOperation = false;
2589 
2590 		return GL_INVALID_OPERATION;
2591 	}
2592 
2593 	if(mOutOfMemory)
2594 	{
2595 		mOutOfMemory = false;
2596 
2597 		return GL_OUT_OF_MEMORY;
2598 	}
2599 
2600 	if(mInvalidFramebufferOperation)
2601 	{
2602 		mInvalidFramebufferOperation = false;
2603 
2604 		return GL_INVALID_FRAMEBUFFER_OPERATION;
2605 	}
2606 
2607 	return GL_NO_ERROR;
2608 }
2609 
getSupportedMultisampleCount(int requested)2610 int Context::getSupportedMultisampleCount(int requested)
2611 {
2612 	int supported = 0;
2613 
2614 	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
2615 	{
2616 		if(supported >= requested)
2617 		{
2618 			return supported;
2619 		}
2620 
2621 		supported = multisampleCount[i];
2622 	}
2623 
2624 	return supported;
2625 }
2626 
detachBuffer(GLuint buffer)2627 void Context::detachBuffer(GLuint buffer)
2628 {
2629 	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
2630 	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
2631 
2632 	if(mState.arrayBuffer.name() == buffer)
2633 	{
2634 		mState.arrayBuffer = nullptr;
2635 	}
2636 
2637 	if(mState.elementArrayBuffer.name() == buffer)
2638 	{
2639 		mState.elementArrayBuffer = nullptr;
2640 	}
2641 
2642 	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2643 	{
2644 		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
2645 		{
2646 			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
2647 		}
2648 	}
2649 }
2650 
detachTexture(GLuint texture)2651 void Context::detachTexture(GLuint texture)
2652 {
2653 	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2654 	// rebound to texture object zero
2655 
2656 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2657 	{
2658 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
2659 		{
2660 			if(mState.samplerTexture[type][sampler].name() == texture)
2661 			{
2662 				mState.samplerTexture[type][sampler] = nullptr;
2663 			}
2664 		}
2665 	}
2666 
2667 	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2668 	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2669 	// image was attached in the currently bound framebuffer.
2670 
2671 	Framebuffer *readFramebuffer = getReadFramebuffer();
2672 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
2673 
2674 	if(readFramebuffer)
2675 	{
2676 		readFramebuffer->detachTexture(texture);
2677 	}
2678 
2679 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2680 	{
2681 		drawFramebuffer->detachTexture(texture);
2682 	}
2683 }
2684 
detachFramebuffer(GLuint framebuffer)2685 void Context::detachFramebuffer(GLuint framebuffer)
2686 {
2687 	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2688 	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2689 
2690 	if(mState.readFramebuffer == framebuffer)
2691 	{
2692 		bindReadFramebuffer(0);
2693 	}
2694 
2695 	if(mState.drawFramebuffer == framebuffer)
2696 	{
2697 		bindDrawFramebuffer(0);
2698 	}
2699 }
2700 
detachRenderbuffer(GLuint renderbuffer)2701 void Context::detachRenderbuffer(GLuint renderbuffer)
2702 {
2703 	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2704 	// had been executed with the target RENDERBUFFER and name of zero.
2705 
2706 	if(mState.renderbuffer.name() == renderbuffer)
2707 	{
2708 		bindRenderbuffer(0);
2709 	}
2710 
2711 	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2712 	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2713 	// point to which this image was attached in the currently bound framebuffer.
2714 
2715 	Framebuffer *readFramebuffer = getReadFramebuffer();
2716 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
2717 
2718 	if(readFramebuffer)
2719 	{
2720 		readFramebuffer->detachRenderbuffer(renderbuffer);
2721 	}
2722 
2723 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2724 	{
2725 		drawFramebuffer->detachRenderbuffer(renderbuffer);
2726 	}
2727 }
2728 
cullSkipsDraw(GLenum drawMode)2729 bool Context::cullSkipsDraw(GLenum drawMode)
2730 {
2731 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
2732 }
2733 
isTriangleMode(GLenum drawMode)2734 bool Context::isTriangleMode(GLenum drawMode)
2735 {
2736 	switch(drawMode)
2737 	{
2738 	case GL_TRIANGLES:
2739 	case GL_TRIANGLE_FAN:
2740 	case GL_TRIANGLE_STRIP:
2741 		return true;
2742 	case GL_POINTS:
2743 	case GL_LINES:
2744 	case GL_LINE_LOOP:
2745 	case GL_LINE_STRIP:
2746 		return false;
2747 	default: UNREACHABLE(drawMode);
2748 	}
2749 
2750 	return false;
2751 }
2752 
setVertexAttrib(GLuint index,float x,float y,float z,float w)2753 void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w)
2754 {
2755 	ASSERT(index < MAX_VERTEX_ATTRIBS);
2756 
2757 	mState.vertexAttribute[index].mCurrentValue[0] = x;
2758 	mState.vertexAttribute[index].mCurrentValue[1] = y;
2759 	mState.vertexAttribute[index].mCurrentValue[2] = z;
2760 	mState.vertexAttribute[index].mCurrentValue[3] = w;
2761 
2762 	mVertexDataManager->dirtyCurrentValue(index);
2763 }
2764 
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask)2765 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2766                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2767                               GLbitfield mask)
2768 {
2769 	Framebuffer *readFramebuffer = getReadFramebuffer();
2770 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
2771 
2772 	int readBufferWidth, readBufferHeight, readBufferSamples;
2773 	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
2774 
2775 	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
2776 	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2777 	{
2778 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2779 	}
2780 
2781 	if(drawBufferSamples > 1)
2782 	{
2783 		return error(GL_INVALID_OPERATION);
2784 	}
2785 
2786 	sw::SliceRect sourceRect;
2787 	sw::SliceRect destRect;
2788 
2789 	if(srcX0 < srcX1)
2790 	{
2791 		sourceRect.x0 = srcX0;
2792 		sourceRect.x1 = srcX1;
2793 		destRect.x0 = dstX0;
2794 		destRect.x1 = dstX1;
2795 	}
2796 	else
2797 	{
2798 		sourceRect.x0 = srcX1;
2799 		destRect.x0 = dstX1;
2800 		sourceRect.x1 = srcX0;
2801 		destRect.x1 = dstX0;
2802 	}
2803 
2804 	if(srcY0 < srcY1)
2805 	{
2806 		sourceRect.y0 = srcY0;
2807 		destRect.y0 = dstY0;
2808 		sourceRect.y1 = srcY1;
2809 		destRect.y1 = dstY1;
2810 	}
2811 	else
2812 	{
2813 		sourceRect.y0 = srcY1;
2814 		destRect.y0 = dstY1;
2815 		sourceRect.y1 = srcY0;
2816 		destRect.y1 = dstY0;
2817 	}
2818 
2819 	sw::Rect sourceScissoredRect = sourceRect;
2820 	sw::Rect destScissoredRect = destRect;
2821 
2822 	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
2823 	{
2824 		if(destRect.x0 < mState.scissorX)
2825 		{
2826 			int xDiff = mState.scissorX - destRect.x0;
2827 			destScissoredRect.x0 = mState.scissorX;
2828 			sourceScissoredRect.x0 += xDiff;
2829 		}
2830 
2831 		if(destRect.x1 > mState.scissorX + mState.scissorWidth)
2832 		{
2833 			int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
2834 			destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
2835 			sourceScissoredRect.x1 -= xDiff;
2836 		}
2837 
2838 		if(destRect.y0 < mState.scissorY)
2839 		{
2840 			int yDiff = mState.scissorY - destRect.y0;
2841 			destScissoredRect.y0 = mState.scissorY;
2842 			sourceScissoredRect.y0 += yDiff;
2843 		}
2844 
2845 		if(destRect.y1 > mState.scissorY + mState.scissorHeight)
2846 		{
2847 			int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
2848 			destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
2849 			sourceScissoredRect.y1 -= yDiff;
2850 		}
2851 	}
2852 
2853 	sw::Rect sourceTrimmedRect = sourceScissoredRect;
2854 	sw::Rect destTrimmedRect = destScissoredRect;
2855 
2856 	// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
2857 	// the actual draw and read surfaces.
2858 	if(sourceTrimmedRect.x0 < 0)
2859 	{
2860 		int xDiff = 0 - sourceTrimmedRect.x0;
2861 		sourceTrimmedRect.x0 = 0;
2862 		destTrimmedRect.x0 += xDiff;
2863 	}
2864 
2865 	if(sourceTrimmedRect.x1 > readBufferWidth)
2866 	{
2867 		int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
2868 		sourceTrimmedRect.x1 = readBufferWidth;
2869 		destTrimmedRect.x1 -= xDiff;
2870 	}
2871 
2872 	if(sourceTrimmedRect.y0 < 0)
2873 	{
2874 		int yDiff = 0 - sourceTrimmedRect.y0;
2875 		sourceTrimmedRect.y0 = 0;
2876 		destTrimmedRect.y0 += yDiff;
2877 	}
2878 
2879 	if(sourceTrimmedRect.y1 > readBufferHeight)
2880 	{
2881 		int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
2882 		sourceTrimmedRect.y1 = readBufferHeight;
2883 		destTrimmedRect.y1 -= yDiff;
2884 	}
2885 
2886 	if(destTrimmedRect.x0 < 0)
2887 	{
2888 		int xDiff = 0 - destTrimmedRect.x0;
2889 		destTrimmedRect.x0 = 0;
2890 		sourceTrimmedRect.x0 += xDiff;
2891 	}
2892 
2893 	if(destTrimmedRect.x1 > drawBufferWidth)
2894 	{
2895 		int xDiff = destTrimmedRect.x1 - drawBufferWidth;
2896 		destTrimmedRect.x1 = drawBufferWidth;
2897 		sourceTrimmedRect.x1 -= xDiff;
2898 	}
2899 
2900 	if(destTrimmedRect.y0 < 0)
2901 	{
2902 		int yDiff = 0 - destTrimmedRect.y0;
2903 		destTrimmedRect.y0 = 0;
2904 		sourceTrimmedRect.y0 += yDiff;
2905 	}
2906 
2907 	if(destTrimmedRect.y1 > drawBufferHeight)
2908 	{
2909 		int yDiff = destTrimmedRect.y1 - drawBufferHeight;
2910 		destTrimmedRect.y1 = drawBufferHeight;
2911 		sourceTrimmedRect.y1 -= yDiff;
2912 	}
2913 
2914 	bool partialBufferCopy = false;
2915 
2916 	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
2917 	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
2918 	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
2919 	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
2920 	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
2921 	{
2922 		partialBufferCopy = true;
2923 	}
2924 
2925 	bool blitRenderTarget = false;
2926 	bool blitDepthStencil = false;
2927 
2928 	if(mask & GL_COLOR_BUFFER_BIT)
2929 	{
2930 		const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2931 		                           readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2932 		const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2933 		                           drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2934 		if(!validReadType || !validDrawType ||
2935 		   readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
2936 		{
2937 			ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
2938 			return error(GL_INVALID_OPERATION);
2939 		}
2940 
2941 		if(partialBufferCopy && readBufferSamples > 1)
2942 		{
2943 			return error(GL_INVALID_OPERATION);
2944 		}
2945 
2946 		blitRenderTarget = true;
2947 	}
2948 
2949 	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
2950 	{
2951 		Renderbuffer *readDSBuffer = nullptr;
2952 		Renderbuffer *drawDSBuffer = nullptr;
2953 
2954 		// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
2955 		// both a depth and stencil buffer, it will be the same buffer.
2956 
2957 		if(mask & GL_DEPTH_BUFFER_BIT)
2958 		{
2959 			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2960 			{
2961 				if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
2962 				   readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
2963 				{
2964 					return error(GL_INVALID_OPERATION);
2965 				}
2966 
2967 				blitDepthStencil = true;
2968 				readDSBuffer = readFramebuffer->getDepthbuffer();
2969 				drawDSBuffer = drawFramebuffer->getDepthbuffer();
2970 			}
2971 		}
2972 
2973 		if(mask & GL_STENCIL_BUFFER_BIT)
2974 		{
2975 			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2976 			{
2977 				if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
2978 				   readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
2979 				{
2980 					return error(GL_INVALID_OPERATION);
2981 				}
2982 
2983 				blitDepthStencil = true;
2984 				readDSBuffer = readFramebuffer->getStencilbuffer();
2985 				drawDSBuffer = drawFramebuffer->getStencilbuffer();
2986 			}
2987 		}
2988 
2989 		if(partialBufferCopy)
2990 		{
2991 			ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
2992 			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
2993 		}
2994 
2995 		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
2996 		   (readDSBuffer && readDSBuffer->getSamples() > 1))
2997 		{
2998 			return error(GL_INVALID_OPERATION);
2999 		}
3000 	}
3001 
3002 	if(blitRenderTarget || blitDepthStencil)
3003 	{
3004 		if(blitRenderTarget)
3005 		{
3006 			Image *readRenderTarget = readFramebuffer->getRenderTarget();
3007 			Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
3008 
3009 			bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
3010 
3011 			readRenderTarget->release();
3012 			drawRenderTarget->release();
3013 
3014 			if(!success)
3015 			{
3016 				ERR("BlitFramebufferANGLE failed.");
3017 				return;
3018 			}
3019 		}
3020 
3021 		if(blitDepthStencil)
3022 		{
3023 			bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false);
3024 
3025 			if(!success)
3026 			{
3027 				ERR("BlitFramebufferANGLE failed.");
3028 				return;
3029 			}
3030 		}
3031 	}
3032 }
3033 
setMatrixMode(GLenum mode)3034 void Context::setMatrixMode(GLenum mode)
3035 {
3036 	matrixMode = mode;
3037 }
3038 
currentMatrixStack()3039 sw::MatrixStack &Context::currentMatrixStack()
3040 {
3041 	switch(matrixMode)
3042 	{
3043 	case GL_MODELVIEW:  return modelView;                     break;
3044 	case GL_PROJECTION: return projection;                    break;
3045 	case GL_TEXTURE:    return texture[mState.activeSampler]; break;
3046 	default:            UNREACHABLE(matrixMode); return modelView;      break;
3047 	}
3048 }
3049 
loadIdentity()3050 void Context::loadIdentity()
3051 {
3052 	if(drawing)
3053 	{
3054 		return error(GL_INVALID_OPERATION);
3055 	}
3056 
3057 	currentMatrixStack().identity();
3058 }
3059 
pushMatrix()3060 void Context::pushMatrix()
3061 {
3062 	//if(drawing)
3063 	//{
3064 	//    return error(GL_INVALID_OPERATION);
3065 	//}
3066 
3067 	if(!currentMatrixStack().push())
3068 	{
3069 		return error(GL_STACK_OVERFLOW);
3070 	}
3071 }
3072 
popMatrix()3073 void Context::popMatrix()
3074 {
3075 	//if(drawing)
3076 	//{
3077 	//    return error(GL_INVALID_OPERATION);
3078 	//}
3079 
3080 	if(!currentMatrixStack().pop())
3081 	{
3082 		return error(GL_STACK_OVERFLOW);
3083 	}
3084 }
3085 
rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3086 void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3087 {
3088 	if(drawing)
3089 	{
3090 		return error(GL_INVALID_OPERATION);
3091 	}
3092 
3093 	currentMatrixStack().rotate(angle, x, y, z);
3094 }
3095 
translate(GLfloat x,GLfloat y,GLfloat z)3096 void Context::translate(GLfloat x, GLfloat y, GLfloat z)
3097 {
3098 	if(drawing)
3099 	{
3100 		return error(GL_INVALID_OPERATION);
3101 	}
3102 
3103 	currentMatrixStack().translate(x, y, z);
3104 }
3105 
scale(GLfloat x,GLfloat y,GLfloat z)3106 void Context::scale(GLfloat x, GLfloat y, GLfloat z)
3107 {
3108 	if(drawing)
3109 	{
3110 		return error(GL_INVALID_OPERATION);
3111 	}
3112 
3113 	currentMatrixStack().scale(x, y, z);
3114 }
3115 
multiply(const GLdouble * m)3116 void Context::multiply(const GLdouble *m)
3117 {
3118 	if(drawing)
3119 	{
3120 		return error(GL_INVALID_OPERATION);
3121 	}
3122 
3123 	currentMatrixStack().multiply(m);
3124 }
3125 
multiply(const GLfloat * m)3126 void Context::multiply(const GLfloat *m)
3127 {
3128 	if(drawing)
3129 	{
3130 		return error(GL_INVALID_OPERATION);
3131 	}
3132 
3133 	currentMatrixStack().multiply(m);
3134 }
3135 
frustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar)3136 void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
3137 {
3138 	if(drawing)
3139 	{
3140 		return error(GL_INVALID_OPERATION);
3141 	}
3142 
3143 	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
3144 }
3145 
ortho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar)3146 void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
3147 {
3148 	if(drawing)
3149 	{
3150 		return error(GL_INVALID_OPERATION);
3151 	}
3152 
3153 	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
3154 }
3155 
setLightingEnabled(bool enable)3156 void Context::setLightingEnabled(bool enable)
3157 {
3158 	if(drawing)
3159 	{
3160 		return error(GL_INVALID_OPERATION);
3161 	}
3162 
3163 	device->setLightingEnable(enable);
3164 }
3165 
setFogEnabled(bool enable)3166 void Context::setFogEnabled(bool enable)
3167 {
3168 	if(drawing)
3169 	{
3170 		return error(GL_INVALID_OPERATION);
3171 	}
3172 
3173 	device->setFogEnable(enable);
3174 }
3175 
setAlphaTestEnabled(bool enable)3176 void Context::setAlphaTestEnabled(bool enable)
3177 {
3178 	if(drawing)
3179 	{
3180 		return error(GL_INVALID_OPERATION);
3181 	}
3182 
3183 	device->setAlphaTestEnable(enable);
3184 }
3185 
alphaFunc(GLenum func,GLclampf ref)3186 void Context::alphaFunc(GLenum func, GLclampf ref)
3187 {
3188 	if(drawing)
3189 	{
3190 		return error(GL_INVALID_OPERATION);
3191 	}
3192 
3193 	switch(func)
3194 	{
3195 	case GL_NEVER:    device->setAlphaCompare(sw::ALPHA_NEVER);        break;
3196 	case GL_LESS:     device->setAlphaCompare(sw::ALPHA_LESS);         break;
3197 	case GL_EQUAL:    device->setAlphaCompare(sw::ALPHA_EQUAL);        break;
3198 	case GL_LEQUAL:   device->setAlphaCompare(sw::ALPHA_LESSEQUAL);    break;
3199 	case GL_GREATER:  device->setAlphaCompare(sw::ALPHA_GREATER);      break;
3200 	case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL);     break;
3201 	case GL_GEQUAL:   device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break;
3202 	case GL_ALWAYS:   device->setAlphaCompare(sw::ALPHA_ALWAYS);       break;
3203 	default: UNREACHABLE(func);
3204 	}
3205 
3206 	device->setAlphaReference(gl::clamp01(ref));
3207 }
3208 
setTexture2DEnabled(bool enable)3209 void Context::setTexture2DEnabled(bool enable)
3210 {
3211 	if(drawing)
3212 	{
3213 		return error(GL_INVALID_OPERATION);
3214 	}
3215 
3216 	envEnable[mState.activeSampler] = enable;
3217 }
3218 
setShadeModel(GLenum mode)3219 void Context::setShadeModel(GLenum mode)
3220 {
3221 	//if(drawing)
3222 	//{
3223 	//    return error(GL_INVALID_OPERATION);
3224 	//}
3225 
3226 	switch(mode)
3227 	{
3228 	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
3229 	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
3230 	default: return error(GL_INVALID_ENUM);
3231 	}
3232 }
3233 
setLightEnabled(int index,bool enable)3234 void Context::setLightEnabled(int index, bool enable)
3235 {
3236 	device->setLightEnable(index, enable);
3237 }
3238 
setNormalizeNormalsEnabled(bool enable)3239 void Context::setNormalizeNormalsEnabled(bool enable)
3240 {
3241 	device->setNormalizeNormals(enable);
3242 }
3243 
genLists(GLsizei range)3244 GLuint Context::genLists(GLsizei range)
3245 {
3246 	if(drawing)
3247 	{
3248 		return error(GL_INVALID_OPERATION, 0);
3249 	}
3250 
3251 	int firstIndex = std::max(1u, firstFreeIndex);
3252 	for(; true; firstIndex++)
3253 	{
3254 		int empty = 0;
3255 		for(; empty < range; empty++)
3256 		{
3257 			if(displayList[firstIndex + empty] != 0)
3258 			{
3259 				break;
3260 			}
3261 		}
3262 
3263 		if(empty == range)
3264 		{
3265 			for(int i = firstIndex; i < firstIndex + range; i++)
3266 			{
3267 				displayList[i] = new DisplayList();
3268 			}
3269 
3270 			if(firstIndex == firstFreeIndex)
3271 			{
3272 				firstFreeIndex = firstIndex + range;
3273 			}
3274 
3275 			return firstIndex;
3276 		}
3277 	}
3278 
3279 	return 0;
3280 }
3281 
newList(GLuint list,GLenum mode)3282 void Context::newList(GLuint list, GLenum mode)
3283 {
3284 	if(drawing || listIndex != 0)
3285 	{
3286 		return error(GL_INVALID_OPERATION);
3287 	}
3288 
3289 	ASSERT(!this->list);
3290 	this->list = new DisplayList();
3291 
3292 	listIndex = list;
3293 	listMode = mode;
3294 }
3295 
endList()3296 void Context::endList()
3297 {
3298 	if(drawing || listIndex == 0)
3299 	{
3300 		return error(GL_INVALID_OPERATION);
3301 	}
3302 
3303 	ASSERT(list);
3304 	delete displayList[listIndex];
3305 	displayList[listIndex] = list;
3306 	list = 0;
3307 
3308 	listIndex = 0;
3309 	listMode = 0;
3310 }
3311 
callList(GLuint list)3312 void Context::callList(GLuint list)
3313 {
3314 	// As per GL specifications, if the list does not exist, it is ignored
3315 	if(displayList[list])
3316 	{
3317 		displayList[list]->call();
3318 	}
3319 }
3320 
deleteList(GLuint list)3321 void Context::deleteList(GLuint list)
3322 {
3323 	delete displayList[list];
3324 	displayList[list] = 0;
3325 	displayList.erase(list);
3326 	firstFreeIndex = std::min(firstFreeIndex , list);
3327 }
3328 
listCommand(Command * command)3329 void Context::listCommand(Command *command)
3330 {
3331 	ASSERT(list);
3332 	list->list.push_back(command);
3333 
3334 	if(listMode == GL_COMPILE_AND_EXECUTE)
3335 	{
3336 		listMode = 0;
3337 		command->call();
3338 		listMode = GL_COMPILE_AND_EXECUTE;
3339 	}
3340 }
3341 
glVertexAttribArray(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)3342 void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
3343 {
3344 	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
3345 	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
3346 	      index, size, type, normalized, stride, ptr);
3347 
3348 	gl::Context *context = gl::getContext();
3349 
3350 	if(context)
3351 	{
3352 		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
3353 		context->setVertexAttribArrayEnabled(index, ptr != 0);
3354 	}
3355 }
3356 
captureAttribs()3357 void Context::captureAttribs()
3358 {
3359 	memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));
3360 }
3361 
captureDrawArrays(GLenum mode,GLint first,GLsizei count)3362 void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count)
3363 {
3364 	ASSERT(first == 0);   // FIXME: UNIMPLEMENTED!
3365 
3366 	for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3367 	{
3368 		GLint size = mState.vertexAttribute[i].mSize;
3369 		GLenum type = mState.vertexAttribute[i].mType;
3370 		GLboolean normalized = mState.vertexAttribute[i].mNormalized;
3371 		GLsizei stride = mState.vertexAttribute[i].mStride;
3372 		const GLvoid *pointer = mState.vertexAttribute[i].mPointer;
3373 
3374 		size_t length = count * mState.vertexAttribute[i].stride();
3375 
3376 		if(mState.vertexAttribute[i].mArrayEnabled)
3377 		{
3378 			ASSERT(pointer);   // FIXME: Add to condition?
3379 			const int padding = 1024;   // For SIMD processing of vertices   // FIXME: Still necessary?
3380 			void *buffer = new unsigned char[length + padding];
3381 			memcpy(buffer, pointer, length);
3382 
3383 			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer));
3384 		}
3385 		else
3386 		{
3387 			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0));
3388 		}
3389 	}
3390 }
3391 
restoreAttribs()3392 void Context::restoreAttribs()
3393 {
3394 	memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));
3395 }
3396 
clientActiveTexture(GLenum texture)3397 void Context::clientActiveTexture(GLenum texture)
3398 {
3399 	clientTexture = texture;
3400 }
3401 
getClientActiveTexture() const3402 GLenum Context::getClientActiveTexture() const
3403 {
3404 	return clientTexture;
3405 }
3406 
getActiveTexture() const3407 unsigned int Context::getActiveTexture() const
3408 {
3409 	return mState.activeSampler;
3410 }
3411 
begin(GLenum mode)3412 void Context::begin(GLenum mode)
3413 {
3414 	if(drawing)
3415 	{
3416 		return error(GL_INVALID_OPERATION);
3417 	}
3418 
3419 	drawing = true;
3420 	drawMode = mode;
3421 
3422 	vertex.clear();
3423 }
3424 
position(GLfloat x,GLfloat y,GLfloat z,GLfloat w)3425 void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3426 {
3427 	InVertex v;
3428 
3429 	v.P.x = x;
3430 	v.P.y = y;
3431 	v.P.z = z;
3432 	v.P.w = w;
3433 	v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0];
3434 	v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1];
3435 	v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2];
3436 	v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3];
3437 	v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0];
3438 	v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1];
3439 	v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2];
3440 	v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3];
3441 	v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0];
3442 	v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1];
3443 	v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2];
3444 	v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3];
3445 	v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0];
3446 	v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1];
3447 	v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2];
3448 	v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3];
3449 
3450 	vertex.push_back(v);
3451 }
3452 
end()3453 void Context::end()
3454 {
3455 	if(!drawing)
3456 	{
3457 		return error(GL_INVALID_OPERATION);
3458 	}
3459 
3460 	device->setProjectionMatrix(projection.current());
3461 	device->setViewMatrix(modelView.current());
3462 	device->setTextureMatrix(0, texture[0].current());
3463 	device->setTextureMatrix(1, texture[1].current());
3464 	device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
3465 	device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
3466 
3467 	captureAttribs();
3468 
3469 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3470 	{
3471 		mState.vertexAttribute[i].mArrayEnabled = false;
3472 	}
3473 
3474 	setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P);
3475 	setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N);
3476 	setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C);
3477 	setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0);
3478 	setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1);
3479 
3480 	mState.vertexAttribute[sw::Position].mArrayEnabled = true;
3481 	mState.vertexAttribute[sw::Normal].mArrayEnabled = true;
3482 	mState.vertexAttribute[sw::Color0].mArrayEnabled = true;
3483 	mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true;
3484 	mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true;
3485 
3486 	applyState(drawMode);
3487 
3488 	GLenum err = applyVertexBuffer(0, 0, vertex.size());
3489 	if(err != GL_NO_ERROR)
3490 	{
3491 		return error(err);
3492 	}
3493 
3494 	applyTextures();
3495 
3496 	switch(drawMode)
3497 	{
3498 	case GL_POINTS:
3499 		UNIMPLEMENTED();
3500 		break;
3501 	case GL_LINES:
3502 		UNIMPLEMENTED();
3503 		break;
3504 	case GL_LINE_STRIP:
3505 		UNIMPLEMENTED();
3506 		break;
3507 	case GL_LINE_LOOP:
3508 		UNIMPLEMENTED();
3509 		break;
3510 	case GL_TRIANGLES:
3511 		UNIMPLEMENTED();
3512 		break;
3513 	case GL_TRIANGLE_STRIP:
3514 		device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2);
3515 		break;
3516 	case GL_TRIANGLE_FAN:
3517 		UNIMPLEMENTED();
3518 		break;
3519 	case GL_QUADS:
3520 		UNIMPLEMENTED();
3521 		break;
3522 	case GL_QUAD_STRIP:
3523 		UNIMPLEMENTED();
3524 		break;
3525 	case GL_POLYGON:
3526 		UNIMPLEMENTED();
3527 		break;
3528 	default:
3529 		UNREACHABLE(drawMode);
3530 	}
3531 
3532 	restoreAttribs();
3533 
3534 	drawing = false;
3535 }
3536 
setColorLogicOpEnabled(bool colorLogicOpEnabled)3537 void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)
3538 {
3539 	if(mState.colorLogicOpEnabled != colorLogicOpEnabled)
3540 	{
3541 		mState.colorLogicOpEnabled = colorLogicOpEnabled;
3542 		mColorLogicOperatorDirty = true;
3543 	}
3544 }
3545 
isColorLogicOpEnabled()3546 bool Context::isColorLogicOpEnabled()
3547 {
3548 	return mState.colorLogicOpEnabled;
3549 }
3550 
setLogicalOperation(GLenum logicalOperation)3551 void Context::setLogicalOperation(GLenum logicalOperation)
3552 {
3553 	if(mState.logicalOperation != logicalOperation)
3554 	{
3555 		mState.logicalOperation = logicalOperation;
3556 		mColorLogicOperatorDirty = true;
3557 	}
3558 }
3559 
setColorMaterialEnabled(bool enable)3560 void Context::setColorMaterialEnabled(bool enable)
3561 {
3562 	device->setColorVertexEnable(enable);
3563 }
3564 
setColorMaterialMode(GLenum mode)3565 void Context::setColorMaterialMode(GLenum mode)
3566 {
3567 	switch(mode)
3568 	{
3569 	case GL_EMISSION:
3570 		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3571 		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3572 		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3573 		device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
3574 		break;
3575 	case GL_AMBIENT:
3576 		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3577 		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3578 		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3579 		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3580 		break;
3581 	case GL_DIFFUSE:
3582 		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3583 		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3584 		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3585 		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3586 		break;
3587 	case GL_SPECULAR:
3588 		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3589 		device->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
3590 		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3591 		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3592 		break;
3593 	case GL_AMBIENT_AND_DIFFUSE:
3594 		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3595 		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3596 		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3597 		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3598 		break;
3599 	default:
3600 		UNREACHABLE(mode);
3601 	}
3602 }
3603 
getDevice()3604 Device *Context::getDevice()
3605 {
3606 	return device;
3607 }
3608 
3609 }
3610