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