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