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