OSDN Git Service

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