[dali_1.9.29] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-gl-abstraction.h
1 #ifndef TEST_GL_ABSTRACTION_H
2 #define TEST_GL_ABSTRACTION_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstdio>
23 #include <cstring>
24 #include <cstring> // for strcmp
25 #include <map>
26 #include <sstream>
27 #include <string>
28 #include <typeinfo>
29
30 // INTERNAL INCLUDES
31 #include <dali/devel-api/rendering/frame-buffer-devel.h>
32 #include <dali/integration-api/core.h>
33 #include <dali/integration-api/gl-abstraction.h>
34 #include <dali/integration-api/gl-defines.h>
35 #include <dali/public-api/dali-core.h>
36 #include <test-compare-types.h>
37 #include <test-trace-call-stack.h>
38
39 namespace Dali
40 {
41 static const unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 64;
42 static const char*        mStdAttribs[MAX_ATTRIBUTE_CACHE_SIZE] =
43   {
44     "aPosition",    // ATTRIB_POSITION
45     "aNormal",      // ATTRIB_NORMAL
46     "aTexCoord",    // ATTRIB_TEXCOORD
47     "aColor",       // ATTRIB_COLOR
48     "aBoneWeights", // ATTRIB_BONE_WEIGHTS
49     "aBoneIndices"  // ATTRIB_BONE_INDICES
50 };
51
52 class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
53 {
54 public:
55   TestGlAbstraction();
56   ~TestGlAbstraction() override;
57   void Initialize();
58
59   void PreRender() override;
60   void PostRender() override;
61
62   bool IsSurfacelessContextSupported() const override;
63
64   bool TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const override;
65
66   /* OpenGL ES 2.0 */
67
68   inline void ActiveTexture(GLenum textureUnit) override
69   {
70     mActiveTextureUnit = textureUnit - GL_TEXTURE0;
71   }
72
73   inline GLenum GetActiveTextureUnit() const
74   {
75     return mActiveTextureUnit + GL_TEXTURE0;
76   }
77
78   inline void AttachShader(GLuint program, GLuint shader) override
79   {
80     std::stringstream out;
81     out << program << ", " << shader;
82
83     TraceCallStack::NamedParams namedParams;
84     namedParams["program"] = ToString(program);
85     namedParams["shader"]  = ToString(shader);
86     mShaderTrace.PushCall("AttachShader", out.str(), namedParams);
87   }
88
89   inline void BindAttribLocation(GLuint program, GLuint index, const char* name) override
90   {
91   }
92
93   inline void BindBuffer(GLenum target, GLuint buffer) override
94   {
95   }
96
97   inline void BindFramebuffer(GLenum target, GLuint framebuffer) override
98   {
99     //Add 010 bit;
100     mFramebufferStatus |= 2;
101   }
102
103   inline void BindRenderbuffer(GLenum target, GLuint renderbuffer) override
104   {
105   }
106
107   /**
108    * This method can be used by test cases, to query the texture IDs that have been bound by BindTexture.
109    * @return A vector containing the IDs that were bound.
110    */
111   inline const std::vector<GLuint>& GetBoundTextures() const
112   {
113     return mBoundTextures;
114   }
115
116   /**
117    * Query the texture IDs that have been bound with BindTexture, with a specific active texture unit.
118    * @param[in] activeTextureUnit The specific active texture unit.
119    * @return A vector containing the IDs that were bound.
120    */
121   inline const std::vector<GLuint>& GetBoundTextures(GLuint activeTextureUnit) const
122   {
123     return mActiveTextures[activeTextureUnit - GL_TEXTURE0].mBoundTextures;
124   }
125
126   /**
127    * This method can be used by test cases, to clear the record of texture IDs that have been bound by BindTexture.
128    */
129   inline void ClearBoundTextures()
130   {
131     mBoundTextures.clear();
132
133     for(unsigned int i = 0; i < MIN_TEXTURE_UNIT_LIMIT; ++i)
134     {
135       mActiveTextures[i].mBoundTextures.clear();
136     }
137   }
138
139   inline void BindTexture(GLenum target, GLuint texture) override
140   {
141     // Record the bound textures for future checks
142     if(texture)
143     {
144       mBoundTextures.push_back(texture);
145
146       if(mActiveTextureUnit < MIN_TEXTURE_UNIT_LIMIT)
147       {
148         mActiveTextures[mActiveTextureUnit].mBoundTextures.push_back(texture);
149       }
150     }
151
152     std::stringstream out;
153     out << target << ", " << texture;
154
155     TraceCallStack::NamedParams namedParams;
156     namedParams["target"]  = ToString(target);
157     namedParams["texture"] = ToString(texture);
158
159     mTextureTrace.PushCall("BindTexture", out.str(), namedParams);
160   }
161
162   inline void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) override
163   {
164     mLastBlendColor.r = red;
165     mLastBlendColor.g = green;
166     mLastBlendColor.b = blue;
167     mLastBlendColor.a = alpha;
168   }
169
170   inline const Vector4& GetLastBlendColor() const
171   {
172     return mLastBlendColor;
173   }
174
175   inline void BlendEquation(GLenum mode) override
176   {
177     mLastBlendEquationRgb   = mode;
178     mLastBlendEquationAlpha = mode;
179   }
180
181   inline void BlendEquationSeparate(GLenum modeRgb, GLenum modeAlpha) override
182   {
183     mLastBlendEquationRgb   = modeRgb;
184     mLastBlendEquationAlpha = modeAlpha;
185   }
186
187   inline GLenum GetLastBlendEquationRgb() const
188   {
189     return mLastBlendEquationRgb;
190   }
191
192   inline GLenum GetLastBlendEquationAlpha() const
193   {
194     return mLastBlendEquationAlpha;
195   }
196
197   inline void BlendFunc(GLenum sfactor, GLenum dfactor) override
198   {
199     mLastBlendFuncSrcRgb   = sfactor;
200     mLastBlendFuncDstRgb   = dfactor;
201     mLastBlendFuncSrcAlpha = sfactor;
202     mLastBlendFuncDstAlpha = dfactor;
203   }
204
205   inline void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) override
206   {
207     mLastBlendFuncSrcRgb   = srcRGB;
208     mLastBlendFuncDstRgb   = dstRGB;
209     mLastBlendFuncSrcAlpha = srcAlpha;
210     mLastBlendFuncDstAlpha = dstAlpha;
211   }
212
213   inline GLenum GetLastBlendFuncSrcRgb() const
214   {
215     return mLastBlendFuncSrcRgb;
216   }
217
218   inline GLenum GetLastBlendFuncDstRgb() const
219   {
220     return mLastBlendFuncDstRgb;
221   }
222
223   inline GLenum GetLastBlendFuncSrcAlpha() const
224   {
225     return mLastBlendFuncSrcAlpha;
226   }
227
228   inline GLenum GetLastBlendFuncDstAlpha() const
229   {
230     return mLastBlendFuncDstAlpha;
231   }
232
233   inline void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) override
234   {
235     mBufferDataCalls.push_back(size);
236   }
237
238   inline void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) override
239   {
240     mBufferSubDataCalls.push_back(size);
241   }
242
243   inline GLenum CheckFramebufferStatus(GLenum target) override
244   {
245     //If it has the three last bits set to 1 - 111, then the three minimum functions to create a
246     //Framebuffer texture have been called
247     if(mFramebufferStatus == 7)
248     {
249       return GL_FRAMEBUFFER_COMPLETE;
250     }
251
252     return mCheckFramebufferStatusResult;
253   }
254
255   inline GLuint CheckFramebufferColorAttachmentCount()
256   {
257     return mFramebufferColorAttachmentCount;
258   }
259
260   inline GLenum CheckFramebufferDepthAttachment()
261   {
262     return mFramebufferDepthAttached;
263   }
264
265   inline GLenum CheckFramebufferStencilAttachment()
266   {
267     return mFramebufferStencilAttached;
268   }
269
270   inline void Clear(GLbitfield mask) override
271   {
272     mClearCount++;
273     mLastClearBitMask = mask;
274   }
275
276   inline void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) override
277   {
278     mLastClearColor.r = red;
279     mLastClearColor.g = green;
280     mLastClearColor.b = blue;
281     mLastClearColor.a = alpha;
282   }
283
284   inline const Vector4& GetLastClearColor() const
285   {
286     return mLastClearColor;
287   }
288
289   inline void ClearDepthf(GLclampf depth) override
290   {
291   }
292
293   inline void ClearStencil(GLint s) override
294   {
295     std::stringstream out;
296     out << s;
297
298     TraceCallStack::NamedParams namedParams;
299     namedParams["s"] = ToString(s);
300
301     mStencilFunctionTrace.PushCall("ClearStencil", out.str(), namedParams);
302   }
303
304   inline void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) override
305   {
306     mColorMaskParams.red   = red;
307     mColorMaskParams.green = green;
308     mColorMaskParams.blue  = blue;
309     mColorMaskParams.alpha = alpha;
310   }
311
312   inline void CompileShader(GLuint shader) override
313   {
314     std::stringstream out;
315     out << shader;
316     TraceCallStack::NamedParams namedParams;
317     namedParams["shader"] = ToString(shader);
318
319     mShaderTrace.PushCall("CompileShader", out.str(), namedParams);
320   }
321
322   inline void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) override
323   {
324     std::stringstream out;
325     out << target << ", " << level << ", " << width << ", " << height;
326
327     TraceCallStack::NamedParams namedParams;
328     namedParams["target"]         = ToString(target);
329     namedParams["level"]          = ToString(level);
330     namedParams["internalformat"] = ToString(internalformat);
331     namedParams["width"]          = ToString(width);
332     namedParams["height"]         = ToString(height);
333     namedParams["border"]         = ToString(border);
334     namedParams["size"]           = ToString(imageSize);
335
336     mTextureTrace.PushCall("CompressedTexImage2D", out.str(), namedParams);
337   }
338
339   inline void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) override
340   {
341     std::stringstream out;
342     out << target << ", " << level << ", " << xoffset << ", " << yoffset << ", " << width << ", " << height;
343
344     TraceCallStack::NamedParams namedParams;
345     namedParams["target"]  = ToString(target);
346     namedParams["level"]   = ToString(level);
347     namedParams["xoffset"] = ToString(xoffset);
348     namedParams["yoffset"] = ToString(yoffset);
349     namedParams["width"]   = ToString(width);
350     namedParams["height"]  = ToString(height);
351     mTextureTrace.PushCall("CompressedTexSubImage2D", out.str(), namedParams);
352   }
353
354   inline void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) override
355   {
356   }
357
358   inline void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) override
359   {
360   }
361
362   inline GLuint CreateProgram(void) override
363   {
364     mShaderTrace.PushCall("CreateProgram", "");
365
366     ++mLastProgramIdUsed;
367     mUniforms[mLastProgramIdUsed] = UniformIDMap();
368     return mLastProgramIdUsed;
369   }
370
371   inline GLuint CreateShader(GLenum type) override
372   {
373     std::stringstream out;
374     out << type;
375
376     TraceCallStack::NamedParams namedParams;
377     namedParams["type"] = ToString(type);
378     mShaderTrace.PushCall("CreateShader", out.str(), namedParams);
379
380     return ++mLastShaderIdUsed;
381   }
382
383   inline void CullFace(GLenum mode) override
384   {
385     std::stringstream out;
386     out << mode;
387
388     TraceCallStack::NamedParams namedParams;
389     namedParams["program"] = ToString(mode);
390
391     mCullFaceTrace.PushCall("CullFace", out.str(), namedParams);
392   }
393
394   inline void DeleteBuffers(GLsizei n, const GLuint* buffers) override
395   {
396   }
397
398   inline void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override
399   {
400   }
401
402   inline void DeleteProgram(GLuint program) override
403   {
404     std::stringstream out;
405     out << program;
406
407     TraceCallStack::NamedParams namedParams;
408     namedParams["program"] = ToString(program);
409
410     mShaderTrace.PushCall("DeleteProgram", out.str(), namedParams);
411   }
412
413   inline void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override
414   {
415   }
416
417   inline void DeleteShader(GLuint shader) override
418   {
419     std::stringstream out;
420     out << shader;
421
422     TraceCallStack::NamedParams namedParams;
423     namedParams["shader"] = ToString(shader);
424
425     mShaderTrace.PushCall("DeleteShader", out.str(), namedParams);
426   }
427
428   inline void DeleteTextures(GLsizei n, const GLuint* textures) override
429   {
430     std::stringstream out;
431     out << n << ", " << textures << " = [";
432
433     TraceCallStack::NamedParams namedParams;
434
435     for(GLsizei i = 0; i < n; i++)
436     {
437       out << textures[i] << ", ";
438       std::stringstream paramName;
439       paramName << "texture[" << i << "]";
440       namedParams[paramName.str()] = ToString(textures[i]);
441       mDeletedTextureIds.push_back(textures[i]);
442       mNumGeneratedTextures--;
443     }
444     out << "]";
445
446     mTextureTrace.PushCall("DeleteTextures", out.str(), namedParams);
447   }
448
449   inline bool CheckNoTexturesDeleted()
450   {
451     return mDeletedTextureIds.size() == 0;
452   }
453
454   inline bool CheckTextureDeleted(GLuint textureId)
455   {
456     bool found = false;
457
458     for(std::vector<GLuint>::iterator iter = mDeletedTextureIds.begin(); iter != mDeletedTextureIds.end(); ++iter)
459     {
460       if(*iter == textureId)
461       {
462         found = true;
463         break;
464       }
465     }
466     return found;
467   }
468
469   inline void ClearDeletedTextures()
470   {
471     mDeletedTextureIds.clear();
472   }
473
474   inline void DepthFunc(GLenum func) override
475   {
476     std::stringstream out;
477     out << func;
478
479     TraceCallStack::NamedParams namedParams;
480     namedParams["func"] = ToString(func);
481
482     mDepthFunctionTrace.PushCall("DepthFunc", out.str(), namedParams);
483   }
484
485   inline void DepthMask(GLboolean flag) override
486   {
487     mLastDepthMask = flag;
488   }
489
490   inline bool GetLastDepthMask() const
491   {
492     return mLastDepthMask;
493   }
494
495   inline void DepthRangef(GLclampf zNear, GLclampf zFar) override
496   {
497   }
498
499   inline void DetachShader(GLuint program, GLuint shader) override
500   {
501     std::stringstream out;
502     out << program << ", " << shader;
503     TraceCallStack::NamedParams namedParams;
504     namedParams["program"] = ToString(program);
505     namedParams["shader"]  = ToString(shader);
506     mShaderTrace.PushCall("DetachShader", out.str(), namedParams);
507   }
508
509   inline void Disable(GLenum cap) override
510   {
511     std::stringstream out;
512     out << cap;
513     TraceCallStack::NamedParams namedParams;
514     namedParams["cap"] = ToString(cap);
515     mEnableDisableTrace.PushCall("Disable", out.str(), namedParams);
516   }
517
518   inline void DisableVertexAttribArray(GLuint index) override
519   {
520     SetVertexAttribArray(index, false);
521   }
522
523   inline void DrawArrays(GLenum mode, GLint first, GLsizei count) override
524   {
525     std::stringstream out;
526     out << mode << ", " << first << ", " << count;
527     TraceCallStack::NamedParams namedParams;
528     namedParams["mode"]  = ToString(mode);
529     namedParams["first"] = ToString(first);
530     namedParams["count"] = ToString(count);
531     mDrawTrace.PushCall("DrawArrays", out.str(), namedParams);
532   }
533
534   inline void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) override
535   {
536     std::stringstream out;
537     out << mode << ", " << count << ", " << type << ", indices";
538
539     TraceCallStack::NamedParams namedParams;
540     namedParams["mode"]  = ToString(mode);
541     namedParams["count"] = ToString(count);
542     namedParams["type"]  = ToString(type);
543     // Skip void pointers - are they of any use?
544     mDrawTrace.PushCall("DrawElements", out.str(), namedParams);
545   }
546
547   inline void Enable(GLenum cap) override
548   {
549     std::stringstream out;
550     out << cap;
551     TraceCallStack::NamedParams namedParams;
552     namedParams["cap"] = ToString(cap);
553     mEnableDisableTrace.PushCall("Enable", out.str(), namedParams);
554   }
555
556   inline void EnableVertexAttribArray(GLuint index) override
557   {
558     SetVertexAttribArray(index, true);
559   }
560
561   inline void Finish(void) override
562   {
563   }
564
565   inline void Flush(void) override
566   {
567   }
568
569   inline void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) override
570   {
571     if(attachment == GL_DEPTH_ATTACHMENT)
572     {
573       mFramebufferDepthAttached = true;
574     }
575     else if(attachment == GL_STENCIL_ATTACHMENT)
576     {
577       mFramebufferStencilAttached = true;
578     }
579   }
580
581   inline void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) override
582   {
583     //Add 100 bit;
584     mFramebufferStatus |= 4;
585
586     //We check 4 attachment colors
587     if((attachment >= GL_COLOR_ATTACHMENT0) && (attachment < GL_COLOR_ATTACHMENT0 + Dali::DevelFrameBuffer::MAX_COLOR_ATTACHMENTS))
588     {
589       uint8_t mask = 1 << (attachment - GL_COLOR_ATTACHMENT0);
590       if((mFrameBufferColorStatus & mask) == 0)
591       {
592         mFrameBufferColorStatus |= mask;
593         ++mFramebufferColorAttachmentCount;
594       }
595     }
596   }
597
598   inline void FrontFace(GLenum mode) override
599   {
600   }
601
602   inline void GenBuffers(GLsizei n, GLuint* buffers) override
603   {
604     // avoids an assert in GpuBuffers
605     *buffers = 1u;
606   }
607
608   inline void GenerateMipmap(GLenum target) override
609   {
610     std::stringstream out;
611     out << target;
612     TraceCallStack::NamedParams namedParams;
613     namedParams["target"] = ToString(target);
614
615     mTextureTrace.PushCall("GenerateMipmap", out.str(), namedParams);
616   }
617
618   inline void GenFramebuffers(GLsizei n, GLuint* framebuffers) override
619   {
620     for(int i = 0; i < n; i++)
621     {
622       framebuffers[i] = i + 1;
623     }
624
625     //Add 001 bit, this function needs to be called the first one in the chain
626     mFramebufferStatus = 1;
627   }
628
629   inline void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override
630   {
631     for(int i = 0; i < n; i++)
632     {
633       renderbuffers[i] = i + 1;
634     }
635   }
636
637   /**
638    * This method can be used by test cases, to manipulate the texture IDs generated by GenTextures.
639    * @param[in] ids A vector containing the next IDs to be generated
640    */
641   inline void SetNextTextureIds(const std::vector<GLuint>& ids)
642   {
643     mNextTextureIds = ids;
644   }
645
646   inline const std::vector<GLuint>& GetNextTextureIds()
647   {
648     return mNextTextureIds;
649   }
650
651   inline void GenTextures(GLsizei count, GLuint* textures) override
652   {
653     for(int i = 0; i < count; ++i)
654     {
655       if(!mNextTextureIds.empty())
656       {
657         *(textures + i) = mNextTextureIds[0];
658         mNextTextureIds.erase(mNextTextureIds.begin());
659       }
660       else
661       {
662         *(textures + i) = ++mLastAutoTextureIdUsed;
663       }
664       mNumGeneratedTextures++;
665     }
666
667     TraceCallStack::NamedParams namedParams;
668     namedParams["count"] = ToString(count);
669
670     std::stringstream out;
671     for(int i = 0; i < count; i++)
672     {
673       out << textures[i];
674       if(i < count - 1)
675       {
676         out << ", ";
677       }
678       std::ostringstream oss;
679       oss << "indices[" << i << "]";
680       namedParams[oss.str()] = ToString(textures[i]);
681     }
682
683     mTextureTrace.PushCall("GenTextures", out.str(), namedParams);
684   }
685
686   inline GLuint GetLastGenTextureId()
687   {
688     return mLastAutoTextureIdUsed;
689   }
690
691   inline GLuint GetNumGeneratedTextures()
692   {
693     return mNumGeneratedTextures;
694   }
695
696   inline void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
697   {
698   }
699
700   inline void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
701   {
702     switch(index)
703     {
704       case 0:
705         *length = snprintf(name, bufsize, "sTexture");
706         *type   = GL_SAMPLER_2D;
707         *size   = 1;
708         break;
709       case 1:
710         *length = snprintf(name, bufsize, "sEffect");
711         *type   = GL_SAMPLER_2D;
712         *size   = 1;
713         break;
714       case 2:
715         *length = snprintf(name, bufsize, "sGloss");
716         *type   = GL_SAMPLER_2D;
717         *size   = 1;
718         break;
719       default:
720         break;
721     }
722   }
723
724   inline void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) override
725   {
726   }
727
728   inline int GetAttribLocation(GLuint program, const char* name) override
729   {
730     std::string attribName(name);
731
732     for(unsigned int i = 0; i < ATTRIB_TYPE_LAST; ++i)
733     {
734       if(mStdAttribs[i] == attribName)
735       {
736         return i;
737       }
738     }
739
740     // 0 is a valid location
741     return 0;
742   }
743
744   inline void GetBooleanv(GLenum pname, GLboolean* params) override
745   {
746   }
747
748   inline void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) override
749   {
750   }
751
752   inline GLenum GetError(void) override
753   {
754     return mGetErrorResult;
755   }
756
757   inline void GetFloatv(GLenum pname, GLfloat* params) override
758   {
759   }
760
761   inline void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) override
762   {
763   }
764
765   inline void GetIntegerv(GLenum pname, GLint* params) override
766   {
767     switch(pname)
768     {
769       case GL_MAX_TEXTURE_SIZE:
770         *params = 2048;
771         break;
772       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
773         *params = 8;
774         break;
775       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
776         *params = mNumBinaryFormats;
777         break;
778       case GL_PROGRAM_BINARY_FORMATS_OES:
779         *params = mBinaryFormats;
780         break;
781     }
782   }
783
784   inline void GetProgramiv(GLuint program, GLenum pname, GLint* params) override
785   {
786     switch(pname)
787     {
788       case GL_LINK_STATUS:
789         *params = mLinkStatus;
790         break;
791       case GL_PROGRAM_BINARY_LENGTH_OES:
792         *params = mProgramBinaryLength;
793         break;
794       case GL_ACTIVE_UNIFORMS:
795         *params = mNumberOfActiveUniforms;
796         break;
797       case GL_ACTIVE_UNIFORM_MAX_LENGTH:
798         *params = 100;
799         break;
800     }
801   }
802
803   inline void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) override
804   {
805   }
806
807   inline void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) override
808   {
809   }
810
811   inline void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override
812   {
813     switch(pname)
814     {
815       case GL_COMPILE_STATUS:
816         *params = mCompileStatus;
817         break;
818     }
819   }
820
821   inline void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) override
822   {
823   }
824
825   inline void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) override
826   {
827   }
828
829   inline const GLubyte* GetString(GLenum name) override
830   {
831     return mGetStringResult;
832   }
833
834   inline void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override
835   {
836   }
837
838   inline void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override
839   {
840   }
841
842   inline void GetUniformfv(GLuint program, GLint location, GLfloat* params) override
843   {
844   }
845
846   inline void GetUniformiv(GLuint program, GLint location, GLint* params) override
847   {
848   }
849
850   inline GLint GetUniformLocation(GLuint program, const char* name) override
851   {
852     ProgramUniformMap::iterator it = mUniforms.find(program);
853     if(it == mUniforms.end())
854     {
855       // Not a valid program ID
856       mGetErrorResult = GL_INVALID_OPERATION;
857       return -1;
858     }
859
860     UniformIDMap&          uniformIDs = it->second;
861     UniformIDMap::iterator it2        = uniformIDs.find(name);
862     if(it2 == uniformIDs.end())
863     {
864       // Uniform not found, so add it...
865       uniformIDs[name] = ++mLastUniformIdUsed;
866       return mLastUniformIdUsed;
867     }
868
869     return it2->second;
870   }
871
872   inline void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override
873   {
874   }
875
876   inline void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override
877   {
878   }
879
880   inline void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) override
881   {
882   }
883
884   inline void Hint(GLenum target, GLenum mode) override
885   {
886   }
887
888   inline GLboolean IsBuffer(GLuint buffer) override
889   {
890     return mIsBufferResult;
891   }
892
893   inline GLboolean IsEnabled(GLenum cap) override
894   {
895     return mIsEnabledResult;
896   }
897
898   inline GLboolean IsFramebuffer(GLuint framebuffer) override
899   {
900     return mIsFramebufferResult;
901   }
902
903   inline GLboolean IsProgram(GLuint program) override
904   {
905     return mIsProgramResult;
906   }
907
908   inline GLboolean IsRenderbuffer(GLuint renderbuffer) override
909   {
910     return mIsRenderbufferResult;
911   }
912
913   inline GLboolean IsShader(GLuint shader) override
914   {
915     return mIsShaderResult;
916   }
917
918   inline GLboolean IsTexture(GLuint texture) override
919   {
920     return mIsTextureResult;
921   }
922
923   inline void LineWidth(GLfloat width) override
924   {
925   }
926
927   inline void LinkProgram(GLuint program) override
928   {
929     std::stringstream out;
930     out << program;
931
932     TraceCallStack::NamedParams namedParams;
933     namedParams["program"] = ToString(program);
934     mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
935
936     mNumberOfActiveUniforms = 3;
937     GetUniformLocation(program, "sTexture");
938     GetUniformLocation(program, "sEffect");
939     GetUniformLocation(program, "sGloss");
940   }
941
942   inline void PixelStorei(GLenum pname, GLint param) override
943   {
944   }
945
946   inline void PolygonOffset(GLfloat factor, GLfloat units) override
947   {
948   }
949
950   inline void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) override
951   {
952   }
953
954   inline void ReleaseShaderCompiler(void) override
955   {
956   }
957
958   inline void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) override
959   {
960   }
961
962   inline void SampleCoverage(GLclampf value, GLboolean invert) override
963   {
964   }
965
966   inline void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override
967   {
968     mScissorParams.x      = x;
969     mScissorParams.y      = y;
970     mScissorParams.width  = width;
971     mScissorParams.height = height;
972
973     std::stringstream out;
974     out << x << ", " << y << ", " << width << ", " << height;
975     TraceCallStack::NamedParams namedParams;
976     namedParams["x"]      = ToString(x);
977     namedParams["y"]      = ToString(y);
978     namedParams["width"]  = ToString(width);
979     namedParams["height"] = ToString(height);
980     mScissorTrace.PushCall("Scissor", out.str(), namedParams);
981   }
982
983   inline void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) override
984   {
985   }
986
987   inline void ShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) override
988   {
989     std::string stringBuilder;
990     for(int i = 0; i < count; ++i)
991     {
992       stringBuilder += string[i];
993     }
994     mShaderSources[shader] = stringBuilder;
995     mLastShaderCompiled    = shader;
996   }
997
998   inline void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) override
999   {
1000     const std::string shaderSource       = mShaderSources[shader];
1001     const int         shaderSourceLength = static_cast<int>(shaderSource.length());
1002     if(shaderSourceLength < bufsize)
1003     {
1004       strncpy(source, shaderSource.c_str(), shaderSourceLength);
1005       *length = shaderSourceLength;
1006     }
1007     else
1008     {
1009       *length = bufsize - 1;
1010       strncpy(source, shaderSource.c_str(), *length);
1011       source[*length] = 0x0;
1012     }
1013   }
1014
1015   inline std::string GetShaderSource(GLuint shader)
1016   {
1017     return mShaderSources[shader];
1018   }
1019
1020   inline void StencilFunc(GLenum func, GLint ref, GLuint mask) override
1021   {
1022     std::stringstream out;
1023     out << func << ", " << ref << ", " << mask;
1024
1025     TraceCallStack::NamedParams namedParams;
1026     namedParams["func"] = ToString(func);
1027     namedParams["ref"]  = ToString(ref);
1028     namedParams["mask"] = ToString(mask);
1029
1030     mStencilFunctionTrace.PushCall("StencilFunc", out.str(), namedParams);
1031   }
1032
1033   inline void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) override
1034   {
1035     std::stringstream out;
1036     out << face << ", " << func << ", " << ref << ", " << mask;
1037
1038     TraceCallStack::NamedParams namedParams;
1039     namedParams["face"] = ToString(face);
1040     namedParams["func"] = ToString(func);
1041     namedParams["ref"]  = ToString(ref);
1042     namedParams["mask"] = ToString(mask);
1043
1044     mStencilFunctionTrace.PushCall("StencilFuncSeparate", out.str(), namedParams);
1045   }
1046
1047   inline void StencilMask(GLuint mask) override
1048   {
1049     std::stringstream out;
1050     out << mask;
1051
1052     TraceCallStack::NamedParams namedParams;
1053     namedParams["mask"] = ToString(mask);
1054
1055     mStencilFunctionTrace.PushCall("StencilMask", out.str(), namedParams);
1056   }
1057
1058   inline void StencilMaskSeparate(GLenum face, GLuint mask) override
1059   {
1060     std::stringstream out;
1061     out << face << ", " << mask;
1062
1063     TraceCallStack::NamedParams namedParams;
1064     namedParams["face"] = ToString(face);
1065     namedParams["mask"] = ToString(mask);
1066
1067     mStencilFunctionTrace.PushCall("StencilMaskSeparate", out.str(), namedParams);
1068   }
1069
1070   inline void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override
1071   {
1072     std::stringstream out;
1073     out << fail << ", " << zfail << ", " << zpass;
1074
1075     TraceCallStack::NamedParams namedParams;
1076     namedParams["fail"]  = ToString(fail);
1077     namedParams["zfail"] = ToString(zfail);
1078     namedParams["zpass"] = ToString(zpass);
1079
1080     mStencilFunctionTrace.PushCall("StencilOp", out.str(), namedParams);
1081   }
1082
1083   inline void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) override
1084   {
1085     std::stringstream out;
1086     out << face << ", " << fail << ", " << zfail << "," << zpass;
1087
1088     TraceCallStack::NamedParams namedParams;
1089     namedParams["face"]  = ToString(face);
1090     namedParams["fail"]  = ToString(fail);
1091     namedParams["zfail"] = ToString(zfail);
1092     namedParams["zpass"] = ToString(zpass);
1093
1094     mStencilFunctionTrace.PushCall("StencilOpSeparate", out.str(), namedParams);
1095   }
1096
1097   inline void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) override
1098   {
1099     std::stringstream out;
1100     out << target << ", " << level << ", " << width << ", " << height;
1101
1102     TraceCallStack::NamedParams namedParams;
1103     namedParams["target"]         = ToString(target);
1104     namedParams["level"]          = ToString(level);
1105     namedParams["internalformat"] = ToString(internalformat);
1106     namedParams["width"]          = ToString(width);
1107     namedParams["height"]         = ToString(height);
1108     namedParams["border"]         = ToString(border);
1109     namedParams["format"]         = ToString(format);
1110     namedParams["type"]           = ToString(type);
1111
1112     mTextureTrace.PushCall("TexImage2D", out.str(), namedParams);
1113   }
1114
1115   inline void TexParameterf(GLenum target, GLenum pname, GLfloat param) override
1116   {
1117     std::stringstream out;
1118     out << target << ", " << pname << ", " << param;
1119
1120     TraceCallStack::NamedParams namedParams;
1121     namedParams["target"] = ToString(target);
1122     namedParams["pname"]  = ToString(pname);
1123     namedParams["param"]  = ToString(param);
1124
1125     mTexParamaterTrace.PushCall("TexParameterf", out.str(), namedParams);
1126   }
1127
1128   inline void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) override
1129   {
1130     std::stringstream out;
1131     out << target << ", " << pname << ", " << params[0];
1132
1133     TraceCallStack::NamedParams namedParams;
1134     namedParams["target"]    = ToString(target);
1135     namedParams["pname"]     = ToString(pname);
1136     namedParams["params[0]"] = ToString(params[0]);
1137
1138     mTexParamaterTrace.PushCall("TexParameterfv", out.str(), namedParams);
1139   }
1140
1141   inline void TexParameteri(GLenum target, GLenum pname, GLint param) override
1142   {
1143     std::stringstream out;
1144     out << target << ", " << pname << ", " << param;
1145     TraceCallStack::NamedParams namedParams;
1146     namedParams["target"] = ToString(target);
1147     namedParams["pname"]  = ToString(pname);
1148     namedParams["param"]  = ToString(param);
1149     mTexParamaterTrace.PushCall("TexParameteri", out.str(), namedParams);
1150   }
1151
1152   inline void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override
1153   {
1154     std::stringstream out;
1155     out << target << ", " << pname << ", " << params[0];
1156     TraceCallStack::NamedParams namedParams;
1157     namedParams["target"]    = ToString(target);
1158     namedParams["pname"]     = ToString(pname);
1159     namedParams["params[0]"] = ToString(params[0]);
1160     mTexParamaterTrace.PushCall("TexParameteriv", out.str(), namedParams);
1161   }
1162
1163   inline void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) override
1164   {
1165     std::stringstream out;
1166     out << target << ", " << level << ", " << xoffset << ", " << yoffset << ", " << width << ", " << height;
1167
1168     TraceCallStack::NamedParams namedParams;
1169     namedParams["target"]  = ToString(target);
1170     namedParams["level"]   = ToString(level);
1171     namedParams["xoffset"] = ToString(xoffset);
1172     namedParams["yoffset"] = ToString(yoffset);
1173     namedParams["width"]   = ToString(width);
1174     namedParams["height"]  = ToString(height);
1175     mTextureTrace.PushCall("TexSubImage2D", out.str(), namedParams);
1176   }
1177
1178   inline void Uniform1f(GLint location, GLfloat value) override
1179   {
1180     std::string params = ToString(value);
1181     AddUniformCallToTraceStack(location, params);
1182
1183     if(!mProgramUniforms1f.SetUniformValue(mCurrentProgram, location, value))
1184     {
1185       mGetErrorResult = GL_INVALID_OPERATION;
1186     }
1187   }
1188
1189   inline void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override
1190   {
1191     std::string params;
1192     for(int i = 0; i < count; ++i)
1193     {
1194       params = params + ToString(v[i]) + ",";
1195     }
1196
1197     AddUniformCallToTraceStack(location, params);
1198
1199     for(int i = 0; i < count; ++i)
1200     {
1201       if(!mProgramUniforms1f.SetUniformValue(mCurrentProgram, location, v[i]))
1202       {
1203         mGetErrorResult = GL_INVALID_OPERATION;
1204         break;
1205       }
1206     }
1207   }
1208
1209   inline void Uniform1i(GLint location, GLint x) override
1210   {
1211     std::string params = ToString(x);
1212
1213     AddUniformCallToTraceStack(location, params);
1214
1215     if(!mProgramUniforms1i.SetUniformValue(mCurrentProgram, location, x))
1216     {
1217       mGetErrorResult = GL_INVALID_OPERATION;
1218     }
1219   }
1220
1221   inline void Uniform1iv(GLint location, GLsizei count, const GLint* v) override
1222   {
1223     std::string params = ToString(v);
1224     AddUniformCallToTraceStack(location, params);
1225
1226     for(int i = 0; i < count; ++i)
1227     {
1228       if(!mProgramUniforms1i.SetUniformValue(mCurrentProgram,
1229                                              location,
1230                                              v[i]))
1231       {
1232         mGetErrorResult = GL_INVALID_OPERATION;
1233         break;
1234       }
1235     }
1236   }
1237
1238   inline void Uniform2f(GLint location, GLfloat x, GLfloat y) override
1239   {
1240     std::string params = ToString(x) + "," + ToString(y);
1241     AddUniformCallToTraceStack(location, params);
1242
1243     if(!mProgramUniforms2f.SetUniformValue(mCurrentProgram,
1244                                            location,
1245                                            Vector2(x, y)))
1246     {
1247       mGetErrorResult = GL_INVALID_OPERATION;
1248     }
1249   }
1250
1251   inline void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override
1252   {
1253     std::string params = ToString(v);
1254     AddUniformCallToTraceStack(location, params);
1255
1256     for(int i = 0; i < count; ++i)
1257     {
1258       if(!mProgramUniforms2f.SetUniformValue(mCurrentProgram,
1259                                              location,
1260                                              Vector2(v[2 * i], v[2 * i + 1])))
1261       {
1262         mGetErrorResult = GL_INVALID_OPERATION;
1263         break;
1264       }
1265     }
1266   }
1267
1268   inline void Uniform2i(GLint location, GLint x, GLint y) override
1269   {
1270     std::string params = ToString(x) + "," + ToString(y);
1271     AddUniformCallToTraceStack(location, params);
1272   }
1273
1274   inline void Uniform2iv(GLint location, GLsizei count, const GLint* v) override
1275   {
1276     std::string params = ToString(v);
1277     AddUniformCallToTraceStack(location, params);
1278   }
1279
1280   inline void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override
1281   {
1282     std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z);
1283     AddUniformCallToTraceStack(location, params);
1284
1285     if(!mProgramUniforms3f.SetUniformValue(mCurrentProgram,
1286                                            location,
1287                                            Vector3(x, y, z)))
1288     {
1289       mGetErrorResult = GL_INVALID_OPERATION;
1290     }
1291   }
1292
1293   inline void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override
1294   {
1295     std::string params = ToString(v);
1296     AddUniformCallToTraceStack(location, params);
1297
1298     for(int i = 0; i < count; ++i)
1299     {
1300       if(!mProgramUniforms3f.SetUniformValue(
1301            mCurrentProgram,
1302            location,
1303            Vector3(v[3 * i], v[3 * i + 1], v[3 * i + 2])))
1304       {
1305         mGetErrorResult = GL_INVALID_OPERATION;
1306         break;
1307       }
1308     }
1309   }
1310
1311   inline void Uniform3i(GLint location, GLint x, GLint y, GLint z) override
1312   {
1313     std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z);
1314     AddUniformCallToTraceStack(location, params);
1315   }
1316
1317   inline void Uniform3iv(GLint location, GLsizei count, const GLint* v) override
1318   {
1319     std::string params = ToString(v);
1320     AddUniformCallToTraceStack(location, params);
1321   }
1322
1323   inline void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) override
1324   {
1325     std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z) + "," + ToString(w);
1326     AddUniformCallToTraceStack(location, params);
1327
1328     if(!mProgramUniforms4f.SetUniformValue(mCurrentProgram,
1329                                            location,
1330                                            Vector4(x, y, z, w)))
1331     {
1332       mGetErrorResult = GL_INVALID_OPERATION;
1333     }
1334   }
1335
1336   inline void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override
1337   {
1338     std::string params = ToString(v);
1339     AddUniformCallToTraceStack(location, params);
1340
1341     for(int i = 0; i < count; ++i)
1342     {
1343       if(!mProgramUniforms4f.SetUniformValue(
1344            mCurrentProgram,
1345            location,
1346            Vector4(v[4 * i], v[4 * i + 1], v[4 * i + 2], v[4 * i + 3])))
1347       {
1348         mGetErrorResult = GL_INVALID_OPERATION;
1349         break;
1350       }
1351     }
1352   }
1353
1354   inline void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override
1355   {
1356     std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z) + "," + ToString(w);
1357     AddUniformCallToTraceStack(location, params);
1358   }
1359
1360   inline void Uniform4iv(GLint location, GLsizei count, const GLint* v) override
1361   {
1362     std::string params = ToString(v);
1363     AddUniformCallToTraceStack(location, params);
1364   }
1365
1366   inline void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1367   {
1368     std::string params = ToString(value);
1369     AddUniformCallToTraceStack(location, params);
1370   }
1371
1372   inline void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1373   {
1374     std::string params = ToString(value);
1375     AddUniformCallToTraceStack(location, params);
1376
1377     for(int i = 0; i < count; ++i)
1378     {
1379       if(!mProgramUniformsMat3.SetUniformValue(
1380            mCurrentProgram,
1381            location,
1382            Matrix3(value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], value[8])))
1383       {
1384         mGetErrorResult = GL_INVALID_OPERATION;
1385         break;
1386       }
1387     }
1388   }
1389
1390   inline void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1391   {
1392     std::string params = ToString(value);
1393     AddUniformCallToTraceStack(location, params);
1394
1395     for(int i = 0; i < count; ++i)
1396     {
1397       if(!mProgramUniformsMat4.SetUniformValue(
1398            mCurrentProgram,
1399            location,
1400            Matrix(value)))
1401       {
1402         mGetErrorResult = GL_INVALID_OPERATION;
1403         break;
1404       }
1405     }
1406   }
1407
1408   inline void UseProgram(GLuint program) override
1409   {
1410     mCurrentProgram = program;
1411   }
1412
1413   inline void ValidateProgram(GLuint program) override
1414   {
1415   }
1416
1417   inline void VertexAttrib1f(GLuint indx, GLfloat x) override
1418   {
1419   }
1420
1421   inline void VertexAttrib1fv(GLuint indx, const GLfloat* values) override
1422   {
1423   }
1424
1425   inline void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override
1426   {
1427   }
1428
1429   inline void VertexAttrib2fv(GLuint indx, const GLfloat* values) override
1430   {
1431   }
1432
1433   inline void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) override
1434   {
1435   }
1436
1437   inline void VertexAttrib3fv(GLuint indx, const GLfloat* values) override
1438   {
1439   }
1440
1441   inline void VertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) override
1442   {
1443   }
1444
1445   inline void VertexAttrib4fv(GLuint indx, const GLfloat* values) override
1446   {
1447   }
1448
1449   inline void VertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) override
1450   {
1451   }
1452
1453   inline void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
1454   {
1455     std::string commaString(", ");
1456     std::string params(std::to_string(x) + commaString + std::to_string(y) + commaString + std::to_string(width) + commaString + std::to_string(height));
1457
1458     mViewportTrace.PushCall("Viewport", params);
1459   }
1460
1461   /* OpenGL ES 3.0 */
1462
1463   inline void ReadBuffer(GLenum mode) override
1464   {
1465   }
1466
1467   inline void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) override
1468   {
1469   }
1470
1471   inline void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) override
1472   {
1473   }
1474
1475   inline void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) override
1476   {
1477   }
1478
1479   inline void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) override
1480   {
1481   }
1482
1483   inline void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) override
1484   {
1485   }
1486
1487   inline void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) override
1488   {
1489   }
1490
1491   inline void GenQueries(GLsizei n, GLuint* ids) override
1492   {
1493   }
1494
1495   inline void DeleteQueries(GLsizei n, const GLuint* ids) override
1496   {
1497   }
1498
1499   inline GLboolean IsQuery(GLuint id) override
1500   {
1501     return false;
1502   }
1503
1504   inline void BeginQuery(GLenum target, GLuint id) override
1505   {
1506   }
1507
1508   inline void EndQuery(GLenum target) override
1509   {
1510   }
1511
1512   inline void GetQueryiv(GLenum target, GLenum pname, GLint* params) override
1513   {
1514   }
1515
1516   inline void GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) override
1517   {
1518   }
1519
1520   inline GLboolean UnmapBuffer(GLenum target) override
1521   {
1522     return false;
1523   }
1524
1525   inline void GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) override
1526   {
1527   }
1528
1529   inline void DrawBuffers(GLsizei n, const GLenum* bufs) override
1530   {
1531   }
1532
1533   inline void UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1534   {
1535   }
1536
1537   inline void UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1538   {
1539   }
1540
1541   inline void UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1542   {
1543   }
1544
1545   inline void UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1546   {
1547   }
1548
1549   inline void UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1550   {
1551   }
1552
1553   inline void UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1554   {
1555   }
1556
1557   inline void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override
1558   {
1559   }
1560
1561   inline void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) override
1562   {
1563   }
1564
1565   inline void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
1566   {
1567   }
1568
1569   inline GLvoid* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) override
1570   {
1571     return NULL;
1572   }
1573
1574   inline void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) override
1575   {
1576   }
1577
1578   inline void BindVertexArray(GLuint array) override
1579   {
1580   }
1581
1582   inline void DeleteVertexArrays(GLsizei n, const GLuint* arrays) override
1583   {
1584   }
1585
1586   inline void GenVertexArrays(GLsizei n, GLuint* arrays) override
1587   {
1588   }
1589
1590   inline GLboolean IsVertexArray(GLuint array) override
1591   {
1592     return false;
1593   }
1594
1595   inline void GetIntegeri_v(GLenum target, GLuint index, GLint* data) override
1596   {
1597   }
1598
1599   inline void BeginTransformFeedback(GLenum primitiveMode) override
1600   {
1601   }
1602
1603   inline void EndTransformFeedback(void) override
1604   {
1605   }
1606
1607   inline void BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) override
1608   {
1609   }
1610
1611   inline void BindBufferBase(GLenum target, GLuint index, GLuint buffer) override
1612   {
1613   }
1614
1615   inline void TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) override
1616   {
1617   }
1618
1619   inline void GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) override
1620   {
1621   }
1622
1623   inline void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) override
1624   {
1625   }
1626
1627   inline void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override
1628   {
1629   }
1630
1631   inline void GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) override
1632   {
1633   }
1634
1635   inline void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) override
1636   {
1637   }
1638
1639   inline void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) override
1640   {
1641   }
1642
1643   inline void VertexAttribI4iv(GLuint index, const GLint* v) override
1644   {
1645   }
1646
1647   inline void VertexAttribI4uiv(GLuint index, const GLuint* v) override
1648   {
1649   }
1650
1651   inline void GetUniformuiv(GLuint program, GLint location, GLuint* params) override
1652   {
1653   }
1654
1655   inline GLint GetFragDataLocation(GLuint program, const GLchar* name) override
1656   {
1657     return -1;
1658   }
1659
1660   inline void Uniform1ui(GLint location, GLuint v0) override
1661   {
1662   }
1663
1664   inline void Uniform2ui(GLint location, GLuint v0, GLuint v1) override
1665   {
1666   }
1667
1668   inline void Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) override
1669   {
1670   }
1671
1672   inline void Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) override
1673   {
1674   }
1675
1676   inline void Uniform1uiv(GLint location, GLsizei count, const GLuint* value) override
1677   {
1678   }
1679
1680   inline void Uniform2uiv(GLint location, GLsizei count, const GLuint* value) override
1681   {
1682   }
1683
1684   inline void Uniform3uiv(GLint location, GLsizei count, const GLuint* value) override
1685   {
1686   }
1687
1688   inline void Uniform4uiv(GLint location, GLsizei count, const GLuint* value) override
1689   {
1690   }
1691
1692   inline void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) override
1693   {
1694   }
1695
1696   inline void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) override
1697   {
1698   }
1699
1700   inline void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) override
1701   {
1702   }
1703
1704   inline void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override
1705   {
1706   }
1707
1708   inline const GLubyte* GetStringi(GLenum name, GLuint index) override
1709   {
1710     return NULL;
1711   }
1712
1713   inline void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) override
1714   {
1715   }
1716
1717   inline void GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) override
1718   {
1719   }
1720
1721   inline void GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) override
1722   {
1723   }
1724
1725   inline GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) override
1726   {
1727     return GL_INVALID_INDEX;
1728   }
1729
1730   inline void GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) override
1731   {
1732   }
1733
1734   inline void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) override
1735   {
1736   }
1737
1738   inline void UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override
1739   {
1740   }
1741
1742   inline void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) override
1743   {
1744   }
1745
1746   inline void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) override
1747   {
1748   }
1749
1750   inline GLsync FenceSync(GLenum condition, GLbitfield flags) override
1751   {
1752     return NULL;
1753   }
1754
1755   inline GLboolean IsSync(GLsync sync) override
1756   {
1757     return false;
1758   }
1759
1760   inline void DeleteSync(GLsync sync) override
1761   {
1762   }
1763
1764   inline GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override
1765   {
1766     return 0;
1767   }
1768
1769   inline void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override
1770   {
1771   }
1772
1773   inline void GetInteger64v(GLenum pname, GLint64* params) override
1774   {
1775   }
1776
1777   inline void GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) override
1778   {
1779   }
1780
1781   inline void GetInteger64i_v(GLenum target, GLuint index, GLint64* data) override
1782   {
1783   }
1784
1785   inline void GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) override
1786   {
1787   }
1788
1789   inline void GenSamplers(GLsizei count, GLuint* samplers) override
1790   {
1791   }
1792
1793   inline void DeleteSamplers(GLsizei count, const GLuint* samplers) override
1794   {
1795   }
1796
1797   inline GLboolean IsSampler(GLuint sampler) override
1798   {
1799     return false;
1800   }
1801
1802   inline void BindSampler(GLuint unit, GLuint sampler) override
1803   {
1804   }
1805
1806   inline void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override
1807   {
1808   }
1809
1810   inline void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) override
1811   {
1812   }
1813
1814   inline void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override
1815   {
1816   }
1817
1818   inline void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) override
1819   {
1820   }
1821
1822   inline void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) override
1823   {
1824   }
1825
1826   inline void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) override
1827   {
1828   }
1829
1830   inline void VertexAttribDivisor(GLuint index, GLuint divisor) override
1831   {
1832   }
1833
1834   inline void BindTransformFeedback(GLenum target, GLuint id) override
1835   {
1836   }
1837
1838   inline void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override
1839   {
1840   }
1841
1842   inline void GenTransformFeedbacks(GLsizei n, GLuint* ids) override
1843   {
1844   }
1845
1846   inline GLboolean IsTransformFeedback(GLuint id) override
1847   {
1848     return false;
1849   }
1850
1851   inline void PauseTransformFeedback(void) override
1852   {
1853   }
1854
1855   inline void ResumeTransformFeedback(void) override
1856   {
1857   }
1858
1859   inline void GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) override
1860   {
1861     mGetProgramBinaryCalled = true;
1862   }
1863
1864   inline void ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) override
1865   {
1866   }
1867
1868   inline void ProgramParameteri(GLuint program, GLenum pname, GLint value) override
1869   {
1870   }
1871
1872   inline void InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) override
1873   {
1874   }
1875
1876   inline void InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) override
1877   {
1878   }
1879
1880   inline void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) override
1881   {
1882   }
1883
1884   inline void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) override
1885   {
1886   }
1887
1888   inline void GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) override
1889   {
1890   }
1891
1892 private:
1893   inline void AddUniformCallToTraceStack(GLint location, std::string& value)
1894   {
1895     std::string name    = "<not found>";
1896     bool        matched = false;
1897
1898     UniformIDMap& map = mUniforms[mCurrentProgram];
1899     for(UniformIDMap::iterator it = map.begin(); it != map.end(); ++it)
1900     {
1901       if(it->second == location)
1902       {
1903         name    = it->first;
1904         matched = true;
1905         break;
1906       }
1907     }
1908
1909     if(matched)
1910     {
1911       mSetUniformTrace.PushCall(name, value);
1912     }
1913   }
1914
1915 public: // TEST FUNCTIONS
1916   inline void SetCompileStatus(GLuint value)
1917   {
1918     mCompileStatus = value;
1919   }
1920   inline void SetLinkStatus(GLuint value)
1921   {
1922     mLinkStatus = value;
1923   }
1924   inline void SetGetAttribLocationResult(int result)
1925   {
1926     mGetAttribLocationResult = result;
1927   }
1928   inline void SetGetErrorResult(GLenum result)
1929   {
1930     mGetErrorResult = result;
1931   }
1932   inline void SetGetStringResult(GLubyte* result)
1933   {
1934     mGetStringResult = result;
1935   }
1936   inline void SetIsBufferResult(GLboolean result)
1937   {
1938     mIsBufferResult = result;
1939   }
1940   inline void SetIsEnabledResult(GLboolean result)
1941   {
1942     mIsEnabledResult = result;
1943   }
1944   inline void SetIsFramebufferResult(GLboolean result)
1945   {
1946     mIsFramebufferResult = result;
1947   }
1948   inline void SetIsProgramResult(GLboolean result)
1949   {
1950     mIsProgramResult = result;
1951   }
1952   inline void SetIsRenderbufferResult(GLboolean result)
1953   {
1954     mIsRenderbufferResult = result;
1955   }
1956   inline void SetIsShaderResult(GLboolean result)
1957   {
1958     mIsShaderResult = result;
1959   }
1960   inline void SetIsTextureResult(GLboolean result)
1961   {
1962     mIsTextureResult = result;
1963   }
1964   inline void SetCheckFramebufferStatusResult(GLenum result)
1965   {
1966     mCheckFramebufferStatusResult = result;
1967   }
1968   inline void SetNumBinaryFormats(GLint numFormats)
1969   {
1970     mNumBinaryFormats = numFormats;
1971   }
1972   inline void SetBinaryFormats(GLint binaryFormats)
1973   {
1974     mBinaryFormats = binaryFormats;
1975   }
1976   inline void SetProgramBinaryLength(GLint length)
1977   {
1978     mProgramBinaryLength = length;
1979   }
1980
1981   inline bool GetVertexAttribArrayState(GLuint index)
1982   {
1983     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
1984     {
1985       // out of range
1986       return false;
1987     }
1988     return mVertexAttribArrayState[index];
1989   }
1990   inline void ClearVertexAttribArrayChanged()
1991   {
1992     mVertexAttribArrayChanged = false;
1993   }
1994   inline bool GetVertexAttribArrayChanged()
1995   {
1996     return mVertexAttribArrayChanged;
1997   }
1998
1999   //Methods for CullFace verification
2000   inline void EnableCullFaceCallTrace(bool enable)
2001   {
2002     mCullFaceTrace.Enable(enable);
2003   }
2004   inline void ResetCullFaceCallStack()
2005   {
2006     mCullFaceTrace.Reset();
2007   }
2008   inline TraceCallStack& GetCullFaceTrace()
2009   {
2010     return mCullFaceTrace;
2011   }
2012
2013   //Methods for Enable/Disable call verification
2014   inline void EnableEnableDisableCallTrace(bool enable)
2015   {
2016     mEnableDisableTrace.Enable(enable);
2017   }
2018   inline void ResetEnableDisableCallStack()
2019   {
2020     mEnableDisableTrace.Reset();
2021   }
2022   inline TraceCallStack& GetEnableDisableTrace()
2023   {
2024     return mEnableDisableTrace;
2025   }
2026
2027   //Methods for Shader verification
2028   inline void EnableShaderCallTrace(bool enable)
2029   {
2030     mShaderTrace.Enable(enable);
2031   }
2032   inline void ResetShaderCallStack()
2033   {
2034     mShaderTrace.Reset();
2035   }
2036   inline TraceCallStack& GetShaderTrace()
2037   {
2038     return mShaderTrace;
2039   }
2040
2041   //Methods for Texture verification
2042   inline void EnableTextureCallTrace(bool enable)
2043   {
2044     mTextureTrace.Enable(enable);
2045   }
2046   inline void ResetTextureCallStack()
2047   {
2048     mTextureTrace.Reset();
2049   }
2050   inline TraceCallStack& GetTextureTrace()
2051   {
2052     return mTextureTrace;
2053   }
2054
2055   //Methods for Texture verification
2056   inline void EnableTexParameterCallTrace(bool enable)
2057   {
2058     mTexParamaterTrace.Enable(enable);
2059   }
2060   inline void ResetTexParameterCallStack()
2061   {
2062     mTexParamaterTrace.Reset();
2063   }
2064   inline TraceCallStack& GetTexParameterTrace()
2065   {
2066     return mTexParamaterTrace;
2067   }
2068
2069   //Methods for Draw verification
2070   inline void EnableDrawCallTrace(bool enable)
2071   {
2072     mDrawTrace.Enable(enable);
2073   }
2074   inline void ResetDrawCallStack()
2075   {
2076     mDrawTrace.Reset();
2077   }
2078   inline TraceCallStack& GetDrawTrace()
2079   {
2080     return mDrawTrace;
2081   }
2082
2083   //Methods for Depth function verification
2084   inline void EnableDepthFunctionCallTrace(bool enable)
2085   {
2086     mDepthFunctionTrace.Enable(enable);
2087   }
2088   inline void ResetDepthFunctionCallStack()
2089   {
2090     mDepthFunctionTrace.Reset();
2091   }
2092   inline TraceCallStack& GetDepthFunctionTrace()
2093   {
2094     return mDepthFunctionTrace;
2095   }
2096
2097   //Methods for Stencil function verification
2098   inline void EnableStencilFunctionCallTrace(bool enable)
2099   {
2100     mStencilFunctionTrace.Enable(enable);
2101   }
2102   inline void ResetStencilFunctionCallStack()
2103   {
2104     mStencilFunctionTrace.Reset();
2105   }
2106   inline TraceCallStack& GetStencilFunctionTrace()
2107   {
2108     return mStencilFunctionTrace;
2109   }
2110
2111   //Methods for Scissor verification
2112   inline void EnableScissorCallTrace(bool enable)
2113   {
2114     mScissorTrace.Enable(enable);
2115   }
2116   inline void ResetScissorCallStack()
2117   {
2118     mScissorTrace.Reset();
2119   }
2120   inline TraceCallStack& GetScissorTrace()
2121   {
2122     return mScissorTrace;
2123   }
2124
2125   //Methods for Uniform function verification
2126   inline void EnableSetUniformCallTrace(bool enable)
2127   {
2128     mSetUniformTrace.Enable(enable);
2129   }
2130   inline void ResetSetUniformCallStack()
2131   {
2132     mSetUniformTrace.Reset();
2133   }
2134   inline TraceCallStack& GetSetUniformTrace()
2135   {
2136     return mSetUniformTrace;
2137   }
2138
2139   //Methods for Viewport verification
2140   inline void EnableViewportCallTrace(bool enable)
2141   {
2142     mViewportTrace.Enable(enable);
2143   }
2144   inline void ResetViewportCallStack()
2145   {
2146     mViewportTrace.Reset();
2147   }
2148   inline TraceCallStack& GetViewportTrace()
2149   {
2150     return mViewportTrace;
2151   }
2152
2153   template<typename T>
2154   inline bool GetUniformValue(const char* name, T& value) const
2155   {
2156     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2157         program_it != mUniforms.end();
2158         ++program_it)
2159     {
2160       const UniformIDMap& uniformIDs = program_it->second;
2161
2162       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2163       if(uniform_it != uniformIDs.end())
2164       {
2165         // found one matching uniform name, lets check the value...
2166         GLuint programId = program_it->first;
2167         GLint  uniformId = uniform_it->second;
2168
2169         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2170         return mProgramUniforms.GetUniformValue(programId, uniformId, value);
2171       }
2172     }
2173     return false;
2174   }
2175
2176   template<typename T>
2177   inline bool CheckUniformValue(const char* name, const T& value) const
2178   {
2179     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2180         program_it != mUniforms.end();
2181         ++program_it)
2182     {
2183       const UniformIDMap& uniformIDs = program_it->second;
2184
2185       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2186       if(uniform_it != uniformIDs.end())
2187       {
2188         // found one matching uniform name, lets check the value...
2189         GLuint programId = program_it->first;
2190         GLint  uniformId = uniform_it->second;
2191
2192         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2193         if(mProgramUniforms.CheckUniformValue(programId, uniformId, value))
2194         {
2195           // the value matches
2196           return true;
2197         }
2198       }
2199     }
2200
2201     fprintf(stderr, "Not found, printing possible values:\n");
2202     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2203         program_it != mUniforms.end();
2204         ++program_it)
2205     {
2206       const UniformIDMap& uniformIDs = program_it->second;
2207
2208       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2209       if(uniform_it != uniformIDs.end())
2210       {
2211         // found one matching uniform name, lets check the value...
2212         GLuint programId = program_it->first;
2213         GLint  uniformId = uniform_it->second;
2214
2215         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2216         T                             origValue;
2217         if(mProgramUniforms.GetUniformValue(programId, uniformId, origValue))
2218         {
2219           std::stringstream out;
2220           out << uniform_it->first << ": " << origValue;
2221           fprintf(stderr, "%s\n", out.str().c_str());
2222         }
2223       }
2224     }
2225     return false;
2226   }
2227
2228   template<typename T>
2229   inline bool GetUniformValue(GLuint programId, GLuint uniformId, T& outValue) const
2230   {
2231     const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(outValue);
2232     return mProgramUniforms.GetUniformValue(programId, uniformId, outValue);
2233   }
2234
2235   inline bool GetUniformIds(const char* name, GLuint& programId, GLuint& uniformId) const
2236   {
2237     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2238         program_it != mUniforms.end();
2239         ++program_it)
2240     {
2241       const UniformIDMap& uniformIDs = program_it->second;
2242
2243       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2244       if(uniform_it != uniformIDs.end())
2245       {
2246         programId = program_it->first;
2247         uniformId = uniform_it->second;
2248         return true;
2249       }
2250     }
2251     return false;
2252   }
2253
2254   inline GLuint GetLastShaderCompiled() const
2255   {
2256     return mLastShaderCompiled;
2257   }
2258
2259   inline GLuint GetLastProgramCreated() const
2260   {
2261     return mLastProgramIdUsed;
2262   }
2263
2264   inline GLbitfield GetLastClearMask() const
2265   {
2266     return mLastClearBitMask;
2267   }
2268
2269   enum AttribType
2270   {
2271     ATTRIB_UNKNOWN = -1,
2272     ATTRIB_POSITION,
2273     ATTRIB_NORMAL,
2274     ATTRIB_TEXCOORD,
2275     ATTRIB_COLOR,
2276     ATTRIB_BONE_WEIGHTS,
2277     ATTRIB_BONE_INDICES,
2278     ATTRIB_TYPE_LAST
2279   };
2280
2281   struct ScissorParams
2282   {
2283     GLint   x;
2284     GLint   y;
2285     GLsizei width;
2286     GLsizei height;
2287
2288     ScissorParams()
2289     : x(0),
2290       y(0),
2291       width(0),
2292       height(0)
2293     {
2294     }
2295   };
2296
2297   // Methods to check scissor tests
2298   inline const ScissorParams& GetScissorParams() const
2299   {
2300     return mScissorParams;
2301   }
2302
2303   struct ColorMaskParams
2304   {
2305     GLboolean red;
2306     GLboolean green;
2307     GLboolean blue;
2308     GLboolean alpha;
2309
2310     ColorMaskParams()
2311     : red(true),
2312       green(true),
2313       blue(true),
2314       alpha(true)
2315     {
2316     }
2317   };
2318
2319   inline bool GetProgramBinaryCalled() const
2320   {
2321     return mGetProgramBinaryCalled;
2322   }
2323
2324   inline unsigned int GetClearCountCalled() const
2325   {
2326     return mClearCount;
2327   }
2328
2329   inline const ColorMaskParams& GetColorMaskParams() const
2330   {
2331     return mColorMaskParams;
2332   }
2333
2334   typedef std::vector<size_t>   BufferDataCalls;
2335   inline const BufferDataCalls& GetBufferDataCalls() const
2336   {
2337     return mBufferDataCalls;
2338   }
2339   inline void ResetBufferDataCalls()
2340   {
2341     mBufferDataCalls.clear();
2342   }
2343
2344   typedef std::vector<size_t>      BufferSubDataCalls;
2345   inline const BufferSubDataCalls& GetBufferSubDataCalls() const
2346   {
2347     return mBufferSubDataCalls;
2348   }
2349   inline void ResetBufferSubDataCalls()
2350   {
2351     mBufferSubDataCalls.clear();
2352   }
2353
2354 private:
2355   GLuint                                mCurrentProgram;
2356   GLuint                                mCompileStatus;
2357   BufferDataCalls                       mBufferDataCalls;
2358   BufferSubDataCalls                    mBufferSubDataCalls;
2359   GLuint                                mLinkStatus;
2360   GLint                                 mNumberOfActiveUniforms;
2361   GLint                                 mGetAttribLocationResult;
2362   GLenum                                mGetErrorResult;
2363   GLubyte*                              mGetStringResult;
2364   GLboolean                             mIsBufferResult;
2365   GLboolean                             mIsEnabledResult;
2366   GLboolean                             mIsFramebufferResult;
2367   GLboolean                             mIsProgramResult;
2368   GLboolean                             mIsRenderbufferResult;
2369   GLboolean                             mIsShaderResult;
2370   GLboolean                             mIsTextureResult;
2371   GLenum                                mActiveTextureUnit;
2372   GLenum                                mCheckFramebufferStatusResult;
2373   GLint                                 mFramebufferStatus;
2374   GLenum                                mFramebufferDepthAttached;
2375   GLenum                                mFramebufferStencilAttached;
2376   GLuint                                mFramebufferColorAttachmentCount;
2377   GLuint                                mFrameBufferColorStatus;
2378   GLint                                 mNumBinaryFormats;
2379   GLint                                 mBinaryFormats;
2380   GLint                                 mProgramBinaryLength;
2381   bool                                  mVertexAttribArrayState[MAX_ATTRIBUTE_CACHE_SIZE];
2382   bool                                  mVertexAttribArrayChanged; // whether the vertex attrib array has been changed
2383   bool                                  mGetProgramBinaryCalled;
2384   typedef std::map<GLuint, std::string> ShaderSourceMap;
2385   ShaderSourceMap                       mShaderSources;
2386   GLuint                                mLastShaderCompiled;
2387   GLbitfield                            mLastClearBitMask;
2388   Vector4                               mLastClearColor;
2389   unsigned int                          mClearCount;
2390
2391   Vector4 mLastBlendColor;
2392   GLenum  mLastBlendEquationRgb;
2393   GLenum  mLastBlendEquationAlpha;
2394   GLenum  mLastBlendFuncSrcRgb;
2395   GLenum  mLastBlendFuncDstRgb;
2396   GLenum  mLastBlendFuncSrcAlpha;
2397   GLenum  mLastBlendFuncDstAlpha;
2398
2399   GLboolean mLastDepthMask;
2400
2401   // Data for manipulating the IDs returned by GenTextures
2402   GLuint              mLastAutoTextureIdUsed;
2403   GLuint              mNumGeneratedTextures;
2404   std::vector<GLuint> mNextTextureIds;
2405   std::vector<GLuint> mDeletedTextureIds;
2406   std::vector<GLuint> mBoundTextures;
2407
2408   struct ActiveTextureType
2409   {
2410     std::vector<GLuint> mBoundTextures;
2411   };
2412
2413   ActiveTextureType mActiveTextures[MIN_TEXTURE_UNIT_LIMIT];
2414
2415   TraceCallStack mCullFaceTrace;
2416   TraceCallStack mEnableDisableTrace;
2417   TraceCallStack mShaderTrace;
2418   TraceCallStack mTextureTrace;
2419   TraceCallStack mTexParamaterTrace;
2420   TraceCallStack mDrawTrace;
2421   TraceCallStack mDepthFunctionTrace;
2422   TraceCallStack mStencilFunctionTrace;
2423   TraceCallStack mScissorTrace;
2424   TraceCallStack mSetUniformTrace;
2425   TraceCallStack mViewportTrace;
2426
2427   // Shaders & Uniforms
2428   GLuint                                 mLastShaderIdUsed;
2429   GLuint                                 mLastProgramIdUsed;
2430   GLuint                                 mLastUniformIdUsed;
2431   typedef std::map<std::string, GLint>   UniformIDMap;
2432   typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
2433   ProgramUniformMap                      mUniforms;
2434
2435   template<typename T>
2436   struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >
2437   {
2438   public:
2439     typedef std::map<GLint, T>                UniformValueMap;
2440     typedef std::map<GLuint, UniformValueMap> Map;
2441
2442     bool SetUniformValue(GLuint program, GLuint uniform, const T& value)
2443     {
2444       if(program == 0)
2445       {
2446         return false;
2447       }
2448
2449       typename Map::iterator it = Map::find(program);
2450       if(it == Map::end())
2451       {
2452         // if its the first uniform for this program add it
2453         std::pair<typename Map::iterator, bool> result =
2454           Map::insert(typename Map::value_type(program, UniformValueMap()));
2455         it = result.first;
2456       }
2457
2458       UniformValueMap& uniforms = it->second;
2459       uniforms[uniform]         = value;
2460
2461       return true;
2462     }
2463
2464     bool CheckUniformValue(GLuint program, GLuint uniform, const T& value) const
2465     {
2466       T uniformValue;
2467       if(GetUniformValue(program, uniform, uniformValue))
2468       {
2469         return CompareType<T>(value, uniformValue, Math::MACHINE_EPSILON_10);
2470       }
2471
2472       return false;
2473     }
2474
2475     bool GetUniformValue(GLuint program, GLuint uniform, T& value) const
2476     {
2477       if(program == 0)
2478       {
2479         return false;
2480       }
2481
2482       typename Map::const_iterator it = Map::find(program);
2483       if(it == Map::end())
2484       {
2485         // Uniform values always initialised as 0
2486         value = GetZero();
2487         return true;
2488       }
2489
2490       const UniformValueMap&                   uniforms = it->second;
2491       typename UniformValueMap::const_iterator it2      = uniforms.find(uniform);
2492       if(it2 == uniforms.end())
2493       {
2494         // Uniform values always initialised as 0
2495         value = GetZero();
2496         return true;
2497       }
2498       value = it2->second;
2499
2500       return true;
2501     }
2502
2503     T GetZero() const;
2504   };
2505   ProgramUniformValue<int>     mProgramUniforms1i;
2506   ProgramUniformValue<float>   mProgramUniforms1f;
2507   ProgramUniformValue<Vector2> mProgramUniforms2f;
2508   ProgramUniformValue<Vector3> mProgramUniforms3f;
2509   ProgramUniformValue<Vector4> mProgramUniforms4f;
2510   ProgramUniformValue<Matrix>  mProgramUniformsMat4;
2511   ProgramUniformValue<Matrix3> mProgramUniformsMat3;
2512
2513   inline const ProgramUniformValue<int>& GetProgramUniformsForType(const int) const
2514   {
2515     return mProgramUniforms1i;
2516   }
2517   inline const ProgramUniformValue<float>& GetProgramUniformsForType(const float) const
2518   {
2519     return mProgramUniforms1f;
2520   }
2521   inline const ProgramUniformValue<Vector2>& GetProgramUniformsForType(const Vector2&) const
2522   {
2523     return mProgramUniforms2f;
2524   }
2525   inline const ProgramUniformValue<Vector3>& GetProgramUniformsForType(const Vector3&) const
2526   {
2527     return mProgramUniforms3f;
2528   }
2529   inline const ProgramUniformValue<Vector4>& GetProgramUniformsForType(const Vector4&) const
2530   {
2531     return mProgramUniforms4f;
2532   }
2533   inline const ProgramUniformValue<Matrix>& GetProgramUniformsForType(const Matrix&) const
2534   {
2535     return mProgramUniformsMat4;
2536   }
2537   inline const ProgramUniformValue<Matrix3>& GetProgramUniformsForType(const Matrix3&) const
2538   {
2539     return mProgramUniformsMat3;
2540   }
2541   inline void SetVertexAttribArray(GLuint index, bool state)
2542   {
2543     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
2544     {
2545       // out of range
2546       return;
2547     }
2548     mVertexAttribArrayState[index] = state;
2549     mVertexAttribArrayChanged      = true;
2550   }
2551
2552   ScissorParams   mScissorParams;
2553   ColorMaskParams mColorMaskParams;
2554 };
2555
2556 template<>
2557 inline int TestGlAbstraction::ProgramUniformValue<int>::GetZero() const
2558 {
2559   return 0;
2560 }
2561
2562 template<>
2563 inline float TestGlAbstraction::ProgramUniformValue<float>::GetZero() const
2564 {
2565   return 0.0f;
2566 }
2567
2568 template<>
2569 inline Vector2 TestGlAbstraction::ProgramUniformValue<Vector2>::GetZero() const
2570 {
2571   return Vector2::ZERO;
2572 }
2573
2574 template<>
2575 inline Vector3 TestGlAbstraction::ProgramUniformValue<Vector3>::GetZero() const
2576 {
2577   return Vector3::ZERO;
2578 }
2579
2580 template<>
2581 inline Vector4 TestGlAbstraction::ProgramUniformValue<Vector4>::GetZero() const
2582 {
2583   return Vector4::ZERO;
2584 }
2585
2586 template<>
2587 inline Matrix TestGlAbstraction::ProgramUniformValue<Matrix>::GetZero() const
2588 {
2589   return Matrix();
2590 }
2591
2592 template<>
2593 inline Matrix3 TestGlAbstraction::ProgramUniformValue<Matrix3>::GetZero() const
2594 {
2595   return Matrix3(Matrix());
2596 }
2597
2598 } // namespace Dali
2599
2600 bool BlendEnabled(const Dali::TraceCallStack& callStack);
2601 bool BlendDisabled(const Dali::TraceCallStack& callStack);
2602
2603 #endif // TEST_GL_ABSTRACTION_H