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