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