5679a01d8e4dc1270046013a6595e670297cd25c
[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 << target << ", " << texture;
161
162     TraceCallStack::NamedParams namedParams;
163     namedParams["target"] << 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     }
835   }
836
837   inline void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) override
838   {
839   }
840
841   inline void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) override
842   {
843   }
844
845   inline void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override
846   {
847     switch(pname)
848     {
849       case GL_COMPILE_STATUS:
850         *params = mCompileStatus;
851         break;
852     }
853   }
854
855   inline void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) override
856   {
857   }
858
859   inline void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) override
860   {
861   }
862
863   inline const GLubyte* GetString(GLenum name) override
864   {
865     return mGetStringResult;
866   }
867
868   inline void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override
869   {
870   }
871
872   inline void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override
873   {
874   }
875
876   inline void GetUniformfv(GLuint program, GLint location, GLfloat* params) override
877   {
878   }
879
880   inline void GetUniformiv(GLuint program, GLint location, GLint* params) override
881   {
882   }
883
884   inline GLint GetUniformLocation(GLuint program, const char* name) override
885   {
886     ProgramUniformMap::iterator it = mUniforms.find(program);
887     if(it == mUniforms.end())
888     {
889       // Not a valid program ID
890       mGetErrorResult = GL_INVALID_OPERATION;
891       return -1;
892     }
893
894     UniformIDMap&          uniformIDs = it->second;
895     UniformIDMap::iterator it2        = uniformIDs.find(name);
896     if(it2 == uniformIDs.end())
897     {
898       // Uniform not found, so add it...
899       uniformIDs[name] = ++mLastUniformIdUsed;
900       return mLastUniformIdUsed;
901     }
902
903     return it2->second;
904   }
905
906   inline void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override
907   {
908   }
909
910   inline void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override
911   {
912   }
913
914   inline void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) override
915   {
916   }
917
918   inline void Hint(GLenum target, GLenum mode) override
919   {
920   }
921
922   inline GLboolean IsBuffer(GLuint buffer) override
923   {
924     return mIsBufferResult;
925   }
926
927   inline GLboolean IsEnabled(GLenum cap) override
928   {
929     return mIsEnabledResult;
930   }
931
932   inline GLboolean IsFramebuffer(GLuint framebuffer) override
933   {
934     return mIsFramebufferResult;
935   }
936
937   inline GLboolean IsProgram(GLuint program) override
938   {
939     return mIsProgramResult;
940   }
941
942   inline GLboolean IsRenderbuffer(GLuint renderbuffer) override
943   {
944     return mIsRenderbufferResult;
945   }
946
947   inline GLboolean IsShader(GLuint shader) override
948   {
949     return mIsShaderResult;
950   }
951
952   inline GLboolean IsTexture(GLuint texture) override
953   {
954     return mIsTextureResult;
955   }
956
957   inline void LineWidth(GLfloat width) override
958   {
959   }
960
961   inline void LinkProgram(GLuint program) override
962   {
963     std::stringstream out;
964     out << program;
965
966     TraceCallStack::NamedParams namedParams;
967     namedParams["program"] << program;
968     mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
969
970     mNumberOfActiveUniforms = 3;
971     GetUniformLocation(program, "sTexture");
972     GetUniformLocation(program, "sEffect");
973     GetUniformLocation(program, "sGloss");
974   }
975
976   inline void PixelStorei(GLenum pname, GLint param) override
977   {
978   }
979
980   inline void PolygonOffset(GLfloat factor, GLfloat units) override
981   {
982   }
983
984   inline void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) override
985   {
986   }
987
988   inline void ReleaseShaderCompiler(void) override
989   {
990   }
991
992   inline void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) override
993   {
994   }
995
996   inline void SampleCoverage(GLclampf value, GLboolean invert) override
997   {
998   }
999
1000   inline void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override
1001   {
1002     mScissorParams.x      = x;
1003     mScissorParams.y      = y;
1004     mScissorParams.width  = width;
1005     mScissorParams.height = height;
1006
1007     std::stringstream out;
1008     out << x << ", " << y << ", " << width << ", " << height;
1009     TraceCallStack::NamedParams namedParams;
1010     namedParams["x"] << x;
1011     namedParams["y"] << y;
1012     namedParams["width"] << width;
1013     namedParams["height"] << height;
1014     mScissorTrace.PushCall("Scissor", out.str(), namedParams);
1015   }
1016
1017   inline void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) override
1018   {
1019   }
1020
1021   inline void ShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) override
1022   {
1023     std::string stringBuilder;
1024     for(int i = 0; i < count; ++i)
1025     {
1026       stringBuilder += string[i];
1027     }
1028     mShaderSources[shader] = stringBuilder;
1029     mLastShaderCompiled    = shader;
1030   }
1031
1032   inline void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) override
1033   {
1034     const std::string shaderSource       = mShaderSources[shader];
1035     const int         shaderSourceLength = static_cast<int>(shaderSource.length());
1036     if(shaderSourceLength < bufsize)
1037     {
1038       strncpy(source, shaderSource.c_str(), shaderSourceLength);
1039       *length = shaderSourceLength;
1040     }
1041     else
1042     {
1043       *length = bufsize - 1;
1044       strncpy(source, shaderSource.c_str(), *length);
1045       source[*length] = 0x0;
1046     }
1047   }
1048
1049   inline std::string GetShaderSource(GLuint shader)
1050   {
1051     return mShaderSources[shader];
1052   }
1053
1054   inline void StencilFunc(GLenum func, GLint ref, GLuint mask) override
1055   {
1056     std::stringstream out;
1057     out << func << ", " << ref << ", " << mask;
1058
1059     TraceCallStack::NamedParams namedParams;
1060     namedParams["func"] << std::hex << func;
1061     namedParams["ref"] << ref;
1062     namedParams["mask"] << mask;
1063
1064     mStencilFunctionTrace.PushCall("StencilFunc", out.str(), namedParams);
1065   }
1066
1067   inline void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) override
1068   {
1069     std::stringstream out;
1070     out << face << ", " << func << ", " << ref << ", " << mask;
1071
1072     TraceCallStack::NamedParams namedParams;
1073     namedParams["face"] << std::hex << face;
1074     namedParams["func"] << std::hex << func;
1075     namedParams["ref"] << ref;
1076     namedParams["mask"] << mask;
1077
1078     mStencilFunctionTrace.PushCall("StencilFuncSeparate", out.str(), namedParams);
1079   }
1080
1081   inline void StencilMask(GLuint mask) override
1082   {
1083     std::stringstream out;
1084     out << mask;
1085
1086     TraceCallStack::NamedParams namedParams;
1087     namedParams["mask"] << mask;
1088
1089     mStencilFunctionTrace.PushCall("StencilMask", out.str(), namedParams);
1090   }
1091
1092   inline void StencilMaskSeparate(GLenum face, GLuint mask) override
1093   {
1094     std::stringstream out;
1095     out << face << ", " << mask;
1096
1097     TraceCallStack::NamedParams namedParams;
1098     namedParams["face"] << std::hex << face;
1099     namedParams["mask"] << mask;
1100
1101     mStencilFunctionTrace.PushCall("StencilMaskSeparate", out.str(), namedParams);
1102   }
1103
1104   inline void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override
1105   {
1106     std::stringstream out;
1107     out << fail << ", " << zfail << ", " << zpass;
1108
1109     TraceCallStack::NamedParams namedParams;
1110     namedParams["fail"] << std::hex << fail;
1111     namedParams["zfail"] << std::hex << zfail;
1112     namedParams["zpass"] << std::hex << zpass;
1113
1114     mStencilFunctionTrace.PushCall("StencilOp", out.str(), namedParams);
1115   }
1116
1117   inline void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) override
1118   {
1119     std::stringstream out;
1120     out << face << ", " << fail << ", " << zfail << "," << zpass;
1121
1122     TraceCallStack::NamedParams namedParams;
1123     namedParams["face"] << std::hex << face;
1124     namedParams["fail"] << std::hex << fail;
1125     namedParams["zfail"] << std::hex << zfail;
1126     namedParams["zpass"] << std::hex << zpass;
1127
1128     mStencilFunctionTrace.PushCall("StencilOpSeparate", out.str(), namedParams);
1129   }
1130
1131   inline void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) override
1132   {
1133     std::stringstream out;
1134     out << target << ", " << level << ", " << width << ", " << height;
1135
1136     TraceCallStack::NamedParams namedParams;
1137     namedParams["target"] << std::hex << target;
1138     namedParams["level"] << level;
1139     namedParams["internalformat"] << internalformat;
1140     namedParams["width"] << width;
1141     namedParams["height"] << height;
1142     namedParams["border"] << border;
1143     namedParams["format"] << std::hex << format;
1144     namedParams["type"] << std::hex << type;
1145
1146     mTextureTrace.PushCall("TexImage2D", out.str(), namedParams);
1147   }
1148
1149   inline void TexParameterf(GLenum target, GLenum pname, GLfloat param) override
1150   {
1151     std::stringstream out;
1152     out << target << ", " << pname << ", " << param;
1153
1154     TraceCallStack::NamedParams namedParams;
1155     namedParams["target"] << std::hex << target;
1156     namedParams["pname"] << std::hex << pname;
1157     namedParams["param"] << param;
1158
1159     mTexParameterTrace.PushCall("TexParameterf", out.str(), namedParams);
1160   }
1161
1162   inline void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) override
1163   {
1164     std::stringstream out;
1165     out << target << ", " << pname << ", " << params[0];
1166
1167     TraceCallStack::NamedParams namedParams;
1168     namedParams["target"] << std::hex << target;
1169     namedParams["pname"] << std::hex << pname;
1170     namedParams["params[0]"] << params[0];
1171
1172     mTexParameterTrace.PushCall("TexParameterfv", out.str(), namedParams);
1173   }
1174
1175   inline void TexParameteri(GLenum target, GLenum pname, GLint param) override
1176   {
1177     std::stringstream out;
1178     out << std::hex << target << ", " << pname << ", " << param;
1179     std::string params = out.str();
1180
1181     out.str("");
1182     out << std::hex << target;
1183     TraceCallStack::NamedParams namedParams;
1184     namedParams["target"] << out.str();
1185     out.str("");
1186     out << std::hex << pname;
1187     namedParams["pname"] << out.str();
1188     out.str("");
1189     out << std::hex << param;
1190     namedParams["param"] << out.str();
1191     mTexParameterTrace.PushCall("TexParameteri", params, namedParams);
1192   }
1193
1194   inline void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override
1195   {
1196     std::stringstream out;
1197     out << target << ", " << pname << ", " << params[0];
1198     TraceCallStack::NamedParams namedParams;
1199     namedParams["target"] << std::hex << target;
1200     namedParams["pname"] << std::hex << pname;
1201     namedParams["params[0]"] << params[0];
1202     mTexParameterTrace.PushCall("TexParameteriv", out.str(), namedParams);
1203   }
1204
1205   inline void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) override
1206   {
1207     std::stringstream out;
1208     out << target << ", " << level << ", " << xoffset << ", " << yoffset << ", " << width << ", " << height;
1209
1210     TraceCallStack::NamedParams namedParams;
1211     namedParams["target"] << std::hex << target;
1212     namedParams["level"] << level;
1213     namedParams["xoffset"] << xoffset;
1214     namedParams["yoffset"] << yoffset;
1215     namedParams["width"] << width;
1216     namedParams["height"] << height;
1217     mTextureTrace.PushCall("TexSubImage2D", out.str(), namedParams);
1218   }
1219
1220   inline void Uniform1f(GLint location, GLfloat value) override
1221   {
1222     std::string params = std::to_string(value);
1223     AddUniformCallToTraceStack(location, params);
1224
1225     if(!mProgramUniforms1f.SetUniformValue(mCurrentProgram, location, value))
1226     {
1227       mGetErrorResult = GL_INVALID_OPERATION;
1228     }
1229   }
1230
1231   inline void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override
1232   {
1233     std::string params;
1234     for(int i = 0; i < count; ++i)
1235     {
1236       params = params + std::to_string(v[i]) + ",";
1237     }
1238
1239     AddUniformCallToTraceStack(location, params);
1240
1241     for(int i = 0; i < count; ++i)
1242     {
1243       if(!mProgramUniforms1f.SetUniformValue(mCurrentProgram, location, v[i]))
1244       {
1245         mGetErrorResult = GL_INVALID_OPERATION;
1246         break;
1247       }
1248     }
1249   }
1250
1251   inline void Uniform1i(GLint location, GLint x) override
1252   {
1253     std::string params = std::to_string(x);
1254
1255     AddUniformCallToTraceStack(location, params);
1256
1257     if(!mProgramUniforms1i.SetUniformValue(mCurrentProgram, location, x))
1258     {
1259       mGetErrorResult = GL_INVALID_OPERATION;
1260     }
1261   }
1262
1263   inline void Uniform1iv(GLint location, GLsizei count, const GLint* v) override
1264   {
1265     std::ostringstream out;
1266     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1267     AddUniformCallToTraceStack(location, out.str());
1268
1269     for(int i = 0; i < count; ++i)
1270     {
1271       if(!mProgramUniforms1i.SetUniformValue(mCurrentProgram,
1272                                              location,
1273                                              v[i]))
1274       {
1275         mGetErrorResult = GL_INVALID_OPERATION;
1276         break;
1277       }
1278     }
1279   }
1280
1281   inline void Uniform2f(GLint location, GLfloat x, GLfloat y) override
1282   {
1283     std::string params = std::to_string(x) + "," + std::to_string(y);
1284     AddUniformCallToTraceStack(location, params);
1285
1286     if(!mProgramUniforms2f.SetUniformValue(mCurrentProgram,
1287                                            location,
1288                                            Vector2(x, y)))
1289     {
1290       mGetErrorResult = GL_INVALID_OPERATION;
1291     }
1292   }
1293
1294   inline void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override
1295   {
1296     std::ostringstream out;
1297     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1298     AddUniformCallToTraceStack(location, out.str());
1299
1300     for(int i = 0; i < count; ++i)
1301     {
1302       if(!mProgramUniforms2f.SetUniformValue(mCurrentProgram,
1303                                              location,
1304                                              Vector2(v[2 * i], v[2 * i + 1])))
1305       {
1306         mGetErrorResult = GL_INVALID_OPERATION;
1307         break;
1308       }
1309     }
1310   }
1311
1312   inline void Uniform2i(GLint location, GLint x, GLint y) override
1313   {
1314     std::string params = std::to_string(x) + "," + std::to_string(y);
1315     AddUniformCallToTraceStack(location, params);
1316   }
1317
1318   inline void Uniform2iv(GLint location, GLsizei count, const GLint* v) override
1319   {
1320     std::ostringstream out;
1321     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1322     AddUniformCallToTraceStack(location, out.str());
1323   }
1324
1325   inline void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override
1326   {
1327     std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z);
1328     AddUniformCallToTraceStack(location, params);
1329
1330     if(!mProgramUniforms3f.SetUniformValue(mCurrentProgram,
1331                                            location,
1332                                            Vector3(x, y, z)))
1333     {
1334       mGetErrorResult = GL_INVALID_OPERATION;
1335     }
1336   }
1337
1338   inline void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override
1339   {
1340     std::ostringstream out;
1341     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1342     AddUniformCallToTraceStack(location, out.str());
1343
1344     for(int i = 0; i < count; ++i)
1345     {
1346       if(!mProgramUniforms3f.SetUniformValue(
1347            mCurrentProgram,
1348            location,
1349            Vector3(v[3 * i], v[3 * i + 1], v[3 * i + 2])))
1350       {
1351         mGetErrorResult = GL_INVALID_OPERATION;
1352         break;
1353       }
1354     }
1355   }
1356
1357   inline void Uniform3i(GLint location, GLint x, GLint y, GLint z) override
1358   {
1359     std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z);
1360     AddUniformCallToTraceStack(location, params);
1361   }
1362
1363   inline void Uniform3iv(GLint location, GLsizei count, const GLint* v) override
1364   {
1365     std::ostringstream out;
1366     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1367     AddUniformCallToTraceStack(location, out.str());
1368   }
1369
1370   inline void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) override
1371   {
1372     std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "," + std::to_string(w);
1373     AddUniformCallToTraceStack(location, params);
1374
1375     if(!mProgramUniforms4f.SetUniformValue(mCurrentProgram,
1376                                            location,
1377                                            Vector4(x, y, z, w)))
1378     {
1379       mGetErrorResult = GL_INVALID_OPERATION;
1380     }
1381   }
1382
1383   inline void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override
1384   {
1385     std::ostringstream out;
1386     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1387     AddUniformCallToTraceStack(location, out.str());
1388
1389     for(int i = 0; i < count; ++i)
1390     {
1391       if(!mProgramUniforms4f.SetUniformValue(
1392            mCurrentProgram,
1393            location,
1394            Vector4(v[4 * i], v[4 * i + 1], v[4 * i + 2], v[4 * i + 3])))
1395       {
1396         mGetErrorResult = GL_INVALID_OPERATION;
1397         break;
1398       }
1399     }
1400   }
1401
1402   inline void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override
1403   {
1404     std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "," + std::to_string(w);
1405     AddUniformCallToTraceStack(location, params);
1406   }
1407
1408   inline void Uniform4iv(GLint location, GLsizei count, const GLint* v) override
1409   {
1410     std::ostringstream out;
1411     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
1412     AddUniformCallToTraceStack(location, out.str());
1413   }
1414
1415   inline void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1416   {
1417     std::ostringstream out;
1418     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << value[i];
1419     AddUniformCallToTraceStack(location, out.str());
1420   }
1421
1422   inline void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1423   {
1424     std::ostringstream out;
1425     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << value[i];
1426     AddUniformCallToTraceStack(location, out.str());
1427
1428     for(int i = 0; i < count; ++i)
1429     {
1430       if(!mProgramUniformsMat3.SetUniformValue(
1431            mCurrentProgram,
1432            location,
1433            Matrix3(value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], value[8])))
1434       {
1435         mGetErrorResult = GL_INVALID_OPERATION;
1436         break;
1437       }
1438     }
1439   }
1440
1441   inline void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1442   {
1443     std::ostringstream out;
1444     for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << value[i];
1445     AddUniformCallToTraceStack(location, out.str());
1446
1447     for(int i = 0; i < count; ++i)
1448     {
1449       if(!mProgramUniformsMat4.SetUniformValue(
1450            mCurrentProgram,
1451            location,
1452            Matrix(value)))
1453       {
1454         mGetErrorResult = GL_INVALID_OPERATION;
1455         break;
1456       }
1457     }
1458   }
1459
1460   inline void UseProgram(GLuint program) override
1461   {
1462     mCurrentProgram = program;
1463   }
1464
1465   inline void ValidateProgram(GLuint program) override
1466   {
1467   }
1468
1469   inline void VertexAttrib1f(GLuint indx, GLfloat x) override
1470   {
1471   }
1472
1473   inline void VertexAttrib1fv(GLuint indx, const GLfloat* values) override
1474   {
1475   }
1476
1477   inline void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override
1478   {
1479   }
1480
1481   inline void VertexAttrib2fv(GLuint indx, const GLfloat* values) override
1482   {
1483   }
1484
1485   inline void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) override
1486   {
1487   }
1488
1489   inline void VertexAttrib3fv(GLuint indx, const GLfloat* values) override
1490   {
1491   }
1492
1493   inline void VertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) override
1494   {
1495   }
1496
1497   inline void VertexAttrib4fv(GLuint indx, const GLfloat* values) override
1498   {
1499   }
1500
1501   inline void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) override
1502   {
1503     TraceCallStack::NamedParams namedParams;
1504     namedParams["index"] << index;
1505     namedParams["size"] << size;
1506     namedParams["type"] << std::hex << type;
1507     namedParams["normalized"] << (normalized ? "T" : "F");
1508     namedParams["stride"] << stride;
1509     namedParams["offset"] << std::to_string(reinterpret_cast<unsigned long>(ptr));
1510
1511     mBufferTrace.PushCall("VertexAttribPointer", namedParams.str(), namedParams);
1512   }
1513
1514   inline void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
1515   {
1516     std::string commaString(", ");
1517     std::string params(std::to_string(x) + commaString + std::to_string(y) + commaString + std::to_string(width) + commaString + std::to_string(height));
1518
1519     mViewportTrace.PushCall("Viewport", params);
1520   }
1521
1522   /* OpenGL ES 3.0 */
1523
1524   inline void ReadBuffer(GLenum mode) override
1525   {
1526   }
1527
1528   inline void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) override
1529   {
1530   }
1531
1532   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
1533   {
1534   }
1535
1536   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
1537   {
1538   }
1539
1540   inline void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) override
1541   {
1542   }
1543
1544   inline void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) override
1545   {
1546   }
1547
1548   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
1549   {
1550   }
1551
1552   inline void GenQueries(GLsizei n, GLuint* ids) override
1553   {
1554   }
1555
1556   inline void DeleteQueries(GLsizei n, const GLuint* ids) override
1557   {
1558   }
1559
1560   inline GLboolean IsQuery(GLuint id) override
1561   {
1562     return false;
1563   }
1564
1565   inline void BeginQuery(GLenum target, GLuint id) override
1566   {
1567   }
1568
1569   inline void EndQuery(GLenum target) override
1570   {
1571   }
1572
1573   inline void GetQueryiv(GLenum target, GLenum pname, GLint* params) override
1574   {
1575   }
1576
1577   inline void GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) override
1578   {
1579   }
1580
1581   inline GLboolean UnmapBuffer(GLenum target) override
1582   {
1583     return false;
1584   }
1585
1586   inline void GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) override
1587   {
1588   }
1589
1590   inline void DrawBuffers(GLsizei n, const GLenum* bufs) override
1591   {
1592   }
1593
1594   inline void UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1595   {
1596   }
1597
1598   inline void UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1599   {
1600   }
1601
1602   inline void UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1603   {
1604   }
1605
1606   inline void UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1607   {
1608   }
1609
1610   inline void UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1611   {
1612   }
1613
1614   inline void UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
1615   {
1616   }
1617
1618   inline void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override
1619   {
1620   }
1621
1622   inline void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) override
1623   {
1624   }
1625
1626   inline void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
1627   {
1628   }
1629
1630   inline GLvoid* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) override
1631   {
1632     return NULL;
1633   }
1634
1635   inline void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) override
1636   {
1637   }
1638
1639   inline void BindVertexArray(GLuint array) override
1640   {
1641   }
1642
1643   inline void DeleteVertexArrays(GLsizei n, const GLuint* arrays) override
1644   {
1645   }
1646
1647   inline void GenVertexArrays(GLsizei n, GLuint* arrays) override
1648   {
1649   }
1650
1651   inline GLboolean IsVertexArray(GLuint array) override
1652   {
1653     return false;
1654   }
1655
1656   inline void GetIntegeri_v(GLenum target, GLuint index, GLint* data) override
1657   {
1658   }
1659
1660   inline void BeginTransformFeedback(GLenum primitiveMode) override
1661   {
1662   }
1663
1664   inline void EndTransformFeedback(void) override
1665   {
1666   }
1667
1668   inline void BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) override
1669   {
1670   }
1671
1672   inline void BindBufferBase(GLenum target, GLuint index, GLuint buffer) override
1673   {
1674   }
1675
1676   inline void TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) override
1677   {
1678   }
1679
1680   inline void GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) override
1681   {
1682   }
1683
1684   inline void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) override
1685   {
1686   }
1687
1688   inline void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override
1689   {
1690   }
1691
1692   inline void GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) override
1693   {
1694   }
1695
1696   inline void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) override
1697   {
1698   }
1699
1700   inline void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) override
1701   {
1702   }
1703
1704   inline void VertexAttribI4iv(GLuint index, const GLint* v) override
1705   {
1706   }
1707
1708   inline void VertexAttribI4uiv(GLuint index, const GLuint* v) override
1709   {
1710   }
1711
1712   inline void GetUniformuiv(GLuint program, GLint location, GLuint* params) override
1713   {
1714   }
1715
1716   inline GLint GetFragDataLocation(GLuint program, const GLchar* name) override
1717   {
1718     return -1;
1719   }
1720
1721   inline void Uniform1ui(GLint location, GLuint v0) override
1722   {
1723   }
1724
1725   inline void Uniform2ui(GLint location, GLuint v0, GLuint v1) override
1726   {
1727   }
1728
1729   inline void Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) override
1730   {
1731   }
1732
1733   inline void Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) override
1734   {
1735   }
1736
1737   inline void Uniform1uiv(GLint location, GLsizei count, const GLuint* value) override
1738   {
1739   }
1740
1741   inline void Uniform2uiv(GLint location, GLsizei count, const GLuint* value) override
1742   {
1743   }
1744
1745   inline void Uniform3uiv(GLint location, GLsizei count, const GLuint* value) override
1746   {
1747   }
1748
1749   inline void Uniform4uiv(GLint location, GLsizei count, const GLuint* value) override
1750   {
1751   }
1752
1753   inline void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) override
1754   {
1755   }
1756
1757   inline void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) override
1758   {
1759   }
1760
1761   inline void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) override
1762   {
1763   }
1764
1765   inline void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override
1766   {
1767   }
1768
1769   inline const GLubyte* GetStringi(GLenum name, GLuint index) override
1770   {
1771     return NULL;
1772   }
1773
1774   inline void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) override
1775   {
1776   }
1777
1778   inline void GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) override
1779   {
1780   }
1781
1782   inline void GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) override
1783   {
1784   }
1785
1786   inline GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) override
1787   {
1788     return GL_INVALID_INDEX;
1789   }
1790
1791   inline void GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) override
1792   {
1793   }
1794
1795   inline void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) override
1796   {
1797   }
1798
1799   inline void UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override
1800   {
1801   }
1802
1803   inline void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) override
1804   {
1805   }
1806
1807   inline void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) override
1808   {
1809   }
1810
1811   inline GLsync FenceSync(GLenum condition, GLbitfield flags) override
1812   {
1813     return NULL;
1814   }
1815
1816   inline GLboolean IsSync(GLsync sync) override
1817   {
1818     return false;
1819   }
1820
1821   inline void DeleteSync(GLsync sync) override
1822   {
1823   }
1824
1825   inline GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override
1826   {
1827     return 0;
1828   }
1829
1830   inline void WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) override
1831   {
1832   }
1833
1834   inline void GetInteger64v(GLenum pname, GLint64* params) override
1835   {
1836   }
1837
1838   inline void GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) override
1839   {
1840   }
1841
1842   inline void GetInteger64i_v(GLenum target, GLuint index, GLint64* data) override
1843   {
1844   }
1845
1846   inline void GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) override
1847   {
1848   }
1849
1850   inline void GenSamplers(GLsizei count, GLuint* samplers) override
1851   {
1852   }
1853
1854   inline void DeleteSamplers(GLsizei count, const GLuint* samplers) override
1855   {
1856   }
1857
1858   inline GLboolean IsSampler(GLuint sampler) override
1859   {
1860     return false;
1861   }
1862
1863   inline void BindSampler(GLuint unit, GLuint sampler) override
1864   {
1865   }
1866
1867   inline void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override
1868   {
1869   }
1870
1871   inline void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) override
1872   {
1873   }
1874
1875   inline void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override
1876   {
1877   }
1878
1879   inline void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) override
1880   {
1881   }
1882
1883   inline void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) override
1884   {
1885   }
1886
1887   inline void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) override
1888   {
1889   }
1890
1891   inline void VertexAttribDivisor(GLuint index, GLuint divisor) override
1892   {
1893   }
1894
1895   inline void BindTransformFeedback(GLenum target, GLuint id) override
1896   {
1897   }
1898
1899   inline void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override
1900   {
1901   }
1902
1903   inline void GenTransformFeedbacks(GLsizei n, GLuint* ids) override
1904   {
1905   }
1906
1907   inline GLboolean IsTransformFeedback(GLuint id) override
1908   {
1909     return false;
1910   }
1911
1912   inline void PauseTransformFeedback(void) override
1913   {
1914   }
1915
1916   inline void ResumeTransformFeedback(void) override
1917   {
1918   }
1919
1920   inline void GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) override
1921   {
1922     mGetProgramBinaryCalled = true;
1923   }
1924
1925   inline void ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) override
1926   {
1927   }
1928
1929   inline void ProgramParameteri(GLuint program, GLenum pname, GLint value) override
1930   {
1931   }
1932
1933   inline void InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) override
1934   {
1935   }
1936
1937   inline void InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) override
1938   {
1939   }
1940
1941   inline void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) override
1942   {
1943   }
1944
1945   inline void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) override
1946   {
1947   }
1948
1949   inline void GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) override
1950   {
1951   }
1952
1953   inline void BlendBarrier(void)
1954   {
1955   }
1956
1957 private:
1958   inline void AddUniformCallToTraceStack(GLint location, const std::string& value)
1959   {
1960     std::string name    = "<not found>";
1961     bool        matched = false;
1962
1963     UniformIDMap& map = mUniforms[mCurrentProgram];
1964     for(UniformIDMap::iterator it = map.begin(); it != map.end(); ++it)
1965     {
1966       if(it->second == location)
1967       {
1968         name    = it->first;
1969         matched = true;
1970         break;
1971       }
1972     }
1973
1974     if(matched)
1975     {
1976       mSetUniformTrace.PushCall(name, value);
1977     }
1978   }
1979
1980 public: // TEST FUNCTIONS
1981   inline void SetCompileStatus(GLuint value)
1982   {
1983     mCompileStatus = value;
1984   }
1985   inline void SetLinkStatus(GLuint value)
1986   {
1987     mLinkStatus = value;
1988   }
1989   inline void SetAttribLocations(std::vector<std::string> locs)
1990   {
1991     mAttribLocs = locs;
1992   }
1993   inline void SetGetErrorResult(GLenum result)
1994   {
1995     mGetErrorResult = result;
1996   }
1997   inline void SetGetStringResult(GLubyte* result)
1998   {
1999     mGetStringResult = result;
2000   }
2001   inline void SetIsBufferResult(GLboolean result)
2002   {
2003     mIsBufferResult = result;
2004   }
2005   inline void SetIsEnabledResult(GLboolean result)
2006   {
2007     mIsEnabledResult = result;
2008   }
2009   inline void SetIsFramebufferResult(GLboolean result)
2010   {
2011     mIsFramebufferResult = result;
2012   }
2013   inline void SetIsProgramResult(GLboolean result)
2014   {
2015     mIsProgramResult = result;
2016   }
2017   inline void SetIsRenderbufferResult(GLboolean result)
2018   {
2019     mIsRenderbufferResult = result;
2020   }
2021   inline void SetIsShaderResult(GLboolean result)
2022   {
2023     mIsShaderResult = result;
2024   }
2025   inline void SetIsTextureResult(GLboolean result)
2026   {
2027     mIsTextureResult = result;
2028   }
2029   inline void SetCheckFramebufferStatusResult(GLenum result)
2030   {
2031     mCheckFramebufferStatusResult = result;
2032   }
2033   inline void SetNumBinaryFormats(GLint numFormats)
2034   {
2035     mNumBinaryFormats = numFormats;
2036   }
2037   inline void SetBinaryFormats(GLint binaryFormats)
2038   {
2039     mBinaryFormats = binaryFormats;
2040   }
2041   inline void SetProgramBinaryLength(GLint length)
2042   {
2043     mProgramBinaryLength = length;
2044   }
2045
2046   inline bool GetVertexAttribArrayState(GLuint index)
2047   {
2048     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
2049     {
2050       // out of range
2051       return false;
2052     }
2053     return mVertexAttribArrayState[index];
2054   }
2055   inline void ClearVertexAttribArrayChanged()
2056   {
2057     mVertexAttribArrayChanged = false;
2058   }
2059   inline bool GetVertexAttribArrayChanged()
2060   {
2061     return mVertexAttribArrayChanged;
2062   }
2063
2064   //Methods for CullFace verification
2065   inline void EnableCullFaceCallTrace(bool enable)
2066   {
2067     mCullFaceTrace.Enable(enable);
2068   }
2069   inline void ResetCullFaceCallStack()
2070   {
2071     mCullFaceTrace.Reset();
2072   }
2073   inline TraceCallStack& GetCullFaceTrace()
2074   {
2075     return mCullFaceTrace;
2076   }
2077
2078   //Methods for Enable/Disable call verification
2079   inline void EnableEnableDisableCallTrace(bool enable)
2080   {
2081     mEnableDisableTrace.Enable(enable);
2082   }
2083   inline void ResetEnableDisableCallStack()
2084   {
2085     mEnableDisableTrace.Reset();
2086   }
2087   inline TraceCallStack& GetEnableDisableTrace()
2088   {
2089     return mEnableDisableTrace;
2090   }
2091
2092   //Methods for Shader verification
2093   inline void EnableShaderCallTrace(bool enable)
2094   {
2095     mShaderTrace.Enable(enable);
2096   }
2097   inline void ResetShaderCallStack()
2098   {
2099     mShaderTrace.Reset();
2100   }
2101   inline TraceCallStack& GetShaderTrace()
2102   {
2103     return mShaderTrace;
2104   }
2105
2106   //Methods for Texture verification
2107   inline void EnableTextureCallTrace(bool enable)
2108   {
2109     mTextureTrace.Enable(enable);
2110   }
2111   inline void ResetTextureCallStack()
2112   {
2113     mTextureTrace.Reset();
2114   }
2115   inline TraceCallStack& GetTextureTrace()
2116   {
2117     return mTextureTrace;
2118   }
2119
2120   //Methods for Texture verification
2121   inline void EnableTexParameterCallTrace(bool enable)
2122   {
2123     mTexParameterTrace.Enable(enable);
2124   }
2125   inline void ResetTexParameterCallStack()
2126   {
2127     mTexParameterTrace.Reset();
2128   }
2129   inline TraceCallStack& GetTexParameterTrace()
2130   {
2131     return mTexParameterTrace;
2132   }
2133
2134   //Methods for Draw verification
2135   inline void EnableDrawCallTrace(bool enable)
2136   {
2137     mDrawTrace.Enable(enable);
2138   }
2139   inline void ResetDrawCallStack()
2140   {
2141     mDrawTrace.Reset();
2142   }
2143   inline TraceCallStack& GetDrawTrace()
2144   {
2145     return mDrawTrace;
2146   }
2147
2148   //Methods for Depth function verification
2149   inline void EnableDepthFunctionCallTrace(bool enable)
2150   {
2151     mDepthFunctionTrace.Enable(enable);
2152   }
2153   inline void ResetDepthFunctionCallStack()
2154   {
2155     mDepthFunctionTrace.Reset();
2156   }
2157   inline TraceCallStack& GetDepthFunctionTrace()
2158   {
2159     return mDepthFunctionTrace;
2160   }
2161
2162   //Methods for Stencil function verification
2163   inline void EnableStencilFunctionCallTrace(bool enable)
2164   {
2165     mStencilFunctionTrace.Enable(enable);
2166   }
2167   inline void ResetStencilFunctionCallStack()
2168   {
2169     mStencilFunctionTrace.Reset();
2170   }
2171   inline TraceCallStack& GetStencilFunctionTrace()
2172   {
2173     return mStencilFunctionTrace;
2174   }
2175
2176   //Methods for Scissor verification
2177   inline void EnableScissorCallTrace(bool enable)
2178   {
2179     mScissorTrace.Enable(enable);
2180   }
2181   inline void ResetScissorCallStack()
2182   {
2183     mScissorTrace.Reset();
2184   }
2185   inline TraceCallStack& GetScissorTrace()
2186   {
2187     return mScissorTrace;
2188   }
2189
2190   //Methods for Uniform function verification
2191   inline void EnableSetUniformCallTrace(bool enable)
2192   {
2193     mSetUniformTrace.Enable(enable);
2194   }
2195   inline void ResetSetUniformCallStack()
2196   {
2197     mSetUniformTrace.Reset();
2198   }
2199   inline TraceCallStack& GetSetUniformTrace()
2200   {
2201     return mSetUniformTrace;
2202   }
2203
2204   //Methods for Viewport verification
2205   inline void EnableViewportCallTrace(bool enable)
2206   {
2207     mViewportTrace.Enable(enable);
2208   }
2209   inline void ResetViewportCallStack()
2210   {
2211     mViewportTrace.Reset();
2212   }
2213   inline TraceCallStack& GetViewportTrace()
2214   {
2215     return mViewportTrace;
2216   }
2217   inline TraceCallStack& GetBufferTrace()
2218   {
2219     return mBufferTrace;
2220   }
2221
2222   template<typename T>
2223   inline bool GetUniformValue(const char* name, T& value) const
2224   {
2225     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2226         program_it != mUniforms.end();
2227         ++program_it)
2228     {
2229       const UniformIDMap& uniformIDs = program_it->second;
2230
2231       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2232       if(uniform_it != uniformIDs.end())
2233       {
2234         // found one matching uniform name, lets check the value...
2235         GLuint programId = program_it->first;
2236         GLint  uniformId = uniform_it->second;
2237
2238         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2239         return mProgramUniforms.GetUniformValue(programId, uniformId, value);
2240       }
2241     }
2242     return false;
2243   }
2244
2245   template<typename T>
2246   inline bool CheckUniformValue(const char* name, const T& value) const
2247   {
2248     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2249         program_it != mUniforms.end();
2250         ++program_it)
2251     {
2252       const UniformIDMap& uniformIDs = program_it->second;
2253
2254       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2255       if(uniform_it != uniformIDs.end())
2256       {
2257         // found one matching uniform name, lets check the value...
2258         GLuint programId = program_it->first;
2259         GLint  uniformId = uniform_it->second;
2260
2261         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2262         if(mProgramUniforms.CheckUniformValue(programId, uniformId, value))
2263         {
2264           // the value matches
2265           return true;
2266         }
2267       }
2268     }
2269
2270     fprintf(stderr, "Not found, printing possible values:\n");
2271     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2272         program_it != mUniforms.end();
2273         ++program_it)
2274     {
2275       const UniformIDMap& uniformIDs = program_it->second;
2276
2277       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2278       if(uniform_it != uniformIDs.end())
2279       {
2280         // found one matching uniform name, lets check the value...
2281         GLuint programId = program_it->first;
2282         GLint  uniformId = uniform_it->second;
2283
2284         const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(value);
2285         T                             origValue;
2286         if(mProgramUniforms.GetUniformValue(programId, uniformId, origValue))
2287         {
2288           std::stringstream out;
2289           out << uniform_it->first << ": " << origValue;
2290           fprintf(stderr, "%s\n", out.str().c_str());
2291         }
2292       }
2293     }
2294     return false;
2295   }
2296
2297   template<typename T>
2298   inline bool GetUniformValue(GLuint programId, GLuint uniformId, T& outValue) const
2299   {
2300     const ProgramUniformValue<T>& mProgramUniforms = GetProgramUniformsForType(outValue);
2301     return mProgramUniforms.GetUniformValue(programId, uniformId, outValue);
2302   }
2303
2304   inline bool GetUniformIds(const char* name, GLuint& programId, GLuint& uniformId) const
2305   {
2306     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
2307         program_it != mUniforms.end();
2308         ++program_it)
2309     {
2310       const UniformIDMap& uniformIDs = program_it->second;
2311
2312       UniformIDMap::const_iterator uniform_it = uniformIDs.find(name);
2313       if(uniform_it != uniformIDs.end())
2314       {
2315         programId = program_it->first;
2316         uniformId = uniform_it->second;
2317         return true;
2318       }
2319     }
2320     return false;
2321   }
2322
2323   inline GLuint GetLastShaderCompiled() const
2324   {
2325     return mLastShaderCompiled;
2326   }
2327
2328   inline GLuint GetLastProgramCreated() const
2329   {
2330     return mLastProgramIdUsed;
2331   }
2332
2333   inline GLbitfield GetLastClearMask() const
2334   {
2335     return mLastClearBitMask;
2336   }
2337
2338   enum AttribType
2339   {
2340     ATTRIB_UNKNOWN = -1,
2341     ATTRIB_POSITION,
2342     ATTRIB_NORMAL,
2343     ATTRIB_TEXCOORD,
2344     ATTRIB_COLOR,
2345     ATTRIB_BONE_WEIGHTS,
2346     ATTRIB_BONE_INDICES,
2347     ATTRIB_TYPE_LAST
2348   };
2349
2350   struct ScissorParams
2351   {
2352     GLint   x;
2353     GLint   y;
2354     GLsizei width;
2355     GLsizei height;
2356
2357     ScissorParams()
2358     : x(0),
2359       y(0),
2360       width(0),
2361       height(0)
2362     {
2363     }
2364   };
2365
2366   // Methods to check scissor tests
2367   inline const ScissorParams& GetScissorParams() const
2368   {
2369     return mScissorParams;
2370   }
2371
2372   struct ColorMaskParams
2373   {
2374     GLboolean red;
2375     GLboolean green;
2376     GLboolean blue;
2377     GLboolean alpha;
2378
2379     ColorMaskParams()
2380     : red(true),
2381       green(true),
2382       blue(true),
2383       alpha(true)
2384     {
2385     }
2386   };
2387
2388   inline bool GetProgramBinaryCalled() const
2389   {
2390     return mGetProgramBinaryCalled;
2391   }
2392
2393   inline unsigned int GetClearCountCalled() const
2394   {
2395     return mClearCount;
2396   }
2397
2398   inline const ColorMaskParams& GetColorMaskParams() const
2399   {
2400     return mColorMaskParams;
2401   }
2402
2403   typedef std::vector<size_t>   BufferDataCalls;
2404   inline const BufferDataCalls& GetBufferDataCalls() const
2405   {
2406     return mBufferDataCalls;
2407   }
2408   inline void ResetBufferDataCalls()
2409   {
2410     mBufferDataCalls.clear();
2411   }
2412
2413   typedef std::vector<size_t>      BufferSubDataCalls;
2414   inline const BufferSubDataCalls& GetBufferSubDataCalls() const
2415   {
2416     return mBufferSubDataCalls;
2417   }
2418   inline void ResetBufferSubDataCalls()
2419   {
2420     mBufferSubDataCalls.clear();
2421   }
2422
2423 private:
2424   GLuint                                mCurrentProgram;
2425   GLuint                                mCompileStatus;
2426   BufferDataCalls                       mBufferDataCalls;
2427   BufferSubDataCalls                    mBufferSubDataCalls;
2428   GLuint                                mLinkStatus;
2429   GLint                                 mNumberOfActiveUniforms;
2430   GLenum                                mGetErrorResult;
2431   GLubyte*                              mGetStringResult;
2432   GLboolean                             mIsBufferResult;
2433   GLboolean                             mIsEnabledResult;
2434   GLboolean                             mIsFramebufferResult;
2435   GLboolean                             mIsProgramResult;
2436   GLboolean                             mIsRenderbufferResult;
2437   GLboolean                             mIsShaderResult;
2438   GLboolean                             mIsTextureResult;
2439   GLenum                                mActiveTextureUnit;
2440   GLenum                                mCheckFramebufferStatusResult;
2441   GLint                                 mFramebufferStatus;
2442   GLenum                                mFramebufferDepthAttached;
2443   GLenum                                mFramebufferStencilAttached;
2444   GLuint                                mFramebufferColorAttachmentCount;
2445   GLuint                                mFrameBufferColorStatus;
2446   GLint                                 mNumBinaryFormats;
2447   GLint                                 mBinaryFormats;
2448   GLint                                 mProgramBinaryLength;
2449   bool                                  mVertexAttribArrayState[MAX_ATTRIBUTE_CACHE_SIZE];
2450   bool                                  mVertexAttribArrayChanged; // whether the vertex attrib array has been changed
2451   bool                                  mGetProgramBinaryCalled;
2452   typedef std::map<GLuint, std::string> ShaderSourceMap;
2453   ShaderSourceMap                       mShaderSources;
2454   std::vector<std::string>              mAttribLocs; // should be bound to shader
2455   GLuint                                mLastShaderCompiled;
2456   GLbitfield                            mLastClearBitMask;
2457   Vector4                               mLastClearColor;
2458   unsigned int                          mClearCount;
2459
2460   Vector4 mLastBlendColor;
2461   GLenum  mLastBlendEquationRgb;
2462   GLenum  mLastBlendEquationAlpha;
2463   GLenum  mLastBlendFuncSrcRgb;
2464   GLenum  mLastBlendFuncDstRgb;
2465   GLenum  mLastBlendFuncSrcAlpha;
2466   GLenum  mLastBlendFuncDstAlpha;
2467
2468   GLboolean mLastDepthMask;
2469
2470   // Data for manipulating the IDs returned by GenTextures
2471   GLuint              mLastAutoTextureIdUsed;
2472   GLuint              mNumGeneratedTextures;
2473   std::vector<GLuint> mNextTextureIds;
2474   std::vector<GLuint> mDeletedTextureIds;
2475   std::vector<GLuint> mBoundTextures;
2476
2477   struct ActiveTextureType
2478   {
2479     std::vector<GLuint> mBoundTextures;
2480   };
2481
2482   ActiveTextureType mActiveTextures[MIN_TEXTURE_UNIT_LIMIT];
2483
2484   TraceCallStack mBufferTrace;
2485   TraceCallStack mCullFaceTrace;
2486   TraceCallStack mEnableDisableTrace;
2487   TraceCallStack mShaderTrace;
2488   TraceCallStack mTextureTrace;
2489   TraceCallStack mTexParameterTrace;
2490   TraceCallStack mDrawTrace;
2491   TraceCallStack mDepthFunctionTrace;
2492   TraceCallStack mStencilFunctionTrace;
2493   TraceCallStack mScissorTrace;
2494   TraceCallStack mSetUniformTrace;
2495   TraceCallStack mViewportTrace;
2496
2497   // Shaders & Uniforms
2498   GLuint                                 mLastShaderIdUsed;
2499   GLuint                                 mLastProgramIdUsed;
2500   GLuint                                 mLastUniformIdUsed;
2501   typedef std::map<std::string, GLint>   UniformIDMap;
2502   typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
2503   ProgramUniformMap                      mUniforms;
2504
2505   template<typename T>
2506   struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >
2507   {
2508   public:
2509     typedef std::map<GLint, T>                UniformValueMap;
2510     typedef std::map<GLuint, UniformValueMap> Map;
2511
2512     bool SetUniformValue(GLuint program, GLuint uniform, const T& value)
2513     {
2514       if(program == 0)
2515       {
2516         return false;
2517       }
2518
2519       typename Map::iterator it = Map::find(program);
2520       if(it == Map::end())
2521       {
2522         // if its the first uniform for this program add it
2523         std::pair<typename Map::iterator, bool> result =
2524           Map::insert(typename Map::value_type(program, UniformValueMap()));
2525         it = result.first;
2526       }
2527
2528       UniformValueMap& uniforms = it->second;
2529       uniforms[uniform]         = value;
2530
2531       return true;
2532     }
2533
2534     bool CheckUniformValue(GLuint program, GLuint uniform, const T& value) const
2535     {
2536       T uniformValue;
2537       if(GetUniformValue(program, uniform, uniformValue))
2538       {
2539         return CompareType<T>(value, uniformValue, Math::MACHINE_EPSILON_10);
2540       }
2541
2542       return false;
2543     }
2544
2545     bool GetUniformValue(GLuint program, GLuint uniform, T& value) const
2546     {
2547       if(program == 0)
2548       {
2549         return false;
2550       }
2551
2552       typename Map::const_iterator it = Map::find(program);
2553       if(it == Map::end())
2554       {
2555         // Uniform values always initialised as 0
2556         value = GetZero();
2557         return true;
2558       }
2559
2560       const UniformValueMap&                   uniforms = it->second;
2561       typename UniformValueMap::const_iterator it2      = uniforms.find(uniform);
2562       if(it2 == uniforms.end())
2563       {
2564         // Uniform values always initialised as 0
2565         value = GetZero();
2566         return true;
2567       }
2568       value = it2->second;
2569
2570       return true;
2571     }
2572
2573     T GetZero() const;
2574   };
2575   ProgramUniformValue<int>     mProgramUniforms1i;
2576   ProgramUniformValue<float>   mProgramUniforms1f;
2577   ProgramUniformValue<Vector2> mProgramUniforms2f;
2578   ProgramUniformValue<Vector3> mProgramUniforms3f;
2579   ProgramUniformValue<Vector4> mProgramUniforms4f;
2580   ProgramUniformValue<Matrix>  mProgramUniformsMat4;
2581   ProgramUniformValue<Matrix3> mProgramUniformsMat3;
2582
2583   inline const ProgramUniformValue<int>& GetProgramUniformsForType(const int) const
2584   {
2585     return mProgramUniforms1i;
2586   }
2587   inline const ProgramUniformValue<float>& GetProgramUniformsForType(const float) const
2588   {
2589     return mProgramUniforms1f;
2590   }
2591   inline const ProgramUniformValue<Vector2>& GetProgramUniformsForType(const Vector2&) const
2592   {
2593     return mProgramUniforms2f;
2594   }
2595   inline const ProgramUniformValue<Vector3>& GetProgramUniformsForType(const Vector3&) const
2596   {
2597     return mProgramUniforms3f;
2598   }
2599   inline const ProgramUniformValue<Vector4>& GetProgramUniformsForType(const Vector4&) const
2600   {
2601     return mProgramUniforms4f;
2602   }
2603   inline const ProgramUniformValue<Matrix>& GetProgramUniformsForType(const Matrix&) const
2604   {
2605     return mProgramUniformsMat4;
2606   }
2607   inline const ProgramUniformValue<Matrix3>& GetProgramUniformsForType(const Matrix3&) const
2608   {
2609     return mProgramUniformsMat3;
2610   }
2611   inline void SetVertexAttribArray(GLuint index, bool state)
2612   {
2613     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
2614     {
2615       // out of range
2616       return;
2617     }
2618     mVertexAttribArrayState[index] = state;
2619     mVertexAttribArrayChanged      = true;
2620   }
2621
2622   ScissorParams   mScissorParams;
2623   ColorMaskParams mColorMaskParams;
2624 };
2625
2626 template<>
2627 inline int TestGlAbstraction::ProgramUniformValue<int>::GetZero() const
2628 {
2629   return 0;
2630 }
2631
2632 template<>
2633 inline float TestGlAbstraction::ProgramUniformValue<float>::GetZero() const
2634 {
2635   return 0.0f;
2636 }
2637
2638 template<>
2639 inline Vector2 TestGlAbstraction::ProgramUniformValue<Vector2>::GetZero() const
2640 {
2641   return Vector2::ZERO;
2642 }
2643
2644 template<>
2645 inline Vector3 TestGlAbstraction::ProgramUniformValue<Vector3>::GetZero() const
2646 {
2647   return Vector3::ZERO;
2648 }
2649
2650 template<>
2651 inline Vector4 TestGlAbstraction::ProgramUniformValue<Vector4>::GetZero() const
2652 {
2653   return Vector4::ZERO;
2654 }
2655
2656 template<>
2657 inline Matrix TestGlAbstraction::ProgramUniformValue<Matrix>::GetZero() const
2658 {
2659   return Matrix();
2660 }
2661
2662 template<>
2663 inline Matrix3 TestGlAbstraction::ProgramUniformValue<Matrix3>::GetZero() const
2664 {
2665   return Matrix3(Matrix());
2666 }
2667
2668 } // namespace Dali
2669
2670 bool BlendEnabled(const Dali::TraceCallStack& callStack);
2671 bool BlendDisabled(const Dali::TraceCallStack& callStack);
2672
2673 #endif // TEST_GL_ABSTRACTION_H