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