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