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