Merge "Removed bogus consts and fixed out-of-line definitions." into tizen
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / context.h
1 #ifndef __DALI_INTERNAL_CONTEXT_H__
2 #define __DALI_INTERNAL_CONTEXT_H__
3
4 /*
5  * Copyright (c) 2014 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 // INTERNAL INCLUDES
22 #include <dali/public-api/actors/renderable-actor.h>
23 #include <dali/public-api/common/dali-vector.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/math/rect.h>
26 #include <dali/public-api/math/vector4.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/gl-abstraction.h>
29 #include <dali/integration-api/gl-defines.h>
30 #include <dali/internal/render/common/performance-monitor.h>
31 #include <dali/internal/render/gl-resources/texture-units.h>
32 #include <dali/internal/render/gl-resources/gl-call-debug.h>
33
34 namespace Dali
35 {
36
37 namespace Internal
38 {
39
40 /**
41  * Context records the current GL state, and provides access to the OpenGL ES 2.0 API.
42  * Context avoids duplicate GL calls, if the same setting etc. is requested repeatedly.
43  */
44 class Context
45 {
46 public:
47   /**
48    * Size of the VertexAttributeArray enables
49    * GLES specification states that there's minimum of 8
50    */
51   static const unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
52
53   static const unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
54
55   /**
56    * Creates the Dali Context object.
57    * This method does not create an OpenGL context i.e. that is done from outside dali-core.
58    * @pre Context has not been created.
59    * @exception Context already created.
60    * @param glAbstraction the gl abstraction.
61    */
62   Context( Integration::GlAbstraction& glAbstraction );
63
64   /**
65    * Destructor
66    */
67   ~Context();
68
69   /**
70    * Called when the GL context has been created.
71    */
72   void GlContextCreated();
73
74   /**
75    * Called when the GL context has been destroyed.
76    */
77   void GlContextDestroyed();
78
79   /**
80    * Query whether the OpenGL context has been created.
81    * @return True if the OpenGL context has been created.
82    */
83   bool IsGlContextCreated() { return mGlContextCreated; }
84
85   /**
86    * @return the GLAbstraction
87    */
88   Integration::GlAbstraction& GetAbstraction() { return mGlAbstraction; }
89
90 #ifdef DEBUG_ENABLED
91
92   /**
93    * Debug helper which prints the currently cached GL state.
94    */
95   void PrintCurrentState();
96
97 #endif
98
99   /**
100    * Helper to convert GL error code to string
101    * @param errorCode to convert
102    * @return C string
103    */
104   const char* ErrorToString( GLenum errorCode );
105
106   /**
107    * Helper to print GL string to debug log
108    */
109   void PrintGlString(const char* stringName, GLenum stringId)
110   {
111     DALI_LOG_INFO(Debug::Filter::gRender, Debug::General, "GL %s = %s\n", stringName, (const char *)GetString( stringId ) );
112   }
113
114   /****************************************************************************************
115    * The following methods are forwarded to Dali::Integration::GlAbstraction.
116    * In some cases the GL state is recorded, to avoid duplicate calls with the same state.
117    * All Shader, Program, Uniform and Attribute related calls are not here, Program class
118    * handles them and optimizes any program related state changes
119    ****************************************************************************************/
120
121   /**
122    * Wrapper for OpenGL ES 2.0 glActiveTexture()
123    */
124   void ActiveTexture( TextureUnit textureUnit )
125   {
126     if ( textureUnit != mActiveTextureUnit )
127     {
128       mActiveTextureUnit = textureUnit;
129       LOG_GL("ActiveTexture %x\n", textureUnit);
130       CHECK_GL( mGlAbstraction, mGlAbstraction.ActiveTexture(TextureUnitAsGLenum(textureUnit)) );
131     }
132   }
133
134   /**
135    * Wrapper for OpenGL ES 3.0 glBeginQuery()
136    */
137   void BeginQuery(GLenum target, GLuint id)
138   {
139     LOG_GL("BeginQuery %d %d\n", target, id);
140     CHECK_GL( mGlAbstraction, mGlAbstraction.BeginQuery(target, id) );
141   }
142
143   /**
144    * Wrapper for OpenGL ES 3.0 glBeginTransformFeedback()
145    */
146   void BeginTransformFeedback(GLenum primitiveMode)
147   {
148     LOG_GL("BeginTransformFeedback %x\n", primitiveMode);
149     CHECK_GL( mGlAbstraction, mGlAbstraction.BeginTransformFeedback(primitiveMode) );
150   }
151
152   /**
153    * The wrapper for OpenGL ES 2.0 glBindBuffer() has been replaced by BindArrayBuffer & BindElementArrayBuffer & BindTransformFeedbackBuffer.
154    */
155
156   /**
157    * Wrapper for OpenGL ES 2.0 glBindBuffer(GL_ARRAY_BUFFER, ...)
158    */
159   void BindArrayBuffer(GLuint buffer)
160   {
161     // Avoid unecessary calls to BindBuffer
162     if (mBoundArrayBufferId != buffer)
163     {
164       mBoundArrayBufferId = buffer;
165
166       LOG_GL("BindBuffer GL_ARRAY_BUFFER %d\n", buffer);
167       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBuffer(GL_ARRAY_BUFFER, buffer) );
168     }
169   }
170
171   /**
172    * Wrapper for OpenGL ES 2.0 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)
173    */
174   void BindElementArrayBuffer(GLuint buffer)
175   {
176     // Avoid unecessary calls to BindBuffer
177     if (mBoundElementArrayBufferId!= buffer)
178     {
179       mBoundElementArrayBufferId = buffer;
180
181       LOG_GL("BindBuffer GL_ELEMENT_ARRAY_BUFFER %d\n", buffer);
182       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer) );
183     }
184   }
185
186   /**
187    * Wrapper for OpenGL ES 3.0 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ...)
188    */
189   void BindTransformFeedbackBuffer(GLuint buffer)
190   {
191     // Avoid unecessary calls to BindBuffer
192     if (mBoundTransformFeedbackBufferId != buffer)
193     {
194       mBoundTransformFeedbackBufferId = buffer;
195
196       LOG_GL("BindBuffer GL_TRANSFORM_FEEDBACK_BUFFER %d\n", buffer);
197       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER , buffer) );
198     }
199   }
200
201   /**
202    * Wrapper for OpenGL ES 3.0 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ...)
203    */
204   void BindTransformFeedbackBufferBase(GLuint index, GLuint buffer)
205   {
206     // Avoid unecessary calls to BindBufferBase
207     if (mBoundTransformFeedbackBufferId != buffer)
208     {
209       mBoundTransformFeedbackBufferId = buffer;
210
211       LOG_GL("BindBufferBase GL_TRANSFORM_FEEDBACK_BUFFER %d %d\n", index, buffer);
212       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index, buffer) );
213     }
214   }
215
216   /**
217    * Wrapper for OpenGL ES 2.0 glBindFramebuffer()
218    */
219   void BindFramebuffer(GLenum target, GLuint framebuffer)
220   {
221     LOG_GL("BindFramebuffer %d %d\n", target, framebuffer);
222     CHECK_GL( mGlAbstraction, mGlAbstraction.BindFramebuffer(target, framebuffer) );
223   }
224
225   /**
226    * Wrapper for OpenGL ES 2.0 glBindRenderbuffer()
227    */
228   void BindRenderbuffer(GLenum target, GLuint renderbuffer)
229   {
230     LOG_GL("BindRenderbuffer %d %d\n", target, renderbuffer);
231     CHECK_GL( mGlAbstraction, mGlAbstraction.BindRenderbuffer(target, renderbuffer) );
232   }
233
234   /**
235    * Wrapper for OpenGL ES 3.0 glBindTransformFeedback()
236    */
237   void BindTransformFeedback(GLenum target, GLuint id)
238   {
239     LOG_GL("BindTransformFeedback %d %d\n", target, id);
240     CHECK_GL( mGlAbstraction, mGlAbstraction.BindTransformFeedback(target, id) );
241   }
242
243   /**
244    * Helper to bind texture for rendering. If given texture is
245    * already bound in the given textureunit, this method does nothing.
246    * Otherwise changes the active texture unit and binds the texture.
247    * Note! after this call active texture unit may not necessarily be the one
248    * passed in as argument so you cannot change texture unit state!!
249    * @param textureunit to bind to
250    * @param texture to bind
251    */
252   void BindTextureForUnit( TextureUnit textureunit, GLuint texture )
253   {
254     if( mBound2dTextureId[ textureunit ] != texture )
255     {
256       ActiveTexture( textureunit );
257       Bind2dTexture( texture );
258     }
259   }
260
261   /**
262    * Wrapper for OpenGL ES 2.0 glBindTexture(GL_TEXTURE_2D)
263    */
264   void Bind2dTexture( GLuint texture )
265   {
266     if (mBound2dTextureId[ mActiveTextureUnit ] != texture)
267     {
268       mBound2dTextureId[ mActiveTextureUnit ] = texture;
269
270       LOG_GL("BindTexture GL_TEXTURE_2D %d\n", texture);
271       CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(GL_TEXTURE_2D, texture) );
272
273       INCREASE_COUNTER(PerformanceMonitor::TEXTURE_STATE_CHANGES);
274     }
275   }
276
277   /**
278    * Wrapper for OpenGL ES 2.0 glBlendColor()
279    */
280   void SetDefaultBlendColor()
281   {
282     if( !mUsingDefaultBlendColor )
283     {
284       LOG_GL( "BlendColor %f %f %f %f\n", 0.0f, 0.0f, 0.0f, 0.0f );
285       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendColor( 0.0f, 0.0f, 0.0f, 0.0f ) );
286       mUsingDefaultBlendColor = true;
287     }
288   }
289
290   /**
291    * Wrapper for OpenGL ES 2.0 glBlendColor()
292    */
293   void SetCustomBlendColor( const Vector4& color )
294   {
295     LOG_GL( "BlendColor %f %f %f %f\n", color.r, color.g, color.b, color.a );
296     CHECK_GL( mGlAbstraction, mGlAbstraction.BlendColor(color.r, color.g, color.b, color.a) );
297     mUsingDefaultBlendColor = false;
298   }
299
300   /**
301    * Wrapper for OpenGL ES 2.0 glBlendEquation()
302    */
303   void BlendEquation(GLenum mode)
304   {
305     // use BlendEquationSeparate to set the rgb and alpha modes the same
306     BlendEquationSeparate( mode, mode );
307   }
308
309   /**
310    * Wrapper for OpenGL ES 2.0 glBlendEquationSeparate()
311    */
312   void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
313   {
314     if( ( modeRGB != mBlendEquationSeparateModeRGB ) ||
315         ( modeAlpha != mBlendEquationSeparateModeAlpha ) )
316     {
317       mBlendEquationSeparateModeRGB = modeRGB;
318       mBlendEquationSeparateModeAlpha = modeAlpha;
319       LOG_GL("BlendEquationSeparate %d %d\n", modeRGB, modeAlpha);
320       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendEquationSeparate(modeRGB, modeAlpha) );
321     }
322   }
323
324   /**
325    * Wrapper for OpenGL ES 2.0 glBlendFunc()
326    */
327   void BlendFunc(GLenum sfactor, GLenum dfactor)
328   {
329     // reuse the BlendFuncSeparate as thats what the DDK does anyways
330     BlendFuncSeparate( sfactor, dfactor, sfactor, dfactor );
331   }
332
333   /**
334    * Wrapper for OpenGL ES 2.0 glBlendFuncSeparate()
335    */
336   void BlendFuncSeparate( GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha )
337   {
338     if( ( mBlendFuncSeparateSrcRGB != srcRGB )||( mBlendFuncSeparateDstRGB != dstRGB )||
339         ( mBlendFuncSeparateSrcAlpha != srcAlpha )||( mBlendFuncSeparateDstAlpha != dstAlpha ) )
340     {
341       mBlendFuncSeparateSrcRGB = srcRGB;
342       mBlendFuncSeparateDstRGB = dstRGB;
343       mBlendFuncSeparateSrcAlpha = srcAlpha;
344       mBlendFuncSeparateDstAlpha = dstAlpha;
345
346       LOG_GL( "BlendFuncSeparate %d %d %d %d\n", srcRGB, dstRGB, srcAlpha, dstAlpha );
347       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendFuncSeparate( srcRGB, dstRGB, srcAlpha, dstAlpha ) );
348     }
349   }
350
351   /**
352    * Wrapper for OpenGL ES 3.0 glBlitFramebuffer()
353    */
354   void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
355   {
356     LOG_GL( "BlitFramebuffer %d %d %d %d %d %d %d %d %x %d\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter );
357     CHECK_GL( mGlAbstraction, mGlAbstraction.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter ) );
358   }
359
360   /**
361    * Wrapper for OpenGL ES 2.0 glBufferData()
362    */
363   void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage)
364   {
365     LOG_GL("BufferData %d %d %p %d\n", target, size, data, usage);
366     CHECK_GL( mGlAbstraction, mGlAbstraction.BufferData(target, size, data, usage) );
367   }
368
369   /**
370    * Wrapper for OpenGL ES 2.0 glBufferSubData()
371    */
372   void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data)
373   {
374     LOG_GL("BufferSubData %d %d %d %p\n", target, offset, size, data);
375     CHECK_GL( mGlAbstraction, mGlAbstraction.BufferSubData(target, offset, size, data) );
376   }
377
378   /**
379    * Wrapper for OpenGL ES 2.0  glCheckFramebufferStatus()
380    */
381   GLenum CheckFramebufferStatus(GLenum target)
382   {
383     LOG_GL("CheckFramebufferStatus %d\n", target);
384     GLenum value = CHECK_GL( mGlAbstraction, mGlAbstraction.CheckFramebufferStatus(target) );
385     return value;
386   }
387
388   /**
389    * Wrapper for OpenGL ES 2.0 glClear()
390    */
391   void Clear(GLbitfield mask)
392   {
393     LOG_GL("Clear %d\n", mask);
394     CHECK_GL( mGlAbstraction, mGlAbstraction.Clear(mask) );
395   }
396
397   /**
398    * Wrapper for OpenGL ES 2.0 glClearColor()
399    */
400   void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
401   {
402     Vector4 newCol(red,green,blue,alpha);
403
404     if (!mClearColorSet || mClearColor !=newCol )
405     {
406       LOG_GL("ClearColor %f %f %f %f\n", red, green, blue, alpha);
407       CHECK_GL( mGlAbstraction, mGlAbstraction.ClearColor(red, green, blue, alpha) );
408
409       mClearColorSet = true;
410       mClearColor = newCol;
411     }
412   }
413
414   /**
415    * Wrapper for OpenGL ES 2.0 glClearDepthf()
416    */
417   void ClearDepthf(GLclampf depth)
418   {
419     LOG_GL("ClearDepthf %f\n", depth);
420     CHECK_GL( mGlAbstraction, mGlAbstraction.ClearDepthf(depth) );
421   }
422
423   /**
424    * Wrapper for OpenGL ES 2.0 glClearStencil()
425    */
426   void ClearStencil(GLint s)
427   {
428     LOG_GL("ClearStencil %d\n", s);
429     CHECK_GL( mGlAbstraction, mGlAbstraction.ClearStencil(s) );
430   }
431
432   /**
433    * Wrapper for OpenGL ES 2.0 glColorMask()
434    * @note This has been optimized to a single boolean value (masking individual channels is not required)
435    */
436   void ColorMask( bool flag )
437   {
438     // only change state if needed
439     if( flag != mColorMask )
440     {
441       mColorMask = flag;
442       LOG_GL("ColorMask %s %s %s %s\n", flag ? "True" : "False", flag ? "True" : "False", flag ? "True" : "False", flag ? "True" : "False");
443       CHECK_GL( mGlAbstraction, mGlAbstraction.ColorMask(flag, flag, flag, flag) );
444     }
445   }
446
447   /**
448    * Wrapper for OpenGL ES 2.0 glCompressedTexImage2D()
449    */
450   void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
451                             GLint border, GLsizei imageSize, const void* data)
452   {
453     LOG_GL("CompressedTexImage2D %d %d %x %d %d %d %d %p\n", target, level, internalformat, width, height, border, imageSize, data);
454     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data) );
455   }
456
457   /**
458    * Wrapper for OpenGL ES 3.0 glCompressedTexImage3D()
459    */
460   void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
461                             GLint border, GLsizei imageSize, const void* data)
462   {
463     LOG_GL("CompressedTexImage3D %d %d %x %d %d %d %d %d %p\n", target, level, internalformat, width, height, depth, border, imageSize, data);
464     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data) );
465   }
466
467   /**
468    * Wrapper for OpenGL ES 2.0 glCompressedTexSubImage2D()
469    */
470   void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
471                                GLenum format, GLsizei imageSize, const void* data)
472   {
473     LOG_GL("CompressedTexSubImage2D %x %d %d %d %d %d %x %d %p\n", target, level, xoffset, yoffset, width, height, format, imageSize, data);
474     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) );
475   }
476
477   /**
478    * Wrapper for OpenGL ES 3.0 glCompressedTexSubImage3D()
479    */
480   void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
481                                GLsizei width, GLsizei height, GLsizei depth,
482                                GLenum format, GLsizei imageSize, const void* data)
483   {
484     LOG_GL("CompressedTexSubImage3D %x %d %d %d %d %d %d %d %x %d %p\n", target, level, xoffset, yoffset, xoffset, width, height, depth, format, imageSize, data);
485     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data) );
486   }
487
488   /**
489    * Wrapper for OpenGL ES 2.0 glCopyTexImage2D()
490    */
491   void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
492   {
493     LOG_GL("CopyTexImage2D %x %d %x %d %d %d %d %d\n", target, level, internalformat, x, y, width, height, border);
494     CHECK_GL( mGlAbstraction, mGlAbstraction.CopyTexImage2D(target, level, internalformat, x, y, width, height, border) );
495   }
496
497   /**
498    * Wrapper for OpenGL ES 2.0 glCopyTexSubImage2D()
499    */
500   void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
501   {
502     LOG_GL("CopyTexSubImage2D %x %d %d %d %d %d %d %d\n", target, level, xoffset, yoffset, x, y, width, height);
503     CHECK_GL( mGlAbstraction, mGlAbstraction.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) );
504   }
505
506   /**
507    * Wrapper for OpenGL ES 3.0 glCopyTexSubImage3D()
508    */
509   void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
510   {
511     LOG_GL("CopyTexSubImage3D %x %d %d %d %d %d %d %d %d\n", target, level, xoffset, yoffset, zoffset, x, y, width, height);
512     CHECK_GL( mGlAbstraction, mGlAbstraction.CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height) );
513   }
514
515   /**
516    * Wrapper for OpenGL ES 2.0 glCullFace()
517    * enables GL_CULL_FACE if in any of the face culling modes
518    * otherwise disables GL_CULL_FACE
519    */
520   void CullFace(CullFaceMode mode)
521   {
522     // Avoid unnecessary calls to gl
523     if(mCullFaceMode != mode)
524     {
525       mCullFaceMode = mode;
526       switch(mode)
527       {
528         case CullNone:
529         {
530           LOG_GL("Disable GL_CULL_FACE\n");
531           CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_CULL_FACE) );
532           break;
533         }
534
535         case CullFront:
536         {
537           LOG_GL("Enable GL_CULL_FACE\n");
538           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
539           LOG_GL("Enable GL_FRONT\n");
540           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_FRONT) );
541           break;
542         }
543
544         case CullBack:
545         {
546           LOG_GL("Enable GL_CULL_FACE\n");
547           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
548           LOG_GL("Enable GL_BACK\n");
549           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_BACK) );
550           break;
551         }
552
553         case CullFrontAndBack:
554         {
555           LOG_GL("Enable GL_CULL_FACE\n");
556           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
557           LOG_GL("Enable GL_FRONT_AND_BACK\n");
558           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_FRONT_AND_BACK) );
559           break;
560         }
561
562         default:
563           break;
564       }
565     }
566   }
567
568   /**
569    * Wrapper for OpenGL ES 2.0 glDeleteBuffers()
570    */
571   void DeleteBuffers(GLsizei n, const GLuint* buffers)
572   {
573     // @todo: this is to prevent mesh destructor from doing GL calls when DALi core is being deleted
574     // can be taken out once render manages either knows about meshes or gpubuffers and can tell them directly that context is lost
575     if( this->IsGlContextCreated() )
576     {
577       LOG_GL("DeleteBuffers %d %p\n", n, buffers);
578       CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteBuffers(n, buffers) );
579     }
580     // reset the cached buffer id's
581     // fixes problem where some drivers will a generate a buffer with the
582     // same id, as the last deleted buffer id.
583     mBoundArrayBufferId = 0;
584     mBoundElementArrayBufferId = 0;
585     mBoundTransformFeedbackBufferId = 0;
586   }
587
588   /**
589    * Wrapper for OpenGL ES 2.0 glDeleteFramebuffers()
590    */
591   void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
592   {
593     LOG_GL("DeleteFramebuffers %d %p\n", n, framebuffers);
594     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteFramebuffers(n, framebuffers) );
595   }
596
597   /**
598    * Wrapper for OpenGL ES 3.0 glDeleteQueries()
599    */
600   void DeleteQueries(GLsizei n, GLuint* ids)
601   {
602     LOG_GL("DeleteQueries %d %p\n", n, ids);
603     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteQueries(n, ids) );
604   }
605
606   /**
607    * Wrapper for OpenGL ES 2.0 glDeleteRenderbuffers()
608    */
609   void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
610   {
611     LOG_GL("DeleteRenderbuffers %d %p\n", n, renderbuffers);
612     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteRenderbuffers(n, renderbuffers) );
613   }
614
615   /**
616    * Wrapper for OpenGL ES 2.0 glDeleteTextures()
617    */
618   void DeleteTextures(GLsizei n, const GLuint* textures)
619   {
620     LOG_GL("DeleteTextures %d %p\n", n, textures);
621     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteTextures(n, textures) );
622
623     // reset the cached texture id's incase the driver re-uses them
624     // when creating new textures
625     for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
626     {
627        mBound2dTextureId[ i ] = 0;
628     }
629   }
630
631   /**
632    * Wrapper for OpenGL ES 3.0 glDeleteTransformFeedbacks()
633    */
634   void DeleteTransformFeedbacks(GLsizei n, GLuint* ids)
635   {
636     LOG_GL("DeleteTransformFeedbacks %d %p\n", n, ids);
637     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteTransformFeedbacks(n, ids) );
638   }
639
640   /**
641    * Wrapper for OpenGL ES 2.0 glDepthFunc()
642    */
643   void DepthFunc(GLenum func)
644   {
645     LOG_GL("DepthFunc %x\n", func);
646     CHECK_GL( mGlAbstraction, mGlAbstraction.DepthFunc(func) );
647   }
648
649   /**
650    * Wrapper for OpenGL ES 2.0 glDepthMask()
651    */
652   void DepthMask(GLboolean flag)
653   {
654     // only change state if needed
655     if( flag != mDepthMaskEnabled )
656     {
657       mDepthMaskEnabled = flag;
658       LOG_GL("DepthMask %s\n", flag ? "True" : "False");
659       CHECK_GL( mGlAbstraction, mGlAbstraction.DepthMask( mDepthMaskEnabled ) );
660     }
661   }
662
663   /**
664    * Wrapper for OpenGL ES 2.0 glDepthRangef()
665    */
666   void DepthRangef(GLclampf zNear, GLclampf zFar)
667   {
668     LOG_GL("DepthRangef %f %f\n", zNear, zFar);
669     CHECK_GL( mGlAbstraction, mGlAbstraction.DepthRangef(zNear, zFar) );
670   }
671
672   /**
673    * The wrapper for OpenGL ES 2.0 glDisable() has been replaced by SetBlend, SetCullFace, SetDepthTest,
674    * SetDither, SetPolygonOffsetFill, SetSampleAlphaToCoverage, SetSampleCoverage, SetScissorTest & SetStencilTest.
675    */
676
677   /**
678    * Wrapper for OpenGL ES 2.0 glDrawArrays()
679    */
680   void DrawArrays(GLenum mode, GLint first, GLsizei count)
681   {
682     FlushVertexAttributeLocations();
683
684     LOG_GL("DrawArrays %x %d %d\n", mode, first, count);
685     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawArrays(mode, first, count) );
686   }
687
688   /**
689    * Wrapper for OpenGL ES 3.0 glDrawArraysInstanced()
690    */
691   void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
692   {
693     FlushVertexAttributeLocations();
694
695     LOG_GL("DrawArraysInstanced %x %d %d %d\n", mode, first, count, instanceCount);
696     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawArraysInstanced(mode, first, count,instanceCount) );
697   }
698
699   /**
700    * Wrapper for OpenGL ES 3.0 glDrawBuffers()
701    */
702   void DrawBuffers(GLsizei n, const GLenum* bufs)
703   {
704     LOG_GL("DrawBuffers %d %p\n", n, bufs);
705     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawBuffers(n, bufs) );
706   }
707
708   /**
709    * Wrapper for OpenGL ES 2.0 glDrawElements()
710    */
711   void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
712   {
713     FlushVertexAttributeLocations();
714
715     LOG_GL("DrawElements %x %d %d %p\n", mode, count, type, indices);
716     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawElements(mode, count, type, indices) );
717   }
718
719   /**
720    * Wrapper for OpenGL ES 3.0 glDrawElementsInstanced()
721    */
722   void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instanceCount)
723   {
724     FlushVertexAttributeLocations();
725
726     LOG_GL("DrawElementsInstanced %x %d %d %p %d\n", mode, count, type, indices, instanceCount);
727     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawElementsInstanced(mode, count, type, indices, instanceCount) );
728   }
729
730   /**
731    * Wrapper for OpenGL ES 3.0 glDrawRangeElements()
732    */
733   void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
734   {
735     FlushVertexAttributeLocations();
736
737     LOG_GL("DrawRangeElements %x %u %u %d %d %p\n", mode, start, end, count, type, indices);
738     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawRangeElements(mode, start, end, count, type, indices) );
739   }
740
741   /**
742    * Wrapper for OpenGL ES 3.0 glGenQuerieS()
743    */
744   void GenQueries(GLsizei n, GLuint* ids)
745   {
746     LOG_GL("GenQueries %d %p\n", n, ids);
747     CHECK_GL( mGlAbstraction, mGlAbstraction.GenQueries(n, ids) );
748   }
749
750   /**
751    * Wrapper for OpenGL ES 3.0 glGenTransformFeedbacks()
752    */
753   void GenTransformFeedbacks(GLsizei n, GLuint* ids)
754   {
755     LOG_GL("GenTransformFeedbacks %d %p\n", n, ids);
756     CHECK_GL( mGlAbstraction, mGlAbstraction.GenTransformFeedbacks(n, ids) );
757   }
758
759   /**
760    * @return the current buffer bound for a given target
761    */
762   GLuint GetCurrentBoundArrayBuffer(GLenum target)
763   {
764     GLuint result(0);
765     switch(target)
766     {
767       case GL_ARRAY_BUFFER:
768       {
769         result = mBoundArrayBufferId;
770         break;
771       }
772       case GL_ELEMENT_ARRAY_BUFFER:
773       {
774         result = mBoundElementArrayBufferId;
775         break;
776       }
777       case GL_TRANSFORM_FEEDBACK_BUFFER:
778       {
779         result = mBoundTransformFeedbackBufferId;
780         break;
781       }
782       default:
783       {
784         DALI_ASSERT_DEBUG(0 && "target buffer type not supported");
785       }
786     }
787     return result;
788   }
789
790   void EnableVertexAttributeArray( GLuint location )
791   {
792     SetVertexAttributeLocation( location, true);
793   }
794
795   void DisableVertexAttributeArray( GLuint location )
796   {
797     SetVertexAttributeLocation( location, false);
798   }
799
800   /**
801    * Wrapper for OpenGL ES 3.0 glVertexAttribDivisor()
802    */
803   void VertexAttribDivisor ( GLuint index, GLuint divisor )
804   {
805     LOG_GL("VertexAttribDivisor(%d, %d)\n", index, divisor );
806     CHECK_GL( mGlAbstraction, mGlAbstraction.VertexAttribDivisor( index, divisor ) );
807   }
808
809   /**
810    * Wrapper for OpenGL ES 2.0 glVertexAttribPointer()
811    */
812   void VertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr )
813   {
814     LOG_GL("VertexAttribPointer(%d, %d, %d, %d, %d, %x)\n", index, size, type, normalized, stride, ptr );
815     CHECK_GL( mGlAbstraction, mGlAbstraction.VertexAttribPointer( index, size, type, normalized, stride, ptr ) );
816   }
817
818   /**
819    * Wrapper for OpenGL ES 3.0 glInvalidateFramebuffer()
820    */
821   void InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
822   {
823     LOG_GL("InvalidateFramebuffer\n");
824     CHECK_GL( mGlAbstraction, mGlAbstraction.InvalidateFramebuffer(target, numAttachments, attachments) );
825   }
826
827   /**
828    * The wrapper for OpenGL ES 2.0 glEnable() has been replaced by SetBlend, SetCullFace, SetDepthTest,
829    * SetDither, SetPolygonOffsetFill, SetSampleAlphaToCoverage, SetSampleCoverage, SetScissorTest & SetStencilTest.
830    */
831
832   /**
833    * This method replaces glEnable(GL_BLEND) and glDisable(GL_BLEND).
834    * @param[in] enable True if GL_BLEND should be enabled.
835    */
836   void SetBlend(bool enable)
837   {
838     // Avoid unecessary calls to glEnable/glDisable
839     if (enable != mBlendEnabled)
840     {
841       mBlendEnabled = enable;
842
843       if (enable)
844       {
845         LOG_GL("Enable GL_BLEND\n");
846         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_BLEND) );
847       }
848       else
849       {
850         LOG_GL("Disable GL_BLEND\n");
851         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_BLEND) );
852       }
853     }
854   }
855
856   /**
857    * This method replaces glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST).
858    * @param[in] enable True if GL_DEPTH_TEST should be enabled.
859    */
860   void SetDepthTest(bool enable)
861   {
862     // Avoid unecessary calls to glEnable/glDisable
863     if (enable != mDepthTestEnabled)
864     {
865       mDepthTestEnabled = enable;
866
867       if (enable)
868       {
869         LOG_GL("Enable GL_DEPTH_TEST\n");
870         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_DEPTH_TEST) );
871       }
872       else
873       {
874         LOG_GL("Disable GL_DEPTH_TEST\n");
875         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_DEPTH_TEST) );
876       }
877     }
878   }
879
880   /**
881    * This method replaces glEnable(GL_DITHER) and glDisable(GL_DITHER).
882    * @param[in] enable True if GL_DITHER should be enabled.
883    */
884   void SetDither(bool enable)
885   {
886     // Avoid unecessary calls to glEnable/glDisable
887     if (enable != mDitherEnabled)
888     {
889       mDitherEnabled = enable;
890
891       if (enable)
892       {
893         LOG_GL("Enable GL_DITHER\n");
894         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_DITHER) );
895       }
896       else
897       {
898         LOG_GL("Disable GL_DITHER\n");
899         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_DITHER) );
900       }
901     }
902   }
903
904   /**
905    * This method replaces glEnable(GL_POLYGON_OFFSET_FILL) and glDisable(GL_POLYGON_OFFSET_FILL).
906    * @param[in] enable True if GL_POLYGON_OFFSET_FILL should be enabled.
907    */
908   void SetPolygonOffsetFill(bool enable)
909   {
910     // Avoid unecessary calls to glEnable/glDisable
911     if (enable != mPolygonOffsetFillEnabled)
912     {
913       mPolygonOffsetFillEnabled = enable;
914
915       if (enable)
916       {
917         LOG_GL("Enable GL_POLYGON_OFFSET_FILL\n");
918         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_POLYGON_OFFSET_FILL) );
919       }
920       else
921       {
922         LOG_GL("Disable GL_POLYGON_OFFSET_FILL\n");
923         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL) );
924       }
925     }
926   }
927
928   /**
929    * This method replaces glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) and glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE).
930    * @param[in] enable True if GL_SAMPLE_ALPHA_TO_COVERAGE should be enabled.
931    */
932   void SetSampleAlphaToCoverage(bool enable)
933   {
934     // Avoid unecessary calls to glEnable/glDisable
935     if (enable != mSampleAlphaToCoverageEnabled)
936     {
937       mSampleAlphaToCoverageEnabled = enable;
938
939       if (enable)
940       {
941         LOG_GL("Enable GL_SAMPLE_ALPHA_TO_COVERAGE\n");
942         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE) );
943       }
944       else
945       {
946         LOG_GL("Disable GL_SAMPLE_ALPHA_TO_COVERAGE\n");
947         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE) );
948       }
949     }
950   }
951
952   /**
953    * This method replaces glEnable(GL_SAMPLE_COVERAGE) and glDisable(GL_SAMPLE_COVERAGE).
954    * @param[in] enable True if GL_SAMPLE_COVERAGE should be enabled.
955    */
956   void SetSampleCoverage(bool enable)
957   {
958     // Avoid unecessary calls to glEnable/glDisable
959     if (enable != mSampleCoverageEnabled)
960     {
961       mSampleCoverageEnabled = enable;
962
963       if (enable)
964       {
965         LOG_GL("Enable GL_SAMPLE_COVERAGE\n");
966         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SAMPLE_COVERAGE) );
967       }
968       else
969       {
970         LOG_GL("Disable GL_SAMPLE_COVERAGE\n");
971         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SAMPLE_COVERAGE) );
972       }
973     }
974   }
975
976   /**
977    * This method replaces glEnable(GL_SCISSOR_TEST) and glDisable(GL_SCISSOR_TEST).
978    * @param[in] enable True if GL_SCISSOR_TEST should be enabled.
979    */
980   void SetScissorTest(bool enable)
981   {
982     // Avoid unecessary calls to glEnable/glDisable
983     if (enable != mScissorTestEnabled)
984     {
985       mScissorTestEnabled = enable;
986
987       if (enable)
988       {
989         LOG_GL("Enable GL_SCISSOR_TEST\n");
990         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SCISSOR_TEST) );
991       }
992       else
993       {
994         LOG_GL("Disable GL_SCISSOR_TEST\n");
995         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SCISSOR_TEST) );
996       }
997     }
998   }
999
1000   /**
1001    * This method replaces glEnable(GL_STENCIL_TEST) and glDisable(GL_STENCIL_TEST).
1002    * @param[in] enable True if GL_STENCIL_TEST should be enabled.
1003    */
1004   void SetStencilTest(bool enable)
1005   {
1006     // Avoid unecessary calls to glEnable/glDisable
1007     if (enable != mStencilTestEnabled)
1008     {
1009       mStencilTestEnabled = enable;
1010
1011       if (enable)
1012       {
1013         LOG_GL("Enable GL_STENCIL_TEST\n");
1014         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_STENCIL_TEST) );
1015       }
1016       else
1017       {
1018         LOG_GL("Disable GL_STENCIL_TEST\n");
1019         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_STENCIL_TEST) );
1020       }
1021     }
1022   }
1023
1024   /**
1025    * Wrapper for OpenGL ES 3.0 glEndQuery()
1026    */
1027   void EndQuery(GLenum target)
1028   {
1029     LOG_GL("EndQuery %d\n", target);
1030     CHECK_GL( mGlAbstraction, mGlAbstraction.EndQuery(target) );
1031   }
1032
1033   /**
1034    * Wrapper for OpenGL ES 3.0 glEndTransformFeedback()
1035    */
1036   void EndTransformFeedback()
1037   {
1038     LOG_GL("EndTransformFeedback\n");
1039     CHECK_GL( mGlAbstraction, mGlAbstraction.EndTransformFeedback() );
1040   }
1041
1042   /**
1043    * Wrapper for OpenGL ES 2.0 glFinish()
1044    */
1045   void Finish(void)
1046   {
1047     LOG_GL("Finish\n");
1048     CHECK_GL( mGlAbstraction, mGlAbstraction.Finish() );
1049   }
1050
1051   /**
1052    * Wrapper for OpenGL ES 2.0 glFlush()
1053    */
1054   void Flush(void)
1055   {
1056     LOG_GL("Flush\n");
1057     CHECK_GL( mGlAbstraction, mGlAbstraction.Flush() );
1058   }
1059
1060   /**
1061    * Wrapper for OpenGL ES 2.0 glFramebufferRenderbuffer()
1062    */
1063   void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1064   {
1065     LOG_GL("FramebufferRenderbuffer %x %x %x %d\n", target, attachment, renderbuffertarget, renderbuffer);
1066     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) );
1067   }
1068
1069   /**
1070    * Wrapper for OpenGL ES 2.0 glFramebufferTexture2D()
1071    */
1072   void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1073   {
1074     LOG_GL("FramebufferTexture2D %x %x %x %d %d\n", target, attachment, textarget, texture, level);
1075     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferTexture2D(target, attachment, textarget, texture, level) );
1076   }
1077
1078   /**
1079    * Wrapper for OpenGL ES 3.0 glFramebufferTextureLayer()
1080    */
1081   void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
1082   {
1083     LOG_GL("FramebufferTextureLayer %x %x %d %d %d\n", target, attachment, texture, level, layer);
1084     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferTextureLayer(target, attachment, texture, level, layer) );
1085   }
1086
1087   /**
1088    * Wrapper for OpenGL ES 2.0 glFrontFace()
1089    */
1090   void FrontFace(GLenum mode)
1091   {
1092     LOG_GL("FrontFace %x\n", mode);
1093     CHECK_GL( mGlAbstraction, mGlAbstraction.FrontFace(mode) );
1094   }
1095
1096   /**
1097    * Wrapper for OpenGL ES 2.0 glGenBuffers()
1098    */
1099   void GenBuffers(GLsizei n, GLuint* buffers)
1100   {
1101     LOG_GL("GenBuffers %d\n", n, buffers);
1102     CHECK_GL( mGlAbstraction, mGlAbstraction.GenBuffers(n, buffers) );
1103   }
1104
1105   /**
1106    * Wrapper for OpenGL ES 2.0 glGenerateMipmap()
1107    */
1108   void GenerateMipmap(GLenum target)
1109   {
1110     LOG_GL("GenerateMipmap %x\n", target);
1111     CHECK_GL( mGlAbstraction, mGlAbstraction.GenerateMipmap(target) );
1112   }
1113
1114   /**
1115    * Wrapper for OpenGL ES 2.0 glGenFramebuffers()
1116    */
1117   void GenFramebuffers(GLsizei n, GLuint* framebuffers)
1118   {
1119     LOG_GL("GenFramebuffers %d %p\n", n, framebuffers);
1120     CHECK_GL( mGlAbstraction, mGlAbstraction.GenFramebuffers(n, framebuffers) );
1121   }
1122
1123   /**
1124    * Wrapper for OpenGL ES 2.0 glGenRenderbuffers()
1125    */
1126   void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1127   {
1128     LOG_GL("GenRenderbuffers %d %p\n", n, renderbuffers);
1129     CHECK_GL( mGlAbstraction, mGlAbstraction.GenRenderbuffers(n, renderbuffers) );
1130   }
1131
1132   /**
1133    * Wrapper for OpenGL ES 2.0 glGenTextures()
1134    */
1135   void GenTextures(GLsizei n, GLuint* textures)
1136   {
1137     LOG_GL("GenTextures %d %p\n", n, textures);
1138     CHECK_GL( mGlAbstraction, mGlAbstraction.GenTextures(n, textures) );
1139   }
1140
1141   /**
1142    * Wrapper for OpenGL ES 2.0 glGetBooleanv()
1143    */
1144   void GetBooleanv(GLenum pname, GLboolean* params)
1145   {
1146     LOG_GL("GetBooleanv %x\n", pname);
1147     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBooleanv(pname, params) );
1148   }
1149
1150   /**
1151    * Wrapper for OpenGL ES 2.0 glGetBufferParameteriv()
1152    */
1153   void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1154   {
1155     LOG_GL("GetBufferParameteriv %x %x %p\n", target, pname, params);
1156     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBufferParameteriv(target, pname, params) );
1157   }
1158
1159   /**
1160    * Wrapper for OpenGL ES 3.0 glGetBufferPointer()
1161    */
1162   void GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
1163   {
1164     LOG_GL("GetBufferPointerv %x %x %p\n", target, pname, params);
1165     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBufferPointerv(target, pname, params) );
1166   }
1167
1168   /**
1169    * Wrapper for OpenGL ES 2.0 glGetError()
1170    */
1171   GLenum GetError(void)
1172   {
1173     // Not worth logging here
1174     return mGlAbstraction.GetError();
1175   }
1176
1177   /**
1178    * Wrapper for OpenGL ES 2.0 glGetFloatv()
1179    */
1180   void GetFloatv(GLenum pname, GLfloat* params)
1181   {
1182     LOG_GL("GetFloatv %x\n", pname);
1183     CHECK_GL( mGlAbstraction, mGlAbstraction.GetFloatv(pname, params) );
1184   }
1185
1186   /**
1187    * Wrapper for OpenGL ES 2.0 glGetFramebufferAttachmentParameteriv()
1188    */
1189   void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1190   {
1191     LOG_GL("GetFramebufferAttachmentParameteriv %x %x %x\n", target, attachment, pname);
1192     CHECK_GL( mGlAbstraction, mGlAbstraction.GetFramebufferAttachmentParameteriv(target, attachment, pname, params) );
1193   }
1194
1195   /**
1196    * Wrapper for OpenGL ES 2.0 glGetIntegerv()
1197    */
1198   void GetIntegerv(GLenum pname, GLint* params)
1199   {
1200     LOG_GL("GetIntegerv %x\n", pname);
1201     CHECK_GL( mGlAbstraction, mGlAbstraction.GetIntegerv(pname, params) );
1202   }
1203
1204   /**
1205    * Wrapper for OpenGL ES 3.0 glGetQueryiv()
1206    */
1207   void GetQueryiv(GLenum target, GLenum pname, GLint* params)
1208   {
1209     LOG_GL("GetQueryiv %x %x\n", target, pname);
1210     CHECK_GL( mGlAbstraction, mGlAbstraction.GetQueryiv(target, pname, params) );
1211   }
1212
1213   /**
1214    * Wrapper for OpenGL ES 3.0 glGetQueryObjectuiv()
1215    */
1216   void GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
1217   {
1218     LOG_GL("GetQueryObjectuiv %u %x %p\n", id, pname, params);
1219     CHECK_GL( mGlAbstraction, mGlAbstraction.GetQueryObjectuiv(id, pname, params) );
1220   }
1221
1222   /**
1223    * Wrapper for OpenGL ES 2.0 glGetRenderbufferParameteriv()
1224    */
1225   void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
1226   {
1227     LOG_GL("GetRenderbufferParameteriv %x %x\n", target, pname);
1228     CHECK_GL( mGlAbstraction, mGlAbstraction.GetRenderbufferParameteriv(target, pname, params) );
1229   }
1230
1231   /**
1232    * Wrapper for OpenGL ES 2.0 glGetString()
1233    */
1234   const GLubyte* GetString(GLenum name)
1235   {
1236     LOG_GL("GetString %x\n", name);
1237     const GLubyte* str = CHECK_GL( mGlAbstraction, mGlAbstraction.GetString(name) );
1238     return str;
1239   }
1240
1241   /**
1242    * Wrapper for OpenGL ES 2.0 glGetTexParameterfv()
1243    */
1244   void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
1245   {
1246     LOG_GL("GetTexParameterfv %x %x\n", target, pname);
1247     CHECK_GL( mGlAbstraction, mGlAbstraction.GetTexParameterfv(target, pname, params) );
1248   }
1249
1250   /**
1251    * Wrapper for OpenGL ES 2.0 glGetTexParameteriv()
1252    */
1253   void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
1254   {
1255     LOG_GL("GetTexParameteriv %x %x\n", target, pname);
1256     CHECK_GL( mGlAbstraction, mGlAbstraction.GetTexParameteriv(target, pname, params) );
1257   }
1258
1259   /**
1260    * Wrapper for OpenGL ES 2.0 glHint()
1261    */
1262   void Hint(GLenum target, GLenum mode)
1263   {
1264     LOG_GL("Hint %x %x\n", target, mode);
1265     CHECK_GL( mGlAbstraction, mGlAbstraction.Hint(target, mode) );
1266   }
1267
1268   /**
1269    * Wrapper for OpenGL ES 2.0 glIsBuffer()
1270    */
1271   GLboolean IsBuffer(GLuint buffer)
1272   {
1273     LOG_GL("IsBuffer %d\n", buffer);
1274     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsBuffer(buffer) );
1275     return val;
1276   }
1277
1278   /**
1279    * Wrapper for OpenGL ES 2.0 glIsEnabled()
1280    */
1281   GLboolean IsEnabled(GLenum cap)
1282   {
1283     LOG_GL("IsEnabled %x\n", cap);
1284     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsEnabled(cap) );
1285     return val;
1286   }
1287
1288   /**
1289    * Wrapper for OpenGL ES 2.0 glIsFramebuffer()
1290    */
1291   GLboolean IsFramebuffer(GLuint framebuffer)
1292   {
1293     LOG_GL("IsFramebuffer %d\n", framebuffer);
1294     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsFramebuffer(framebuffer) );
1295     return val;
1296   }
1297
1298   /**
1299    * Wrapper for OpenGL ES 3.0 glIsQuery()
1300    */
1301   GLboolean IsQuery(GLuint id)
1302   {
1303     LOG_GL("IsQuery %u\n", id);
1304     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsQuery(id) );
1305     return val;
1306   }
1307
1308   /**
1309    * Wrapper for OpenGL ES 2.0 glIsRenderbuffer()
1310    */
1311   GLboolean IsRenderbuffer(GLuint renderbuffer)
1312   {
1313     LOG_GL("IsRenderbuffer %d\n", renderbuffer);
1314     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsRenderbuffer(renderbuffer) );
1315     return val;
1316   }
1317
1318   /**
1319    * Wrapper for OpenGL ES 2.0 glIsTexture()
1320    */
1321   GLboolean IsTexture(GLuint texture)
1322   {
1323     LOG_GL("IsTexture %d\n", texture);
1324     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsTexture(texture) );
1325     return val;
1326   }
1327
1328   /**
1329    * Wrapper for OpenGL ES 3.0 glIsTransformFeedback()
1330    */
1331   GLboolean IsTransformFeedback(GLuint id)
1332   {
1333     LOG_GL("IsTransformFeedback %u\n", id);
1334     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsTransformFeedback(id) );
1335     return val;
1336   }
1337
1338   /**
1339    * Wrapper for OpenGL ES 2.0 glLineWidth()
1340    */
1341   void LineWidth(GLfloat width)
1342   {
1343     LOG_GL("LineWidth %f\n", width);
1344     CHECK_GL( mGlAbstraction, mGlAbstraction.LineWidth(width) );
1345   }
1346
1347   /**
1348    * Wrapper for OpenGL ES 3.0 glPauseTransformFeedback()
1349    */
1350   void PauseTransformFeedback()
1351   {
1352     LOG_GL("PauseTransformFeedback\n");
1353     CHECK_GL( mGlAbstraction, mGlAbstraction.PauseTransformFeedback() );
1354   }
1355
1356   /**
1357    * Wrapper for OpenGL ES 2.0 glPixelStorei()
1358    */
1359   void PixelStorei(GLenum pname, GLint param)
1360   {
1361     LOG_GL("PixelStorei %x %d\n", pname, param);
1362     CHECK_GL( mGlAbstraction, mGlAbstraction.PixelStorei(pname, param) );
1363   }
1364
1365   /**
1366    * Wrapper for OpenGL ES 2.0 glPolygonOffset()
1367    */
1368   void PolygonOffset(GLfloat factor, GLfloat units)
1369   {
1370     LOG_GL("PolygonOffset %f %f\n", factor, units);
1371     CHECK_GL( mGlAbstraction, mGlAbstraction.PolygonOffset(factor, units) );
1372   }
1373
1374   /**
1375    * Wrapper for OpenGL ES 2.0 glReadPixels()
1376    */
1377   void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
1378   {
1379     LOG_GL("ReadPixels %d %d %d %d %x %x\n", x, y, width, height, format, type);
1380     CHECK_GL( mGlAbstraction, mGlAbstraction.ReadPixels(x, y, width, height, format, type, pixels) );
1381   }
1382
1383   /**
1384    * Wrapper for OpenGL ES 2.0 glRenderbufferStorage()
1385    */
1386   void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
1387   {
1388     LOG_GL("RenderbufferStorage %x %x %d %d\n", target, internalformat, width, height);
1389     CHECK_GL( mGlAbstraction, mGlAbstraction.RenderbufferStorage(target, internalformat, width, height) );
1390   }
1391
1392   /**
1393    * Wrapper for OpenGL ES 3.0 glRenderbufferStorageMultisample()
1394    */
1395   void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
1396   {
1397     LOG_GL("RenderbufferStorageMultisample %x %u %x %d %d\n", target, samples, internalformat, width, height);
1398     CHECK_GL( mGlAbstraction, mGlAbstraction.RenderbufferStorageMultisample(target, samples, internalformat, width, height) );
1399   }
1400
1401   /**
1402    * Wrapper for OpenGL ES 3.0 glResumeTransformFeedback()
1403    */
1404   void ResumeTransformFeedback()
1405   {
1406     LOG_GL("ResumeTransformFeedback\n");
1407     CHECK_GL( mGlAbstraction, mGlAbstraction.ResumeTransformFeedback() );
1408   }
1409
1410   /**
1411    * Wrapper for OpenGL ES 2.0 glSampleCoverage()
1412    */
1413   void SampleCoverage(GLclampf value, GLboolean invert)
1414   {
1415     LOG_GL("SampleCoverage %f %s\n", value, invert ? "True" : "False");
1416     CHECK_GL( mGlAbstraction, mGlAbstraction.SampleCoverage(value, invert) );
1417   }
1418
1419   /**
1420    * Wrapper for OpenGL ES 2.0 glScissor()
1421    */
1422   void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1423   {
1424     LOG_GL("Scissor %d %d %d %d\n", x, y, width, height);
1425     CHECK_GL( mGlAbstraction, mGlAbstraction.Scissor(x, y, width, height) );
1426   }
1427
1428   /**
1429    * Wrapper for OpenGL ES 2.0 glStencilFunc()
1430    */
1431   void StencilFunc(GLenum func, GLint ref, GLuint mask)
1432   {
1433     LOG_GL("StencilFunc %x %d %d\n", func, ref, mask);
1434     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFunc(func, ref, mask) );
1435   }
1436
1437   /**
1438    * Wrapper for OpenGL ES 2.0 glStencilFuncSeparate()
1439    */
1440   void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
1441   {
1442     LOG_GL("StencilFuncSeparate %x %x %d %d\n", face, func, ref, mask);
1443     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFuncSeparate(face, func, ref, mask) );
1444   }
1445
1446   /**
1447    * Wrapper for OpenGL ES 2.0 glStencilMask()
1448    */
1449   void StencilMask(GLuint mask)
1450   {
1451     if( mask != mStencilMask )
1452     {
1453       mStencilMask = mask;
1454
1455       LOG_GL("StencilMask %d\n", mask);
1456       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilMask(mask) );
1457     }
1458   }
1459
1460   /**
1461    * Wrapper for OpenGL ES 2.0 glStencilMaskSeparate()
1462    */
1463   void StencilMaskSeparate(GLenum face, GLuint mask)
1464   {
1465     LOG_GL("StencilMaskSeparate %x %d\n", face, mask);
1466     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilMaskSeparate(face, mask) );
1467   }
1468
1469   /**
1470    * Wrapper for OpenGL ES 2.0 glStencilOp()
1471    */
1472   void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
1473   {
1474     LOG_GL("StencilOp %x %x %x\n", fail, zfail, zpass);
1475     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilOp(fail, zfail, zpass) );
1476   }
1477
1478   /**
1479    * Wrapper for OpenGL ES 2.0 glStencilOpSeparate()
1480    */
1481   void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
1482   {
1483     LOG_GL("StencilOpSeparate %x %x %x %x\n", face, fail, zfail, zpass);
1484     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilOpSeparate(face, fail, zfail, zpass) );
1485   }
1486
1487   /**
1488    * Wrapper for OpenGL ES 2.0 glTexImage2D()
1489    */
1490   void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
1491                   GLint border, GLenum format, GLenum type, const void* pixels)
1492   {
1493     LOG_GL("TexImage2D %x %d %d %dx%d %d %x %x %p\n", target, level, internalformat, width, height, border, format, type, pixels);
1494     CHECK_GL( mGlAbstraction, mGlAbstraction.TexImage2D(target, level, internalformat, width, height, border, format, type, pixels) );
1495   }
1496
1497   /**
1498    * Wrapper for OpenGL ES 3.0 glTexImage3D()
1499    */
1500   void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth,
1501                   GLint border, GLenum format, GLenum type, const void* pixels)
1502   {
1503     LOG_GL("TexImage3D %x %d %d %dx%dx%d %d %x %x %p\n", target, level, internalformat, width, height, depth, border, format, type, pixels);
1504     CHECK_GL( mGlAbstraction, mGlAbstraction.TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) );
1505   }
1506
1507   /**
1508    * Wrapper for OpenGL ES 2.0 glTexParameterf()
1509    */
1510   void TexParameterf(GLenum target, GLenum pname, GLfloat param)
1511   {
1512     LOG_GL("TexParameterf %x %x %f\n", target, pname, param);
1513     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameterf(target, pname, param) );
1514   }
1515
1516   /**
1517    * Wrapper for OpenGL ES 2.0 glTexParameterfv()
1518    */
1519   void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
1520   {
1521     LOG_GL("TexParameterfv %x %x\n", target, pname);
1522     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameterfv(target, pname, params) );
1523   }
1524
1525   /**
1526    * Wrapper for OpenGL ES 2.0 glTexParameteri()
1527    */
1528   void TexParameteri(GLenum target, GLenum pname, GLint param)
1529   {
1530     LOG_GL("TexParameteri %x %x %d\n", target, pname, param);
1531     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameteri(target, pname, param) );
1532   }
1533
1534   /**
1535    * Wrapper for OpenGL ES 2.0 glTexParameteriv()
1536    */
1537   void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
1538   {
1539     LOG_GL("TexParameteriv %x %x\n", target, pname);
1540     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameteriv(target, pname, params) );
1541   }
1542
1543   /**
1544    * Wrapper for OpenGL ES 2.0 glTexSubImage2D()
1545    */
1546   void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1547                      GLenum format, GLenum type, const void* pixels)
1548   {
1549     LOG_GL("TexSubImage2D %x %d %d %d %d %d %x %x %p\n", target, level, xoffset, yoffset, width, height, format, type, pixels);
1550     CHECK_GL( mGlAbstraction, mGlAbstraction.TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) );
1551   }
1552
1553   /**
1554    * Wrapper for OpenGL ES 3.0 glTexSubImage3D()
1555    */
1556   void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
1557                      GLsizei width, GLsizei height, GLsizei depth,
1558                      GLenum format, GLenum type, const void* pixels)
1559   {
1560     LOG_GL("TexSubImage3D %x %d %d %d %d %d %d %d %x %x %p\n", target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
1561     CHECK_GL( mGlAbstraction, mGlAbstraction.TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) );
1562   }
1563
1564   /**
1565    * Wrapper for OpenGL ES 3.0 glUnmapBubffer()
1566    */
1567   GLboolean UnmapBuffer(GLenum target)
1568   {
1569     LOG_GL("UnmapBuffer %x \n", target);
1570     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.UnmapBuffer(target) );
1571     return val;
1572   }
1573   /**
1574    * Wrapper for OpenGL ES 2.0 glViewport()
1575    */
1576   void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1577   {
1578     // check if its same as already set
1579     Rect<int> newViewport( x, y, width, height );
1580     if( mViewPort != newViewport )
1581     {
1582       // set new one
1583       LOG_GL("Viewport %d %d %d %d\n", x, y, width, height);
1584       CHECK_GL( mGlAbstraction, mGlAbstraction.Viewport(x, y, width, height) );
1585       mViewPort = newViewport; // remember new one
1586     }
1587   }
1588
1589   /**
1590    * Get the implementation defined MAX_TEXTURE_SIZE. This values is cached when the context is created
1591    * @return The implementation defined MAX_TEXTURE_SIZE
1592    */
1593   GLint CachedMaxTextureSize() const
1594   {
1595     return mMaxTextureSize;
1596   }
1597
1598   /**
1599    * Get the current viewport.
1600    * @return Viewport rectangle.
1601    */
1602   const Rect< int >& GetViewport();
1603
1604   /**
1605    * Set the frame count of render thread
1606    */
1607   inline void SetFrameCount(unsigned int frameCount)
1608   {
1609     mFrameCount = frameCount;
1610   }
1611
1612   /**
1613    * Get the frame count
1614    */
1615   inline unsigned int GetFrameCount()
1616   {
1617     return mFrameCount;
1618   }
1619
1620   /**
1621    * Increment the count of culled renderers
1622    */
1623   inline void IncrementCulledCount()
1624   {
1625     mCulledCount++;
1626   }
1627
1628   /**
1629    * Clear the count of culled renderers
1630    */
1631   inline void ClearCulledCount()
1632   {
1633     mCulledCount = 0;
1634   }
1635
1636   /**
1637    * Get the count of culled renderers in this frame
1638    */
1639   inline unsigned int GetCulledCount()
1640   {
1641     return mCulledCount;
1642   }
1643
1644   /**
1645    * Increment the count of culled renderers
1646    */
1647   inline void IncrementRendererCount()
1648   {
1649     mRendererCount++;
1650   }
1651
1652   /**
1653    * Clear the count of image renderers
1654    */
1655   inline void ClearRendererCount()
1656   {
1657     mRendererCount = 0;
1658   }
1659
1660   /**
1661    * Get the count of image renderers in this frame
1662    */
1663   inline unsigned int GetRendererCount()
1664   {
1665     return mRendererCount;
1666   }
1667
1668
1669 private: // Implementation
1670
1671   /**
1672    * Flushes vertex attribute location changes to the driver
1673    */
1674   void FlushVertexAttributeLocations();
1675
1676   /**
1677    * Reset the cached internal vertex attribute state
1678    */
1679   void ResetVertexAttributeState();
1680
1681   /**
1682    * Either enables or disables a vertex attribute location in the cache
1683    * The cahnges won't take affect until FlushVertexAttributeLocations is called
1684    * @param location attribute location
1685    * @param state attribute state
1686    */
1687   void SetVertexAttributeLocation(unsigned int location, bool state);
1688
1689   /**
1690    * Sets the initial GL state.
1691    */
1692   void ResetGlState();
1693
1694 private: // Data
1695
1696   Integration::GlAbstraction& mGlAbstraction;
1697
1698   bool mGlContextCreated; ///< True if the OpenGL context has been created
1699
1700   // glEnable/glDisable states
1701   bool mColorMask;
1702   GLuint mStencilMask;
1703   bool mBlendEnabled;
1704   bool mDepthTestEnabled;
1705   bool mDepthMaskEnabled;
1706   bool mDitherEnabled;
1707   bool mPolygonOffsetFillEnabled;
1708   bool mSampleAlphaToCoverageEnabled;
1709   bool mSampleCoverageEnabled;
1710   bool mScissorTestEnabled;
1711   bool mStencilTestEnabled;
1712   bool mClearColorSet;
1713
1714   // glBindBuffer() state
1715   GLuint mBoundArrayBufferId;        ///< The ID passed to glBindBuffer(GL_ARRAY_BUFFER)
1716   GLuint mBoundElementArrayBufferId; ///< The ID passed to glBindBuffer(GL_ELEMENT_ARRAY_BUFFER)
1717   GLuint mBoundTransformFeedbackBufferId; ///< The ID passed to glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER)
1718
1719   // glBindTexture() state
1720   TextureUnit mActiveTextureUnit;
1721   GLuint mBound2dTextureId[ MAX_TEXTURE_UNITS ];  ///< The ID passed to glBindTexture(GL_TEXTURE_2D)
1722
1723   // glBlendColor() state
1724   bool mUsingDefaultBlendColor;
1725
1726   // glBlendFuncSeparate() state
1727   GLenum mBlendFuncSeparateSrcRGB;   ///< The srcRGB parameter passed to glBlendFuncSeparate()
1728   GLenum mBlendFuncSeparateDstRGB;   ///< The dstRGB parameter passed to glBlendFuncSeparate()
1729   GLenum mBlendFuncSeparateSrcAlpha; ///< The srcAlpha parameter passed to glBlendFuncSeparate()
1730   GLenum mBlendFuncSeparateDstAlpha; ///< The dstAlpha parameter passed to glBlendFuncSeparate()
1731
1732   // glBlendEquationSeparate state
1733   GLenum mBlendEquationSeparateModeRGB;    ///< Controls RGB blend mode
1734   GLenum mBlendEquationSeparateModeAlpha;  ///< Controls Alpha blend mode
1735
1736   GLint mMaxTextureSize;      ///< return value from GetIntegerv(GL_MAX_TEXTURE_SIZE)
1737   Vector4 mClearColor;        ///< clear color
1738
1739   // Face culling mode
1740   CullFaceMode mCullFaceMode;
1741
1742   // cached viewport size
1743   Rect< int > mViewPort;
1744
1745   // Vertex Attribute Buffer enable caching
1746   bool mVertexAttributeCachedState[ MAX_ATTRIBUTE_CACHE_SIZE ];    ///< Value cache for Enable Vertex Attribute
1747   bool mVertexAttributeCurrentState[ MAX_ATTRIBUTE_CACHE_SIZE ];   ///< Current state on the driver for Enable Vertex Attribute
1748
1749   unsigned int mFrameCount;       ///< Number of render frames
1750   unsigned int mCulledCount;      ///< Number of culled renderers per frame
1751   unsigned int mRendererCount;    ///< Number of image renderers per frame
1752 };
1753
1754 } // namespace Internal
1755
1756 } // namespace Dali
1757
1758 #endif // __DALI_INTERNAL_CONTEXT_H__