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