Adding instanced draws
[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) 2023 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     std::stringstream out;
1897     out << mode << ", " << first << ", " << count << ", " << instanceCount;
1898     TraceCallStack::NamedParams namedParams;
1899     namedParams["mode"] << std::hex << mode;
1900     namedParams["first"] << first;
1901     namedParams["count"] << count;
1902     namedParams["instanceCount"] << instanceCount;
1903     mDrawTrace.PushCall("DrawArraysInstanced", out.str(), namedParams);
1904   }
1905
1906   inline void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) override
1907   {
1908     std::stringstream out;
1909     out << mode << ", " << count << ", " << type << ", " << instanceCount;
1910     TraceCallStack::NamedParams namedParams;
1911     namedParams["mode"] << std::hex << mode;
1912     namedParams["count"] << count;
1913     namedParams["type"] << std::hex << type;
1914     namedParams["indexCount"] << instanceCount;
1915     mDrawTrace.PushCall("DrawElementsInstanced", out.str(), namedParams);
1916   }
1917
1918   inline GLsync FenceSync(GLenum condition, GLbitfield flags) override
1919   {
1920     return NULL;
1921   }
1922
1923   inline GLboolean IsSync(GLsync sync) override
1924   {
1925     return false;
1926   }
1927
1928   inline void DeleteSync(GLsync sync) override
1929   {
1930   }
1931
1932   inline GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override
1933   {
1934     return 0;
1935   }
1936
1937   inline void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override
1938   {
1939   }
1940
1941   inline void GetInteger64v(GLenum pname, GLint64* params) override
1942   {
1943   }
1944
1945   inline void GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) override
1946   {
1947   }
1948
1949   inline void GetInteger64i_v(GLenum target, GLuint index, GLint64* data) override
1950   {
1951   }
1952
1953   inline void GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) override
1954   {
1955   }
1956
1957   inline void GenSamplers(GLsizei count, GLuint* samplers) override
1958   {
1959   }
1960
1961   inline void DeleteSamplers(GLsizei count, const GLuint* samplers) override
1962   {
1963   }
1964
1965   inline GLboolean IsSampler(GLuint sampler) override
1966   {
1967     return false;
1968   }
1969
1970   inline void BindSampler(GLuint unit, GLuint sampler) override
1971   {
1972   }
1973
1974   inline void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override
1975   {
1976   }
1977
1978   inline void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) override
1979   {
1980   }
1981
1982   inline void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override
1983   {
1984   }
1985
1986   inline void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) override
1987   {
1988   }
1989
1990   inline void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) override
1991   {
1992   }
1993
1994   inline void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) override
1995   {
1996   }
1997
1998   inline void VertexAttribDivisor(GLuint index, GLuint divisor) override
1999   {
2000     std::stringstream out;
2001     out << index << ", " << divisor;
2002     TraceCallStack::NamedParams namedParams;
2003     namedParams["index"] << index;
2004     namedParams["divisor"] << divisor;
2005     mBufferTrace.PushCall("VertexAttribDivisor", out.str(), namedParams);
2006   }
2007
2008   inline void BindTransformFeedback(GLenum target, GLuint id) override
2009   {
2010   }
2011
2012   inline void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override
2013   {
2014   }
2015
2016   inline void GenTransformFeedbacks(GLsizei n, GLuint* ids) override
2017   {
2018   }
2019
2020   inline GLboolean IsTransformFeedback(GLuint id) override
2021   {
2022     return false;
2023   }
2024
2025   inline void PauseTransformFeedback(void) override
2026   {
2027   }
2028
2029   inline void ResumeTransformFeedback(void) override
2030   {
2031   }
2032
2033   inline void GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) override
2034   {
2035     mGetProgramBinaryCalled = true;
2036   }
2037
2038   inline void ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) override
2039   {
2040   }
2041
2042   inline void ProgramParameteri(GLuint program, GLenum pname, GLint value) override
2043   {
2044   }
2045
2046   inline void InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) override
2047   {
2048   }
2049
2050   inline void InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) override
2051   {
2052   }
2053
2054   inline void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) override
2055   {
2056   }
2057
2058   inline void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) override
2059   {
2060   }
2061
2062   inline void GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) override
2063   {
2064   }
2065
2066   inline void BlendBarrier(void)
2067   {
2068   }
2069
2070 private:
2071   inline void AddUniformCallToTraceStack(GLint location, const std::string& value)
2072   {
2073     std::string name    = "<not found>";
2074     bool        matched = false;
2075
2076     UniformIDMap& map = mUniforms[mCurrentProgram];
2077     for(UniformIDMap::iterator it = map.begin(); it != map.end(); ++it)
2078     {
2079       if(it->second == location)
2080       {
2081         name    = it->first;
2082         matched = true;
2083         break;
2084       }
2085     }
2086
2087     if(matched)
2088     {
2089       mSetUniformTrace.PushCall(name, value);
2090     }
2091   }
2092
2093 public: // TEST FUNCTIONS
2094   inline void SetCompileStatus(GLuint value)
2095   {
2096     mCompileStatus = value;
2097   }
2098   inline void SetLinkStatus(GLuint value)
2099   {
2100     mLinkStatus = value;
2101   }
2102   inline void SetAttribLocations(std::vector<std::string> locs)
2103   {
2104     mAttribLocs = locs;
2105   }
2106   inline void SetGetErrorResult(GLenum result)
2107   {
2108     mGetErrorResult = result;
2109   }
2110   inline void SetGetStringResult(GLubyte* result)
2111   {
2112     mGetStringResult = result;
2113   }
2114   inline void SetIsBufferResult(GLboolean result)
2115   {
2116     mIsBufferResult = result;
2117   }
2118   inline void SetIsEnabledResult(GLboolean result)
2119   {
2120     mIsEnabledResult = result;
2121   }
2122   inline void SetIsFramebufferResult(GLboolean result)
2123   {
2124     mIsFramebufferResult = result;
2125   }
2126   inline void SetIsProgramResult(GLboolean result)
2127   {
2128     mIsProgramResult = result;
2129   }
2130   inline void SetIsRenderbufferResult(GLboolean result)
2131   {
2132     mIsRenderbufferResult = result;
2133   }
2134   inline void SetIsShaderResult(GLboolean result)
2135   {
2136     mIsShaderResult = result;
2137   }
2138   inline void SetIsTextureResult(GLboolean result)
2139   {
2140     mIsTextureResult = result;
2141   }
2142   inline void SetCheckFramebufferStatusResult(GLenum result)
2143   {
2144     mCheckFramebufferStatusResult = result;
2145   }
2146   inline void SetNumBinaryFormats(GLint numFormats)
2147   {
2148     mNumBinaryFormats = numFormats;
2149   }
2150   inline void SetBinaryFormats(GLint binaryFormats)
2151   {
2152     mBinaryFormats = binaryFormats;
2153   }
2154   inline void SetProgramBinaryLength(GLint length)
2155   {
2156     mProgramBinaryLength = length;
2157   }
2158
2159   inline bool GetVertexAttribArrayState(GLuint index)
2160   {
2161     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
2162     {
2163       // out of range
2164       return false;
2165     }
2166     return mVertexAttribArrayState[index];
2167   }
2168   inline void ClearVertexAttribArrayChanged()
2169   {
2170     mVertexAttribArrayChanged = false;
2171   }
2172   inline bool GetVertexAttribArrayChanged()
2173   {
2174     return mVertexAttribArrayChanged;
2175   }
2176
2177   //Methods for CullFace verification
2178   inline void EnableCullFaceCallTrace(bool enable)
2179   {
2180     mCullFaceTrace.Enable(enable);
2181   }
2182   inline void ResetCullFaceCallStack()
2183   {
2184     mCullFaceTrace.Reset();
2185   }
2186   inline TraceCallStack& GetCullFaceTrace()
2187   {
2188     return mCullFaceTrace;
2189   }
2190
2191   //Methods for Enable/Disable call verification
2192   inline void EnableEnableDisableCallTrace(bool enable)
2193   {
2194     mEnableDisableTrace.Enable(enable);
2195   }
2196   inline void ResetEnableDisableCallStack()
2197   {
2198     mEnableDisableTrace.Reset();
2199   }
2200   inline TraceCallStack& GetEnableDisableTrace()
2201   {
2202     return mEnableDisableTrace;
2203   }
2204
2205   //Methods for Shader verification
2206   inline void EnableShaderCallTrace(bool enable)
2207   {
2208     mShaderTrace.Enable(enable);
2209   }
2210   inline void ResetShaderCallStack()
2211   {
2212     mShaderTrace.Reset();
2213   }
2214   inline TraceCallStack& GetShaderTrace()
2215   {
2216     return mShaderTrace;
2217   }
2218
2219   //Methods for Texture verification
2220   inline void EnableTextureCallTrace(bool enable)
2221   {
2222     mTextureTrace.Enable(enable);
2223   }
2224   inline void ResetTextureCallStack()
2225   {
2226     mTextureTrace.Reset();
2227   }
2228   inline TraceCallStack& GetTextureTrace()
2229   {
2230     return mTextureTrace;
2231   }
2232
2233   //Methods for Texture verification
2234   inline void EnableTexParameterCallTrace(bool enable)
2235   {
2236     mTexParameterTrace.Enable(enable);
2237   }
2238   inline void ResetTexParameterCallStack()
2239   {
2240     mTexParameterTrace.Reset();
2241   }
2242   inline TraceCallStack& GetTexParameterTrace()
2243   {
2244     return mTexParameterTrace;
2245   }
2246
2247   //Methods for Draw verification
2248   inline void EnableDrawCallTrace(bool enable)
2249   {
2250     mDrawTrace.Enable(enable);
2251   }
2252   inline void ResetDrawCallStack()
2253   {
2254     mDrawTrace.Reset();
2255   }
2256   inline TraceCallStack& GetDrawTrace()
2257   {
2258     return mDrawTrace;
2259   }
2260
2261   //Methods for Depth function verification
2262   inline void EnableDepthFunctionCallTrace(bool enable)
2263   {
2264     mDepthFunctionTrace.Enable(enable);
2265   }
2266   inline void ResetDepthFunctionCallStack()
2267   {
2268     mDepthFunctionTrace.Reset();
2269   }
2270   inline TraceCallStack& GetDepthFunctionTrace()
2271   {
2272     return mDepthFunctionTrace;
2273   }
2274
2275   //Methods for Stencil function verification
2276   inline void EnableStencilFunctionCallTrace(bool enable)
2277   {
2278     mStencilFunctionTrace.Enable(enable);
2279   }
2280   inline void ResetStencilFunctionCallStack()
2281   {
2282     mStencilFunctionTrace.Reset();
2283   }
2284   inline TraceCallStack& GetStencilFunctionTrace()
2285   {
2286     return mStencilFunctionTrace;
2287   }
2288
2289   //Methods for Scissor verification
2290   inline void EnableScissorCallTrace(bool enable)
2291   {
2292     mScissorTrace.Enable(enable);
2293   }
2294   inline void ResetScissorCallStack()
2295   {
2296     mScissorTrace.Reset();
2297   }
2298   inline TraceCallStack& GetScissorTrace()
2299   {
2300     return mScissorTrace;
2301   }
2302
2303   //Methods for Uniform function verification
2304   inline void EnableSetUniformCallTrace(bool enable)
2305   {
2306     mSetUniformTrace.Enable(enable);
2307   }
2308   inline void ResetSetUniformCallStack()
2309   {
2310     mSetUniformTrace.Reset();
2311   }
2312   inline TraceCallStack& GetSetUniformTrace()
2313   {
2314     return mSetUniformTrace;
2315   }
2316
2317   //Methods for Viewport verification
2318   inline void EnableViewportCallTrace(bool enable)
2319   {
2320     mViewportTrace.Enable(enable);
2321   }
2322   inline void ResetViewportCallStack()
2323   {
2324     mViewportTrace.Reset();
2325   }
2326   inline TraceCallStack& GetViewportTrace()
2327   {
2328     return mViewportTrace;
2329   }
2330   inline TraceCallStack& GetBufferTrace()
2331   {
2332     return mBufferTrace;
2333   }
2334
2335   template<typename T>
2336   inline bool GetUniformValue(const char* name, 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         return mProgramUniforms.GetUniformValue(programId, uniformId, value);
2353       }
2354     }
2355     return false;
2356   }
2357
2358   template<typename T>
2359   inline bool CheckUniformValue(const char* name, const T& value) const
2360   {
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         if(mProgramUniforms.CheckUniformValue(programId, uniformId, value))
2376         {
2377           // the value matches
2378           return true;
2379         }
2380       }
2381     }
2382
2383     fprintf(stderr, "%s Not found, printing possible values:\n", name);
2384     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2385         program_it != mUniforms.end();
2386         ++program_it)
2387     {
2388       const UniformIDMap& uniformIDs = program_it->second;
2389
2390       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2391       if(uniform_it != uniformIDs.end())
2392       {
2393         // found one matching uniform name, lets check the value...
2394         GLuint programId = program_it->first;
2395         GLint  uniformId = uniform_it->second;
2396
2397         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2398         T                             origValue;
2399         if(mProgramUniforms.GetUniformValue(programId, uniformId, origValue))
2400         {
2401           std::stringstream out;
2402           out << "Program: " << programId << ", " << uniform_it->first << ": " << origValue;
2403           fprintf(stderr, "%s\n", out.str().c_str());
2404         }
2405       }
2406     }
2407     return false;
2408   }
2409
2410   template<typename T>
2411   inline bool GetUniformValue(GLuint programId, GLuint uniformId, T& outValue) const
2412   {
2413     const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(outValue);
2414     return mProgramUniforms.GetUniformValue(programId, uniformId, outValue);
2415   }
2416
2417   inline bool GetUniformIds(const char* name, GLuint& programId, GLuint& uniformId) const
2418   {
2419     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2420         program_it != mUniforms.end();
2421         ++program_it)
2422     {
2423       const UniformIDMap& uniformIDs = program_it->second;
2424
2425       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2426       if(uniform_it != uniformIDs.end())
2427       {
2428         programId = program_it->first;
2429         uniformId = uniform_it->second;
2430         return true;
2431       }
2432     }
2433     return false;
2434   }
2435
2436   inline void SetCustomUniforms(std::vector<UniformData>& customUniformData)
2437   {
2438     mCustomUniformData = customUniformData;
2439   }
2440
2441   inline GLuint GetLastShaderCompiled() const
2442   {
2443     return mLastShaderCompiled;
2444   }
2445
2446   inline GLuint GetLastProgramCreated() const
2447   {
2448     return mLastProgramIdUsed;
2449   }
2450
2451   inline GLbitfield GetLastClearMask() const
2452   {
2453     return mLastClearBitMask;
2454   }
2455
2456   enum AttribType
2457   {
2458     ATTRIB_UNKNOWN = -1,
2459     ATTRIB_POSITION,
2460     ATTRIB_NORMAL,
2461     ATTRIB_TEXCOORD,
2462     ATTRIB_COLOR,
2463     ATTRIB_BONE_WEIGHTS,
2464     ATTRIB_BONE_INDICES,
2465     ATTRIB_TYPE_LAST
2466   };
2467
2468   struct ScissorParams
2469   {
2470     GLint   x;
2471     GLint   y;
2472     GLsizei width;
2473     GLsizei height;
2474
2475     ScissorParams()
2476     : x(0),
2477       y(0),
2478       width(0),
2479       height(0)
2480     {
2481     }
2482   };
2483
2484   // Methods to check scissor tests
2485   inline const ScissorParams& GetScissorParams() const
2486   {
2487     return mScissorParams;
2488   }
2489
2490   struct ColorMaskParams
2491   {
2492     GLboolean red;
2493     GLboolean green;
2494     GLboolean blue;
2495     GLboolean alpha;
2496
2497     ColorMaskParams()
2498     : red(true),
2499       green(true),
2500       blue(true),
2501       alpha(true)
2502     {
2503     }
2504   };
2505
2506   inline bool GetProgramBinaryCalled() const
2507   {
2508     return mGetProgramBinaryCalled;
2509   }
2510
2511   inline unsigned int GetClearCountCalled() const
2512   {
2513     return mClearCount;
2514   }
2515
2516   inline const ColorMaskParams& GetColorMaskParams() const
2517   {
2518     return mColorMaskParams;
2519   }
2520
2521   typedef std::vector<size_t>   BufferDataCalls;
2522   inline const BufferDataCalls& GetBufferDataCalls() const
2523   {
2524     return mBufferDataCalls;
2525   }
2526   inline void ResetBufferDataCalls()
2527   {
2528     mBufferDataCalls.clear();
2529   }
2530
2531   typedef std::vector<size_t>      BufferSubDataCalls;
2532   inline const BufferSubDataCalls& GetBufferSubDataCalls() const
2533   {
2534     return mBufferSubDataCalls;
2535   }
2536   inline void ResetBufferSubDataCalls()
2537   {
2538     mBufferSubDataCalls.clear();
2539   }
2540
2541 public:
2542   GLuint                                mCurrentProgram;
2543   GLuint                                mCompileStatus;
2544   BufferDataCalls                       mBufferDataCalls;
2545   BufferSubDataCalls                    mBufferSubDataCalls;
2546   GLvoid*                               mMappedBuffer{nullptr};
2547   GLuint                                mLinkStatus;
2548   GLenum                                mGetErrorResult;
2549   GLubyte*                              mGetStringResult;
2550   GLboolean                             mIsBufferResult;
2551   GLboolean                             mIsEnabledResult;
2552   GLboolean                             mIsFramebufferResult;
2553   GLboolean                             mIsProgramResult;
2554   GLboolean                             mIsRenderbufferResult;
2555   GLboolean                             mIsShaderResult;
2556   GLboolean                             mIsTextureResult;
2557   GLenum                                mActiveTextureUnit;
2558   GLenum                                mCheckFramebufferStatusResult;
2559   GLint                                 mFramebufferStatus;
2560   GLenum                                mFramebufferDepthAttached;
2561   GLenum                                mFramebufferStencilAttached;
2562   GLenum                                mFramebufferDepthStencilAttached;
2563   GLuint                                mFramebufferColorAttachmentCount;
2564   GLuint                                mFrameBufferColorStatus;
2565   GLuint                                mFramebufferDepthAttachmentCount;
2566   GLuint                                mFramebufferStencilAttachmentCount;
2567   GLuint                                mFramebufferDepthStencilAttachmentCount;
2568   GLint                                 mNumBinaryFormats;
2569   GLint                                 mBinaryFormats;
2570   GLint                                 mProgramBinaryLength;
2571   bool                                  mVertexAttribArrayState[MAX_ATTRIBUTE_CACHE_SIZE];
2572   bool                                  mVertexAttribArrayChanged; // whether the vertex attrib array has been changed
2573   bool                                  mGetProgramBinaryCalled;
2574   typedef std::map<GLuint, std::string> ShaderSourceMap;
2575   ShaderSourceMap                       mShaderSources;
2576   std::vector<std::string>              mAttribLocs; // should be bound to shader
2577   GLuint                                mLastShaderCompiled;
2578   GLbitfield                            mLastClearBitMask;
2579   Vector4                               mLastClearColor;
2580   unsigned int                          mClearCount;
2581
2582   Vector4 mLastBlendColor;
2583   GLenum  mLastBlendEquationRgb;
2584   GLenum  mLastBlendEquationAlpha;
2585   GLenum  mLastBlendFuncSrcRgb;
2586   GLenum  mLastBlendFuncDstRgb;
2587   GLenum  mLastBlendFuncSrcAlpha;
2588   GLenum  mLastBlendFuncDstAlpha;
2589
2590   GLboolean mLastDepthMask;
2591
2592   // Data for manipulating the IDs returned by GenTextures
2593   GLuint              mLastAutoTextureIdUsed;
2594   GLuint              mNumGeneratedTextures;
2595   std::vector<GLuint> mNextTextureIds;
2596   std::vector<GLuint> mDeletedTextureIds;
2597   std::vector<GLuint> mBoundTextures;
2598
2599   struct ActiveTextureType
2600   {
2601     std::vector<GLuint> mBoundTextures;
2602   };
2603
2604   ActiveTextureType mActiveTextures[MIN_TEXTURE_UNIT_LIMIT];
2605
2606   TraceCallStack mBufferTrace;
2607   TraceCallStack mCullFaceTrace;
2608   TraceCallStack mEnableDisableTrace;
2609   TraceCallStack mShaderTrace;
2610   TraceCallStack mTextureTrace;
2611   TraceCallStack mTexParameterTrace;
2612   TraceCallStack mDrawTrace;
2613   TraceCallStack mDepthFunctionTrace;
2614   TraceCallStack mStencilFunctionTrace;
2615   TraceCallStack mScissorTrace;
2616   TraceCallStack mSetUniformTrace;
2617   TraceCallStack mViewportTrace;
2618
2619   // Shaders & Uniforms
2620   GLuint                                 mLastShaderIdUsed;
2621   GLuint                                 mLastProgramIdUsed{0u};
2622   GLuint                                 mLastUniformIdUsed;
2623   typedef std::map<std::string, GLint>   UniformIDMap;
2624   typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
2625   ProgramUniformMap                      mUniforms;
2626   std::vector<ActiveUniform>             mActiveUniforms;
2627   std::vector<UniformData>               mCustomUniformData{};
2628
2629   template<typename T>
2630   struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >
2631   {
2632   public:
2633     typedef std::map<GLint, T>                UniformValueMap;
2634     typedef std::map<GLuint, UniformValueMap> Map;
2635
2636     bool SetUniformValue(GLuint program, GLuint uniform, const T& value)
2637     {
2638       if(program == 0)
2639       {
2640         return false;
2641       }
2642
2643       typename Map::iterator it = Map::find(program);
2644       if(it == Map::end())
2645       {
2646         // if its the first uniform for this program add it
2647         std::pair<typename Map::iterator, bool> result =
2648           Map::insert(typename Map::value_type(program, UniformValueMap()));
2649         it = result.first;
2650       }
2651
2652       UniformValueMap& uniforms = it->second;
2653       uniforms[uniform]         = value;
2654
2655       return true;
2656     }
2657
2658     bool CheckUniformValue(GLuint program, GLuint uniform, const T& value) const
2659     {
2660       T uniformValue;
2661       if(GetUniformValue(program, uniform, uniformValue))
2662       {
2663         return CompareType<T>(value, uniformValue, Math::MACHINE_EPSILON_10);
2664       }
2665
2666       return false;
2667     }
2668
2669     bool GetUniformValue(GLuint program, GLuint uniform, T& value) const
2670     {
2671       if(program == 0)
2672       {
2673         return false;
2674       }
2675
2676       typename Map::const_iterator it = Map::find(program);
2677       if(it == Map::end())
2678       {
2679         // Uniform values always initialised as 0
2680         value = GetZero();
2681         return true;
2682       }
2683
2684       const UniformValueMap&                   uniforms = it->second;
2685       typename UniformValueMap::const_iterator it2      = uniforms.find(uniform);
2686       if(it2 == uniforms.end())
2687       {
2688         // Uniform values always initialised as 0
2689         value = GetZero();
2690         return true;
2691       }
2692       value = it2->second;
2693
2694       return true;
2695     }
2696
2697     T GetZero() const;
2698   };
2699   ProgramUniformValue<int>     mProgramUniforms1i;
2700   ProgramUniformValue<float>   mProgramUniforms1f;
2701   ProgramUniformValue<Vector2> mProgramUniforms2f;
2702   ProgramUniformValue<Vector3> mProgramUniforms3f;
2703   ProgramUniformValue<Vector4> mProgramUniforms4f;
2704   ProgramUniformValue<Matrix>  mProgramUniformsMat4;
2705   ProgramUniformValue<Matrix3> mProgramUniformsMat3;
2706
2707   inline const ProgramUniformValue<int>& GetProgramUniformsForType(const int) const
2708   {
2709     return mProgramUniforms1i;
2710   }
2711   inline const ProgramUniformValue<float>& GetProgramUniformsForType(const float) const
2712   {
2713     return mProgramUniforms1f;
2714   }
2715   inline const ProgramUniformValue<Vector2>& GetProgramUniformsForType(const Vector2&) const
2716   {
2717     return mProgramUniforms2f;
2718   }
2719   inline const ProgramUniformValue<Vector3>& GetProgramUniformsForType(const Vector3&) const
2720   {
2721     return mProgramUniforms3f;
2722   }
2723   inline const ProgramUniformValue<Vector4>& GetProgramUniformsForType(const Vector4&) const
2724   {
2725     return mProgramUniforms4f;
2726   }
2727   inline const ProgramUniformValue<Matrix>& GetProgramUniformsForType(const Matrix&) const
2728   {
2729     return mProgramUniformsMat4;
2730   }
2731   inline const ProgramUniformValue<Matrix3>& GetProgramUniformsForType(const Matrix3&) const
2732   {
2733     return mProgramUniformsMat3;
2734   }
2735   inline void SetVertexAttribArray(GLuint index, bool state)
2736   {
2737     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
2738     {
2739       // out of range
2740       return;
2741     }
2742     mVertexAttribArrayState[index] = state;
2743     mVertexAttribArrayChanged      = true;
2744   }
2745
2746   ScissorParams   mScissorParams;
2747   ColorMaskParams mColorMaskParams;
2748 };
2749
2750 template<>
2751 inline int TestGlAbstraction::ProgramUniformValue<int>::GetZero() const
2752 {
2753   return 0;
2754 }
2755
2756 template<>
2757 inline float TestGlAbstraction::ProgramUniformValue<float>::GetZero() const
2758 {
2759   return 0.0f;
2760 }
2761
2762 template<>
2763 inline Vector2 TestGlAbstraction::ProgramUniformValue<Vector2>::GetZero() const
2764 {
2765   return Vector2::ZERO;
2766 }
2767
2768 template<>
2769 inline Vector3 TestGlAbstraction::ProgramUniformValue<Vector3>::GetZero() const
2770 {
2771   return Vector3::ZERO;
2772 }
2773
2774 template<>
2775 inline Vector4 TestGlAbstraction::ProgramUniformValue<Vector4>::GetZero() const
2776 {
2777   return Vector4::ZERO;
2778 }
2779
2780 template<>
2781 inline Matrix TestGlAbstraction::ProgramUniformValue<Matrix>::GetZero() const
2782 {
2783   return Matrix();
2784 }
2785
2786 template<>
2787 inline Matrix3 TestGlAbstraction::ProgramUniformValue<Matrix3>::GetZero() const
2788 {
2789   return Matrix3(Matrix());
2790 }
2791
2792 } // namespace Dali
2793
2794 bool BlendEnabled(const Dali::TraceCallStack& callStack);
2795 bool BlendDisabled(const Dali::TraceCallStack& callStack);
2796
2797 #endif // TEST_GL_ABSTRACTION_H