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