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