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