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