Remove dependency of OpenGL es version.
[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) 2019 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/common/dali-vector.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/public-api/math/rect.h>
25 #include <dali/public-api/math/vector4.h>
26 #include <dali/public-api/rendering/renderer.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, reinterpret_cast< 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 ConvertTexture of Dali::Integration::GlAbstraction
134    */
135   void ConvertTexture( uint8_t* buffer, GLenum& imageGlFormat, const uint32_t dataSize, const GLenum textureGlFormat, const bool isSubImage )
136   {
137     return mGlAbstraction.ConvertTexture( buffer, imageGlFormat, dataSize, textureGlFormat, isSubImage );
138   }
139
140   /**
141    * Wrapper for OpenGL ES 2.0 glActiveTexture()
142    */
143   void ActiveTexture( TextureUnit textureUnit )
144   {
145     if ( textureUnit != mActiveTextureUnit )
146     {
147       mActiveTextureUnit = textureUnit;
148       LOG_GL("ActiveTexture %x\n", textureUnit);
149       CHECK_GL( mGlAbstraction, mGlAbstraction.ActiveTexture(TextureUnitAsGLenum(textureUnit)) );
150     }
151   }
152
153   /**
154    * Wrapper for OpenGL ES 3.0 glBeginQuery()
155    */
156   void BeginQuery(GLenum target, GLuint id)
157   {
158     LOG_GL("BeginQuery %d %d\n", target, id);
159     CHECK_GL( mGlAbstraction, mGlAbstraction.BeginQuery(target, id) );
160   }
161
162   /**
163    * Wrapper for OpenGL ES 3.0 glBeginTransformFeedback()
164    */
165   void BeginTransformFeedback(GLenum primitiveMode)
166   {
167     LOG_GL("BeginTransformFeedback %x\n", primitiveMode);
168     CHECK_GL( mGlAbstraction, mGlAbstraction.BeginTransformFeedback(primitiveMode) );
169   }
170
171   /**
172    * The wrapper for OpenGL ES 2.0 glBindBuffer() has been replaced by BindArrayBuffer & BindElementArrayBuffer & BindTransformFeedbackBuffer.
173    */
174
175   /**
176    * Wrapper for OpenGL ES 2.0 glBindBuffer(GL_ARRAY_BUFFER, ...)
177    */
178   void BindArrayBuffer(GLuint buffer)
179   {
180     // Avoid unecessary calls to BindBuffer
181     if (mBoundArrayBufferId != buffer)
182     {
183       mBoundArrayBufferId = buffer;
184
185       LOG_GL("BindBuffer GL_ARRAY_BUFFER %d\n", buffer);
186       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBuffer(GL_ARRAY_BUFFER, buffer) );
187     }
188   }
189
190   /**
191    * Wrapper for OpenGL ES 2.0 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)
192    */
193   void BindElementArrayBuffer(GLuint buffer)
194   {
195     // Avoid unecessary calls to BindBuffer
196     if (mBoundElementArrayBufferId!= buffer)
197     {
198       mBoundElementArrayBufferId = buffer;
199
200       LOG_GL("BindBuffer GL_ELEMENT_ARRAY_BUFFER %d\n", buffer);
201       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer) );
202     }
203   }
204
205   /**
206    * Wrapper for OpenGL ES 3.0 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ...)
207    */
208   void BindTransformFeedbackBuffer(GLuint buffer)
209   {
210     // Avoid unecessary calls to BindBuffer
211     if (mBoundTransformFeedbackBufferId != buffer)
212     {
213       mBoundTransformFeedbackBufferId = buffer;
214
215       LOG_GL("BindBuffer GL_TRANSFORM_FEEDBACK_BUFFER %d\n", buffer);
216       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER , buffer) );
217     }
218   }
219
220   /**
221    * Wrapper for OpenGL ES 3.0 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ...)
222    */
223   void BindTransformFeedbackBufferBase(GLuint index, GLuint buffer)
224   {
225     // Avoid unecessary calls to BindBufferBase
226     if (mBoundTransformFeedbackBufferId != buffer)
227     {
228       mBoundTransformFeedbackBufferId = buffer;
229
230       LOG_GL("BindBufferBase GL_TRANSFORM_FEEDBACK_BUFFER %d %d\n", index, buffer);
231       CHECK_GL( mGlAbstraction, mGlAbstraction.BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index, buffer) );
232     }
233   }
234
235   /**
236    * Wrapper for OpenGL ES 2.0 glBindFramebuffer()
237    */
238   void BindFramebuffer(GLenum target, GLuint framebuffer)
239   {
240     mFrameBufferStateCache.SetCurrentFrameBuffer( framebuffer );
241
242     LOG_GL("BindFramebuffer %d %d\n", target, framebuffer);
243     CHECK_GL( mGlAbstraction, mGlAbstraction.BindFramebuffer(target, framebuffer) );
244   }
245
246   /**
247    * Wrapper for OpenGL ES 2.0 glBindRenderbuffer()
248    */
249   void BindRenderbuffer(GLenum target, GLuint renderbuffer)
250   {
251     LOG_GL("BindRenderbuffer %d %d\n", target, renderbuffer);
252     CHECK_GL( mGlAbstraction, mGlAbstraction.BindRenderbuffer(target, renderbuffer) );
253   }
254
255   /**
256    * Wrapper for OpenGL ES 3.0 glBindTransformFeedback()
257    */
258   void BindTransformFeedback(GLenum target, GLuint id)
259   {
260     LOG_GL("BindTransformFeedback %d %d\n", target, id);
261     CHECK_GL( mGlAbstraction, mGlAbstraction.BindTransformFeedback(target, id) );
262   }
263
264   /**
265    * Helper to bind texture for rendering. If given texture is
266    * already bound in the given textureunit, this method does nothing.
267    * Otherwise changes the active texture unit and binds the texture.
268    * Note! after this call active texture unit may not necessarily be the one
269    * passed in as argument so you cannot change texture unit state!!
270    * @param textureunit to bind to
271    * @param texture to bind
272    */
273   void BindTextureForUnit( TextureUnit textureunit, int target, GLuint texture )
274   {
275     if( mBoundTextureId[ textureunit ] != texture )
276     {
277       ActiveTexture( textureunit );
278       BindTexture( target, texture );
279     }
280   }
281
282   /**
283    * Wrapper for OpenGL ES 2.0 glBindTexture( target )
284    */
285   void BindTexture( int target, GLuint texture )
286   {
287     if (mBoundTextureId[ mActiveTextureUnit ] != texture)
288     {
289       mBoundTextureId[ mActiveTextureUnit ] = texture;
290
291       LOG_GL("BindTexture target(%d) %d\n", target, texture);
292       CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(target, texture) );
293     }
294   }
295
296   /**
297    * Wrapper for OpenGL ES 2.0 glBlendColor()
298    */
299   void SetDefaultBlendColor()
300   {
301     if( ! mUsingDefaultBlendColor )
302     {
303       SetCustomBlendColor( Color::TRANSPARENT );
304       mUsingDefaultBlendColor = true;
305     }
306   }
307
308   /**
309    * Wrapper for OpenGL ES 2.0 glBlendColor()
310    */
311   void SetCustomBlendColor( const Vector4& color )
312   {
313     if( mUsingDefaultBlendColor || mBlendColor != color )
314     {
315       LOG_GL( "BlendColor %f %f %f %f\n", color.r, color.g, color.b, color.a );
316       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendColor( color.r, color.g, color.b, color.a ) );
317       mUsingDefaultBlendColor = false;
318       mBlendColor = color;
319     }
320   }
321
322   /**
323    * Wrapper for OpenGL ES 2.0 glBlendEquation()
324    */
325   void BlendEquation(GLenum mode)
326   {
327     // use BlendEquationSeparate to set the rgb and alpha modes the same
328     BlendEquationSeparate( mode, mode );
329   }
330
331   /**
332    * Wrapper for OpenGL ES 2.0 glBlendEquationSeparate()
333    */
334   void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
335   {
336     if( ( modeRGB != mBlendEquationSeparateModeRGB ) ||
337         ( modeAlpha != mBlendEquationSeparateModeAlpha ) )
338     {
339       mBlendEquationSeparateModeRGB = modeRGB;
340       mBlendEquationSeparateModeAlpha = modeAlpha;
341       LOG_GL("BlendEquationSeparate %d %d\n", modeRGB, modeAlpha);
342       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendEquationSeparate(modeRGB, modeAlpha) );
343     }
344   }
345
346   /**
347    * Wrapper for OpenGL ES 2.0 glBlendFunc()
348    */
349   void BlendFunc(GLenum sfactor, GLenum dfactor)
350   {
351     // reuse the BlendFuncSeparate as thats what the DDK does anyways
352     BlendFuncSeparate( sfactor, dfactor, sfactor, dfactor );
353   }
354
355   /**
356    * Wrapper for OpenGL ES 2.0 glBlendFuncSeparate()
357    */
358   void BlendFuncSeparate( GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha )
359   {
360     if( ( mBlendFuncSeparateSrcRGB != srcRGB )||( mBlendFuncSeparateDstRGB != dstRGB )||
361         ( mBlendFuncSeparateSrcAlpha != srcAlpha )||( mBlendFuncSeparateDstAlpha != dstAlpha ) )
362     {
363       mBlendFuncSeparateSrcRGB = srcRGB;
364       mBlendFuncSeparateDstRGB = dstRGB;
365       mBlendFuncSeparateSrcAlpha = srcAlpha;
366       mBlendFuncSeparateDstAlpha = dstAlpha;
367
368       LOG_GL( "BlendFuncSeparate %d %d %d %d\n", srcRGB, dstRGB, srcAlpha, dstAlpha );
369       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendFuncSeparate( srcRGB, dstRGB, srcAlpha, dstAlpha ) );
370     }
371   }
372
373   /**
374    * Wrapper for OpenGL ES 3.0 glBlitFramebuffer()
375    */
376   void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
377   {
378     LOG_GL( "BlitFramebuffer %d %d %d %d %d %d %d %d %x %d\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter );
379     CHECK_GL( mGlAbstraction, mGlAbstraction.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter ) );
380   }
381
382   /**
383    * Wrapper for OpenGL ES 2.0 glBufferData()
384    */
385   void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage)
386   {
387     LOG_GL("BufferData %d %d %p %d\n", target, size, data, usage);
388     CHECK_GL( mGlAbstraction, mGlAbstraction.BufferData(target, size, data, usage) );
389   }
390
391   /**
392    * Wrapper for OpenGL ES 2.0 glBufferSubData()
393    */
394   void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data)
395   {
396     LOG_GL("BufferSubData %d %d %d %p\n", target, offset, size, data);
397     CHECK_GL( mGlAbstraction, mGlAbstraction.BufferSubData(target, offset, size, data) );
398   }
399
400   /**
401    * Wrapper for OpenGL ES 2.0  glCheckFramebufferStatus()
402    */
403   GLenum CheckFramebufferStatus(GLenum target)
404   {
405     LOG_GL("CheckFramebufferStatus %d\n", target);
406     GLenum value = CHECK_GL( mGlAbstraction, mGlAbstraction.CheckFramebufferStatus(target) );
407     return value;
408   }
409
410   /**
411    * Wrapper for OpenGL ES 2.0 glClear()
412    */
413   void Clear(GLbitfield mask, ClearMode mode )
414   {
415     bool forceClear = (mode == FORCE_CLEAR );
416     mask = mFrameBufferStateCache.GetClearMask( mask, forceClear , mScissorTestEnabled );
417
418     if( mask > 0 )
419     {
420       LOG_GL("Clear %d\n", mask);
421       CHECK_GL( mGlAbstraction, mGlAbstraction.Clear( mask ) );
422     }
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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( mGlAbstraction, 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( Dali::FaceCullingMode::Type mode )
549   {
550     // Avoid unnecessary calls to gl
551     if(mCullFaceMode != mode)
552     {
553       mCullFaceMode = mode;
554       switch(mode)
555       {
556         case Dali::FaceCullingMode::NONE:
557         {
558           LOG_GL("Disable GL_CULL_FACE\n");
559           CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_CULL_FACE) );
560           break;
561         }
562
563         case Dali::FaceCullingMode::FRONT:
564         {
565           LOG_GL("Enable GL_CULL_FACE\n");
566           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
567           LOG_GL("Enable GL_FRONT\n");
568           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_FRONT) );
569           break;
570         }
571
572         case Dali::FaceCullingMode::BACK:
573         {
574           LOG_GL("Enable GL_CULL_FACE\n");
575           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
576           LOG_GL("Enable GL_BACK\n");
577           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_BACK) );
578           break;
579         }
580
581         case Dali::FaceCullingMode::FRONT_AND_BACK:
582         {
583           LOG_GL("Enable GL_CULL_FACE\n");
584           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
585           LOG_GL("Enable GL_FRONT_AND_BACK\n");
586           CHECK_GL( mGlAbstraction, 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( mGlAbstraction, 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     mFrameBufferStateCache.FrameBuffersDeleted( n, framebuffers );
622
623     LOG_GL("DeleteFramebuffers %d %p\n", n, framebuffers);
624     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteFramebuffers(n, framebuffers) );
625   }
626
627   /**
628    * Wrapper for OpenGL ES 3.0 glDeleteQueries()
629    */
630   void DeleteQueries(GLsizei n, GLuint* ids)
631   {
632     LOG_GL("DeleteQueries %d %p\n", n, ids);
633     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteQueries(n, ids) );
634   }
635
636   /**
637    * Wrapper for OpenGL ES 2.0 glDeleteRenderbuffers()
638    */
639   void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
640   {
641     LOG_GL("DeleteRenderbuffers %d %p\n", n, renderbuffers);
642     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteRenderbuffers(n, renderbuffers) );
643   }
644
645   /**
646    * Wrapper for OpenGL ES 2.0 glDeleteTextures()
647    */
648   void DeleteTextures(GLsizei n, const GLuint* textures)
649   {
650     LOG_GL("DeleteTextures %d %p\n", n, textures);
651     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteTextures(n, textures) );
652
653     // reset the cached texture id's incase the driver re-uses them
654     // when creating new textures
655     for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
656     {
657        mBoundTextureId[ i ] = 0;
658     }
659   }
660
661   /**
662    * Wrapper for OpenGL ES 3.0 glDeleteTransformFeedbacks()
663    */
664   void DeleteTransformFeedbacks(GLsizei n, GLuint* ids)
665   {
666     LOG_GL("DeleteTransformFeedbacks %d %p\n", n, ids);
667     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteTransformFeedbacks(n, ids) );
668   }
669
670   /**
671    * Wrapper for OpenGL ES 2.0 glDepthFunc()
672    */
673   void DepthFunc(GLenum func)
674   {
675     if( func != mDepthFunction )
676     {
677       mDepthFunction = func;
678       LOG_GL("DepthFunc %x\n", func);
679       CHECK_GL( mGlAbstraction, mGlAbstraction.DepthFunc(func) );
680     }
681   }
682
683   /**
684    * Wrapper for OpenGL ES 2.0 glDepthMask()
685    */
686   void DepthMask(GLboolean flag)
687   {
688     bool booleanFlag = flag != GL_FALSE;
689     // only change state if needed
690     if( booleanFlag != mDepthMaskEnabled )
691     {
692       mDepthMaskEnabled = booleanFlag;
693       LOG_GL("DepthMask %s\n", booleanFlag ? "True" : "False");
694       CHECK_GL( mGlAbstraction, mGlAbstraction.DepthMask( mDepthMaskEnabled ) );
695     }
696   }
697
698   /**
699    * Wrapper for OpenGL ES 2.0 glDepthRangef()
700    */
701   void DepthRangef(GLclampf zNear, GLclampf zFar)
702   {
703     LOG_GL("DepthRangef %f %f\n", zNear, zFar);
704     CHECK_GL( mGlAbstraction, mGlAbstraction.DepthRangef(zNear, zFar) );
705   }
706
707   /**
708    * The wrapper for OpenGL ES 2.0 glDisable() has been replaced by SetBlend, SetCullFace, SetDepthTest,
709    * SetDither, SetPolygonOffsetFill, SetSampleAlphaToCoverage, SetSampleCoverage, SetScissorTest & SetStencilTest.
710    */
711
712   /**
713    * Wrapper for OpenGL ES 2.0 glDrawArrays()
714    */
715   void DrawArrays(GLenum mode, GLint first, GLsizei count)
716   {
717     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
718     FlushVertexAttributeLocations();
719
720     LOG_GL("DrawArrays %x %d %d\n", mode, first, count);
721     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawArrays(mode, first, count) );
722   }
723
724   /**
725    * Wrapper for OpenGL ES 3.0 glDrawArraysInstanced()
726    */
727   void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
728   {
729     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
730     FlushVertexAttributeLocations();
731
732     LOG_GL("DrawArraysInstanced %x %d %d %d\n", mode, first, count, instanceCount);
733     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawArraysInstanced(mode, first, count,instanceCount) );
734   }
735
736   /**
737    * Wrapper for OpenGL ES 3.0 glDrawBuffers()
738    */
739   void DrawBuffers(GLsizei n, const GLenum* bufs)
740   {
741     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
742     LOG_GL("DrawBuffers %d %p\n", n, bufs);
743     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawBuffers(n, bufs) );
744   }
745
746   /**
747    * Wrapper for OpenGL ES 2.0 glDrawElements()
748    */
749   void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
750   {
751     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
752
753     FlushVertexAttributeLocations();
754
755     LOG_GL("DrawElements %x %d %d %p\n", mode, count, type, indices);
756     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawElements(mode, count, type, indices) );
757   }
758
759   /**
760    * Wrapper for OpenGL ES 3.0 glDrawElementsInstanced()
761    */
762   void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instanceCount)
763   {
764     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
765
766     FlushVertexAttributeLocations();
767
768     LOG_GL("DrawElementsInstanced %x %d %d %p %d\n", mode, count, type, indices, instanceCount);
769     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawElementsInstanced(mode, count, type, indices, instanceCount) );
770   }
771
772   /**
773    * Wrapper for OpenGL ES 3.0 glDrawRangeElements()
774    */
775   void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
776   {
777     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
778     FlushVertexAttributeLocations();
779
780     LOG_GL("DrawRangeElements %x %u %u %d %d %p\n", mode, start, end, count, type, indices);
781     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawRangeElements(mode, start, end, count, type, indices) );
782   }
783
784   /**
785    * Wrapper for OpenGL ES 3.0 glGenQuerieS()
786    */
787   void GenQueries(GLsizei n, GLuint* ids)
788   {
789     LOG_GL("GenQueries %d %p\n", n, ids);
790     CHECK_GL( mGlAbstraction, mGlAbstraction.GenQueries(n, ids) );
791   }
792
793   /**
794    * Wrapper for OpenGL ES 3.0 glGenTransformFeedbacks()
795    */
796   void GenTransformFeedbacks(GLsizei n, GLuint* ids)
797   {
798     LOG_GL("GenTransformFeedbacks %d %p\n", n, ids);
799     CHECK_GL( mGlAbstraction, mGlAbstraction.GenTransformFeedbacks(n, ids) );
800   }
801
802   /**
803    * @return the current buffer bound for a given target
804    */
805   GLuint GetCurrentBoundArrayBuffer(GLenum target)
806   {
807     GLuint result(0);
808     switch(target)
809     {
810       case GL_ARRAY_BUFFER:
811       {
812         result = mBoundArrayBufferId;
813         break;
814       }
815       case GL_ELEMENT_ARRAY_BUFFER:
816       {
817         result = mBoundElementArrayBufferId;
818         break;
819       }
820       case GL_TRANSFORM_FEEDBACK_BUFFER:
821       {
822         result = mBoundTransformFeedbackBufferId;
823         break;
824       }
825       default:
826       {
827         DALI_ASSERT_DEBUG(0 && "target buffer type not supported");
828       }
829     }
830     return result;
831   }
832
833   void EnableVertexAttributeArray( GLuint location )
834   {
835     SetVertexAttributeLocation( location, true);
836   }
837
838   void DisableVertexAttributeArray( GLuint location )
839   {
840     SetVertexAttributeLocation( location, false);
841   }
842
843   /**
844    * Wrapper for OpenGL ES 3.0 glVertexAttribDivisor()
845    */
846   void VertexAttribDivisor ( GLuint index, GLuint divisor )
847   {
848     LOG_GL("VertexAttribDivisor(%d, %d)\n", index, divisor );
849     CHECK_GL( mGlAbstraction, mGlAbstraction.VertexAttribDivisor( index, divisor ) );
850   }
851
852   /**
853    * Wrapper for OpenGL ES 2.0 glVertexAttribPointer()
854    */
855   void VertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr )
856   {
857     LOG_GL("VertexAttribPointer(%d, %d, %d, %d, %d, %x)\n", index, size, type, normalized, stride, ptr );
858     CHECK_GL( mGlAbstraction, mGlAbstraction.VertexAttribPointer( index, size, type, normalized, stride, ptr ) );
859   }
860
861   /**
862    * Wrapper for OpenGL ES 3.0 glInvalidateFramebuffer()
863    */
864   void InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
865   {
866     LOG_GL("InvalidateFramebuffer\n");
867     CHECK_GL( mGlAbstraction, mGlAbstraction.InvalidateFramebuffer(target, numAttachments, attachments) );
868   }
869
870   /**
871    * The wrapper for OpenGL ES 2.0 glEnable() has been replaced by SetBlend, SetCullFace, SetDepthTest,
872    * SetDither, SetPolygonOffsetFill, SetSampleAlphaToCoverage, SetSampleCoverage, SetScissorTest & SetStencilTest.
873    */
874
875   /**
876    * This method replaces glEnable(GL_BLEND) and glDisable(GL_BLEND).
877    * @param[in] enable True if GL_BLEND should be enabled.
878    */
879   void SetBlend(bool enable)
880   {
881     // Avoid unecessary calls to glEnable/glDisable
882     if (enable != mBlendEnabled)
883     {
884       mBlendEnabled = enable;
885
886       if (enable)
887       {
888         LOG_GL("Enable GL_BLEND\n");
889         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_BLEND) );
890       }
891       else
892       {
893         LOG_GL("Disable GL_BLEND\n");
894         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_BLEND) );
895       }
896     }
897   }
898
899   /**
900    * This method replaces glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST).
901    * Note GL_DEPTH_TEST means enable the depth buffer for writing and or testing.
902    * glDepthMask is used to enable / disable writing to depth buffer.
903    * glDepthFunc us used to control if testing is enabled and how it is performed ( default GL_LESS)
904    *
905    * @param[in] enable True if GL_DEPTH_TEST should be enabled.
906    */
907   void EnableDepthBuffer( bool enable )
908   {
909     // Avoid unecessary calls to glEnable/glDisable
910     if( enable != mDepthBufferEnabled )
911     {
912       mDepthBufferEnabled = enable;
913
914       if (enable)
915       {
916         LOG_GL("Enable GL_DEPTH_TEST\n");
917         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_DEPTH_TEST) );
918       }
919       else
920       {
921         LOG_GL("Disable GL_DEPTH_TEST\n");
922         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_DEPTH_TEST) );
923       }
924     }
925   }
926
927   /**
928    * This method replaces glEnable(GL_DITHER) and glDisable(GL_DITHER).
929    * @param[in] enable True if GL_DITHER should be enabled.
930    */
931   void SetDither(bool enable)
932   {
933     // Avoid unecessary calls to glEnable/glDisable
934     if (enable != mDitherEnabled)
935     {
936       mDitherEnabled = enable;
937
938       if (enable)
939       {
940         LOG_GL("Enable GL_DITHER\n");
941         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_DITHER) );
942       }
943       else
944       {
945         LOG_GL("Disable GL_DITHER\n");
946         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_DITHER) );
947       }
948     }
949   }
950
951   /**
952    * This method replaces glEnable(GL_POLYGON_OFFSET_FILL) and glDisable(GL_POLYGON_OFFSET_FILL).
953    * @param[in] enable True if GL_POLYGON_OFFSET_FILL should be enabled.
954    */
955   void SetPolygonOffsetFill(bool enable)
956   {
957     // Avoid unecessary calls to glEnable/glDisable
958     if (enable != mPolygonOffsetFillEnabled)
959     {
960       mPolygonOffsetFillEnabled = enable;
961
962       if (enable)
963       {
964         LOG_GL("Enable GL_POLYGON_OFFSET_FILL\n");
965         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_POLYGON_OFFSET_FILL) );
966       }
967       else
968       {
969         LOG_GL("Disable GL_POLYGON_OFFSET_FILL\n");
970         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL) );
971       }
972     }
973   }
974
975   /**
976    * This method replaces glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) and glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE).
977    * @param[in] enable True if GL_SAMPLE_ALPHA_TO_COVERAGE should be enabled.
978    */
979   void SetSampleAlphaToCoverage(bool enable)
980   {
981     // Avoid unecessary calls to glEnable/glDisable
982     if (enable != mSampleAlphaToCoverageEnabled)
983     {
984       mSampleAlphaToCoverageEnabled = enable;
985
986       if (enable)
987       {
988         LOG_GL("Enable GL_SAMPLE_ALPHA_TO_COVERAGE\n");
989         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE) );
990       }
991       else
992       {
993         LOG_GL("Disable GL_SAMPLE_ALPHA_TO_COVERAGE\n");
994         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE) );
995       }
996     }
997   }
998
999   /**
1000    * This method replaces glEnable(GL_SAMPLE_COVERAGE) and glDisable(GL_SAMPLE_COVERAGE).
1001    * @param[in] enable True if GL_SAMPLE_COVERAGE should be enabled.
1002    */
1003   void SetSampleCoverage(bool enable)
1004   {
1005     // Avoid unecessary calls to glEnable/glDisable
1006     if (enable != mSampleCoverageEnabled)
1007     {
1008       mSampleCoverageEnabled = enable;
1009
1010       if (enable)
1011       {
1012         LOG_GL("Enable GL_SAMPLE_COVERAGE\n");
1013         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SAMPLE_COVERAGE) );
1014       }
1015       else
1016       {
1017         LOG_GL("Disable GL_SAMPLE_COVERAGE\n");
1018         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SAMPLE_COVERAGE) );
1019       }
1020     }
1021   }
1022
1023   /**
1024    * This method replaces glEnable(GL_SCISSOR_TEST) and glDisable(GL_SCISSOR_TEST).
1025    * @param[in] enable True if GL_SCISSOR_TEST should be enabled.
1026    */
1027   void SetScissorTest(bool enable)
1028   {
1029     // Avoid unecessary calls to glEnable/glDisable
1030     if (enable != mScissorTestEnabled)
1031     {
1032       mScissorTestEnabled = enable;
1033
1034       if (enable)
1035       {
1036         LOG_GL("Enable GL_SCISSOR_TEST\n");
1037         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SCISSOR_TEST) );
1038       }
1039       else
1040       {
1041         LOG_GL("Disable GL_SCISSOR_TEST\n");
1042         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SCISSOR_TEST) );
1043       }
1044     }
1045   }
1046
1047   /**
1048    * This method replaces glEnable(GL_STENCIL_TEST) and glDisable(GL_STENCIL_TEST).
1049    * Note GL_STENCIL_TEST means enable the stencil buffer for writing and or testing.
1050    * glStencilMask is used to control how bits are written to the stencil buffer.
1051    * glStencilFunc is used to control if testing is enabled and how it is performed ( default GL_ALWAYS )
1052    * @param[in] enable True if GL_STENCIL_TEST should be enabled.
1053    */
1054   void EnableStencilBuffer(bool enable)
1055   {
1056     // Avoid unecessary calls to glEnable/glDisable
1057     if( enable != mStencilBufferEnabled )
1058     {
1059       mStencilBufferEnabled = enable;
1060
1061       if (enable)
1062       {
1063         LOG_GL("Enable GL_STENCIL_TEST\n");
1064         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_STENCIL_TEST) );
1065       }
1066       else
1067       {
1068         LOG_GL("Disable GL_STENCIL_TEST\n");
1069         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_STENCIL_TEST) );
1070       }
1071     }
1072   }
1073
1074   /**
1075    * Wrapper for OpenGL ES 3.0 glEndQuery()
1076    */
1077   void EndQuery(GLenum target)
1078   {
1079     LOG_GL("EndQuery %d\n", target);
1080     CHECK_GL( mGlAbstraction, mGlAbstraction.EndQuery(target) );
1081   }
1082
1083   /**
1084    * Wrapper for OpenGL ES 3.0 glEndTransformFeedback()
1085    */
1086   void EndTransformFeedback()
1087   {
1088     LOG_GL("EndTransformFeedback\n");
1089     CHECK_GL( mGlAbstraction, mGlAbstraction.EndTransformFeedback() );
1090   }
1091
1092   /**
1093    * Wrapper for OpenGL ES 2.0 glFinish()
1094    */
1095   void Finish(void)
1096   {
1097     LOG_GL("Finish\n");
1098     CHECK_GL( mGlAbstraction, mGlAbstraction.Finish() );
1099   }
1100
1101   /**
1102    * Wrapper for OpenGL ES 2.0 glFlush()
1103    */
1104   void Flush(void)
1105   {
1106     LOG_GL("Flush\n");
1107     CHECK_GL( mGlAbstraction, mGlAbstraction.Flush() );
1108   }
1109
1110   /**
1111    * Wrapper for OpenGL ES 2.0 glFramebufferRenderbuffer()
1112    */
1113   void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1114   {
1115     LOG_GL("FramebufferRenderbuffer %x %x %x %d\n", target, attachment, renderbuffertarget, renderbuffer);
1116     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) );
1117   }
1118
1119   /**
1120    * Wrapper for OpenGL ES 2.0 glFramebufferTexture2D()
1121    */
1122   void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1123   {
1124     LOG_GL("FramebufferTexture2D %x %x %x %d %d\n", target, attachment, textarget, texture, level);
1125     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferTexture2D(target, attachment, textarget, texture, level) );
1126   }
1127
1128   /**
1129    * Wrapper for OpenGL ES 3.0 glFramebufferTextureLayer()
1130    */
1131   void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
1132   {
1133     LOG_GL("FramebufferTextureLayer %x %x %d %d %d\n", target, attachment, texture, level, layer);
1134     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferTextureLayer(target, attachment, texture, level, layer) );
1135   }
1136
1137   /**
1138    * Wrapper for OpenGL ES 2.0 glFrontFace()
1139    */
1140   void FrontFace(GLenum mode)
1141   {
1142     LOG_GL("FrontFace %x\n", mode);
1143     CHECK_GL( mGlAbstraction, mGlAbstraction.FrontFace(mode) );
1144   }
1145
1146   /**
1147    * Wrapper for OpenGL ES 2.0 glGenBuffers()
1148    */
1149   void GenBuffers(GLsizei n, GLuint* buffers)
1150   {
1151     LOG_GL("GenBuffers %d\n", n, buffers);
1152     CHECK_GL( mGlAbstraction, mGlAbstraction.GenBuffers(n, buffers) );
1153   }
1154
1155   /**
1156    * Wrapper for OpenGL ES 2.0 glGenerateMipmap()
1157    */
1158   void GenerateMipmap(GLenum target)
1159   {
1160     LOG_GL("GenerateMipmap %x\n", target);
1161     CHECK_GL( mGlAbstraction, mGlAbstraction.GenerateMipmap(target) );
1162   }
1163
1164   /**
1165    * Wrapper for OpenGL ES 2.0 glGenFramebuffers()
1166    */
1167   void GenFramebuffers(GLsizei n, GLuint* framebuffers)
1168   {
1169     LOG_GL("GenFramebuffers %d %p\n", n, framebuffers);
1170     CHECK_GL( mGlAbstraction, mGlAbstraction.GenFramebuffers(n, framebuffers) );
1171
1172     mFrameBufferStateCache.FrameBuffersCreated( n, framebuffers );
1173   }
1174
1175   /**
1176    * Wrapper for OpenGL ES 2.0 glGenRenderbuffers()
1177    */
1178   void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1179   {
1180     LOG_GL("GenRenderbuffers %d %p\n", n, renderbuffers);
1181     CHECK_GL( mGlAbstraction, mGlAbstraction.GenRenderbuffers(n, renderbuffers) );
1182   }
1183
1184   /**
1185    * Wrapper for OpenGL ES 2.0 glGenTextures()
1186    */
1187   void GenTextures(GLsizei n, GLuint* textures)
1188   {
1189     LOG_GL("GenTextures %d %p\n", n, textures);
1190     CHECK_GL( mGlAbstraction, mGlAbstraction.GenTextures(n, textures) );
1191   }
1192
1193   /**
1194    * Wrapper for OpenGL ES 2.0 glGetBooleanv()
1195    */
1196   void GetBooleanv(GLenum pname, GLboolean* params)
1197   {
1198     LOG_GL("GetBooleanv %x\n", pname);
1199     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBooleanv(pname, params) );
1200   }
1201
1202   /**
1203    * Wrapper for OpenGL ES 2.0 glGetBufferParameteriv()
1204    */
1205   void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1206   {
1207     LOG_GL("GetBufferParameteriv %x %x %p\n", target, pname, params);
1208     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBufferParameteriv(target, pname, params) );
1209   }
1210
1211   /**
1212    * Wrapper for OpenGL ES 3.0 glGetBufferPointer()
1213    */
1214   void GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
1215   {
1216     LOG_GL("GetBufferPointerv %x %x %p\n", target, pname, params);
1217     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBufferPointerv(target, pname, params) );
1218   }
1219
1220   /**
1221    * Wrapper for OpenGL ES 2.0 glGetError()
1222    */
1223   GLenum GetError(void)
1224   {
1225     // Not worth logging here
1226     return mGlAbstraction.GetError();
1227   }
1228
1229   /**
1230    * Wrapper for OpenGL ES 2.0 glGetFloatv()
1231    */
1232   void GetFloatv(GLenum pname, GLfloat* params)
1233   {
1234     LOG_GL("GetFloatv %x\n", pname);
1235     CHECK_GL( mGlAbstraction, mGlAbstraction.GetFloatv(pname, params) );
1236   }
1237
1238   /**
1239    * Wrapper for OpenGL ES 2.0 glGetFramebufferAttachmentParameteriv()
1240    */
1241   void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1242   {
1243     LOG_GL("GetFramebufferAttachmentParameteriv %x %x %x\n", target, attachment, pname);
1244     CHECK_GL( mGlAbstraction, mGlAbstraction.GetFramebufferAttachmentParameteriv(target, attachment, pname, params) );
1245   }
1246
1247   /**
1248    * Wrapper for OpenGL ES 2.0 glGetIntegerv()
1249    */
1250   void GetIntegerv(GLenum pname, GLint* params)
1251   {
1252     LOG_GL("GetIntegerv %x\n", pname);
1253     CHECK_GL( mGlAbstraction, mGlAbstraction.GetIntegerv(pname, params) );
1254   }
1255
1256   /**
1257    * Wrapper for OpenGL ES 3.0 glGetQueryiv()
1258    */
1259   void GetQueryiv(GLenum target, GLenum pname, GLint* params)
1260   {
1261     LOG_GL("GetQueryiv %x %x\n", target, pname);
1262     CHECK_GL( mGlAbstraction, mGlAbstraction.GetQueryiv(target, pname, params) );
1263   }
1264
1265   /**
1266    * Wrapper for OpenGL ES 3.0 glGetQueryObjectuiv()
1267    */
1268   void GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
1269   {
1270     LOG_GL("GetQueryObjectuiv %u %x %p\n", id, pname, params);
1271     CHECK_GL( mGlAbstraction, mGlAbstraction.GetQueryObjectuiv(id, pname, params) );
1272   }
1273
1274   /**
1275    * Wrapper for OpenGL ES 2.0 glGetRenderbufferParameteriv()
1276    */
1277   void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
1278   {
1279     LOG_GL("GetRenderbufferParameteriv %x %x\n", target, pname);
1280     CHECK_GL( mGlAbstraction, mGlAbstraction.GetRenderbufferParameteriv(target, pname, params) );
1281   }
1282
1283   /**
1284    * Wrapper for OpenGL ES 2.0 glGetString()
1285    */
1286   const GLubyte* GetString(GLenum name)
1287   {
1288     LOG_GL("GetString %x\n", name);
1289     const GLubyte* str = CHECK_GL( mGlAbstraction, mGlAbstraction.GetString(name) );
1290     return str;
1291   }
1292
1293   /**
1294    * Wrapper for OpenGL ES 2.0 glGetTexParameterfv()
1295    */
1296   void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
1297   {
1298     LOG_GL("GetTexParameterfv %x %x\n", target, pname);
1299     CHECK_GL( mGlAbstraction, mGlAbstraction.GetTexParameterfv(target, pname, params) );
1300   }
1301
1302   /**
1303    * Wrapper for OpenGL ES 2.0 glGetTexParameteriv()
1304    */
1305   void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
1306   {
1307     LOG_GL("GetTexParameteriv %x %x\n", target, pname);
1308     CHECK_GL( mGlAbstraction, mGlAbstraction.GetTexParameteriv(target, pname, params) );
1309   }
1310
1311   /**
1312    * Wrapper for OpenGL ES 2.0 glHint()
1313    */
1314   void Hint(GLenum target, GLenum mode)
1315   {
1316     LOG_GL("Hint %x %x\n", target, mode);
1317     CHECK_GL( mGlAbstraction, mGlAbstraction.Hint(target, mode) );
1318   }
1319
1320   /**
1321    * Wrapper for OpenGL ES 2.0 glIsBuffer()
1322    */
1323   GLboolean IsBuffer(GLuint buffer)
1324   {
1325     LOG_GL("IsBuffer %d\n", buffer);
1326     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsBuffer(buffer) );
1327     return val;
1328   }
1329
1330   /**
1331    * Wrapper for OpenGL ES 2.0 glIsEnabled()
1332    */
1333   GLboolean IsEnabled(GLenum cap)
1334   {
1335     LOG_GL("IsEnabled %x\n", cap);
1336     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsEnabled(cap) );
1337     return val;
1338   }
1339
1340   /**
1341    * Wrapper for OpenGL ES 2.0 glIsFramebuffer()
1342    */
1343   GLboolean IsFramebuffer(GLuint framebuffer)
1344   {
1345     LOG_GL("IsFramebuffer %d\n", framebuffer);
1346     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsFramebuffer(framebuffer) );
1347     return val;
1348   }
1349
1350   /**
1351    * Wrapper for OpenGL ES 3.0 glIsQuery()
1352    */
1353   GLboolean IsQuery(GLuint id)
1354   {
1355     LOG_GL("IsQuery %u\n", id);
1356     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsQuery(id) );
1357     return val;
1358   }
1359
1360   /**
1361    * Wrapper for OpenGL ES 2.0 glIsRenderbuffer()
1362    */
1363   GLboolean IsRenderbuffer(GLuint renderbuffer)
1364   {
1365     LOG_GL("IsRenderbuffer %d\n", renderbuffer);
1366     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsRenderbuffer(renderbuffer) );
1367     return val;
1368   }
1369
1370   /**
1371    * Wrapper for OpenGL ES 2.0 glIsTexture()
1372    */
1373   GLboolean IsTexture(GLuint texture)
1374   {
1375     LOG_GL("IsTexture %d\n", texture);
1376     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsTexture(texture) );
1377     return val;
1378   }
1379
1380   /**
1381    * Wrapper for OpenGL ES 3.0 glIsTransformFeedback()
1382    */
1383   GLboolean IsTransformFeedback(GLuint id)
1384   {
1385     LOG_GL("IsTransformFeedback %u\n", id);
1386     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsTransformFeedback(id) );
1387     return val;
1388   }
1389
1390   /**
1391    * Wrapper for OpenGL ES 2.0 glLineWidth()
1392    */
1393   void LineWidth(GLfloat width)
1394   {
1395     LOG_GL("LineWidth %f\n", width);
1396     CHECK_GL( mGlAbstraction, mGlAbstraction.LineWidth(width) );
1397   }
1398
1399   /**
1400    * Wrapper for OpenGL ES 3.0 glPauseTransformFeedback()
1401    */
1402   void PauseTransformFeedback()
1403   {
1404     LOG_GL("PauseTransformFeedback\n");
1405     CHECK_GL( mGlAbstraction, mGlAbstraction.PauseTransformFeedback() );
1406   }
1407
1408   /**
1409    * Wrapper for OpenGL ES 2.0 glPixelStorei()
1410    */
1411   void PixelStorei(GLenum pname, GLint param)
1412   {
1413     LOG_GL("PixelStorei %x %d\n", pname, param);
1414     CHECK_GL( mGlAbstraction, mGlAbstraction.PixelStorei(pname, param) );
1415   }
1416
1417   /**
1418    * Wrapper for OpenGL ES 2.0 glPolygonOffset()
1419    */
1420   void PolygonOffset(GLfloat factor, GLfloat units)
1421   {
1422     LOG_GL("PolygonOffset %f %f\n", factor, units);
1423     CHECK_GL( mGlAbstraction, mGlAbstraction.PolygonOffset(factor, units) );
1424   }
1425
1426   /**
1427    * Wrapper for OpenGL ES 2.0 glReadPixels()
1428    */
1429   void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
1430   {
1431     LOG_GL("ReadPixels %d %d %d %d %x %x\n", x, y, width, height, format, type);
1432     CHECK_GL( mGlAbstraction, mGlAbstraction.ReadPixels(x, y, width, height, format, type, pixels) );
1433   }
1434
1435   /**
1436    * Wrapper for OpenGL ES 2.0 glRenderbufferStorage()
1437    */
1438   void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
1439   {
1440     LOG_GL("RenderbufferStorage %x %x %d %d\n", target, internalformat, width, height);
1441     CHECK_GL( mGlAbstraction, mGlAbstraction.RenderbufferStorage(target, internalformat, width, height) );
1442   }
1443
1444   /**
1445    * Wrapper for OpenGL ES 3.0 glRenderbufferStorageMultisample()
1446    */
1447   void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
1448   {
1449     LOG_GL("RenderbufferStorageMultisample %x %u %x %d %d\n", target, samples, internalformat, width, height);
1450     CHECK_GL( mGlAbstraction, mGlAbstraction.RenderbufferStorageMultisample(target, samples, internalformat, width, height) );
1451   }
1452
1453   /**
1454    * Wrapper for OpenGL ES 3.0 glResumeTransformFeedback()
1455    */
1456   void ResumeTransformFeedback()
1457   {
1458     LOG_GL("ResumeTransformFeedback\n");
1459     CHECK_GL( mGlAbstraction, mGlAbstraction.ResumeTransformFeedback() );
1460   }
1461
1462   /**
1463    * Wrapper for OpenGL ES 2.0 glSampleCoverage()
1464    */
1465   void SampleCoverage(GLclampf value, GLboolean invert)
1466   {
1467     LOG_GL("SampleCoverage %f %s\n", value, invert ? "True" : "False");
1468     CHECK_GL( mGlAbstraction, mGlAbstraction.SampleCoverage(value, invert) );
1469   }
1470
1471   /**
1472    * Wrapper for OpenGL ES 2.0 glScissor()
1473    */
1474   void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1475   {
1476     LOG_GL("Scissor %d %d %d %d\n", x, y, width, height);
1477     CHECK_GL( mGlAbstraction, mGlAbstraction.Scissor(x, y, width, height) );
1478   }
1479
1480   /**
1481    * Wrapper for OpenGL ES 2.0 glStencilFunc()
1482    */
1483   void StencilFunc(GLenum func, GLint ref, GLuint mask)
1484   {
1485     if( ( func != mStencilFunc ) || ( ref != mStencilFuncRef ) || ( mask != mStencilFuncMask ) )
1486     {
1487       mStencilFunc = func;
1488       mStencilFuncRef = ref;
1489       mStencilFuncMask = mask;
1490
1491       LOG_GL("StencilFunc %x %d %d\n", func, ref, mask);
1492       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFunc(func, ref, mask) );
1493     }
1494   }
1495
1496   /**
1497    * Wrapper for OpenGL ES 2.0 glStencilFuncSeparate()
1498    */
1499   void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
1500   {
1501     LOG_GL("StencilFuncSeparate %x %x %d %d\n", face, func, ref, mask);
1502     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFuncSeparate(face, func, ref, mask) );
1503   }
1504
1505   /**
1506    * Wrapper for OpenGL ES 2.0 glStencilMask()
1507    */
1508   void StencilMask(GLuint mask)
1509   {
1510     if( mask != mStencilMask )
1511     {
1512       mStencilMask = mask;
1513
1514       LOG_GL("StencilMask %d\n", mask);
1515       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilMask(mask) );
1516     }
1517   }
1518
1519   /**
1520    * Wrapper for OpenGL ES 2.0 glStencilMaskSeparate()
1521    */
1522   void StencilMaskSeparate(GLenum face, GLuint mask)
1523   {
1524     LOG_GL("StencilMaskSeparate %x %d\n", face, mask);
1525     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilMaskSeparate(face, mask) );
1526   }
1527
1528   /**
1529    * Wrapper for OpenGL ES 2.0 glStencilOp()
1530    */
1531   void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
1532   {
1533     if( ( fail != mStencilOpFail ) || ( zfail != mStencilOpDepthFail ) || ( zpass != mStencilOpDepthPass ) )
1534     {
1535       mStencilOpFail = fail;
1536       mStencilOpDepthFail = zfail;
1537       mStencilOpDepthPass = zpass;
1538
1539       LOG_GL("StencilOp %x %x %x\n", fail, zfail, zpass);
1540       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilOp(fail, zfail, zpass) );
1541     }
1542   }
1543
1544   /**
1545    * Wrapper for OpenGL ES 2.0 glStencilOpSeparate()
1546    */
1547   void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
1548   {
1549     LOG_GL("StencilOpSeparate %x %x %x %x\n", face, fail, zfail, zpass);
1550     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilOpSeparate(face, fail, zfail, zpass) );
1551   }
1552
1553   /**
1554    * Wrapper for OpenGL ES 2.0 glTexImage2D()
1555    */
1556   void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
1557                   GLint border, GLenum format, GLenum type, const void* pixels)
1558   {
1559     LOG_GL("TexImage2D %x %d %d %dx%d %d %x %x %p\n", target, level, internalformat, width, height, border, format, type, pixels);
1560     CHECK_GL( mGlAbstraction, mGlAbstraction.TexImage2D(target, level, internalformat, width, height, border, format, type, pixels) );
1561   }
1562
1563   /**
1564    * Wrapper for OpenGL ES 3.0 glTexImage3D()
1565    */
1566   void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth,
1567                   GLint border, GLenum format, GLenum type, const void* pixels)
1568   {
1569     LOG_GL("TexImage3D %x %d %d %dx%dx%d %d %x %x %p\n", target, level, internalformat, width, height, depth, border, format, type, pixels);
1570     CHECK_GL( mGlAbstraction, mGlAbstraction.TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) );
1571   }
1572
1573   /**
1574    * Wrapper for OpenGL ES 2.0 glTexParameterf()
1575    */
1576   void TexParameterf(GLenum target, GLenum pname, GLfloat param)
1577   {
1578     LOG_GL("TexParameterf %x %x %f\n", target, pname, param);
1579     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameterf(target, pname, param) );
1580   }
1581
1582   /**
1583    * Wrapper for OpenGL ES 2.0 glTexParameterfv()
1584    */
1585   void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
1586   {
1587     LOG_GL("TexParameterfv %x %x\n", target, pname);
1588     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameterfv(target, pname, params) );
1589   }
1590
1591   /**
1592    * Wrapper for OpenGL ES 2.0 glTexParameteri()
1593    */
1594   void TexParameteri(GLenum target, GLenum pname, GLint param)
1595   {
1596     LOG_GL("TexParameteri %x %x %d\n", target, pname, param);
1597     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameteri(target, pname, param) );
1598   }
1599
1600   /**
1601    * Wrapper for OpenGL ES 2.0 glTexParameteriv()
1602    */
1603   void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
1604   {
1605     LOG_GL("TexParameteriv %x %x\n", target, pname);
1606     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameteriv(target, pname, params) );
1607   }
1608
1609   /**
1610    * Wrapper for OpenGL ES 2.0 glTexSubImage2D()
1611    */
1612   void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1613                      GLenum format, GLenum type, const void* pixels)
1614   {
1615     LOG_GL("TexSubImage2D %x %d %d %d %d %d %x %x %p\n", target, level, xoffset, yoffset, width, height, format, type, pixels);
1616     CHECK_GL( mGlAbstraction, mGlAbstraction.TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) );
1617   }
1618
1619   /**
1620    * Wrapper for OpenGL ES 3.0 glTexSubImage3D()
1621    */
1622   void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
1623                      GLsizei width, GLsizei height, GLsizei depth,
1624                      GLenum format, GLenum type, const void* pixels)
1625   {
1626     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);
1627     CHECK_GL( mGlAbstraction, mGlAbstraction.TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) );
1628   }
1629
1630   /**
1631    * Wrapper for OpenGL ES 3.0 glUnmapBubffer()
1632    */
1633   GLboolean UnmapBuffer(GLenum target)
1634   {
1635     LOG_GL("UnmapBuffer %x \n", target);
1636     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.UnmapBuffer(target) );
1637     return val;
1638   }
1639   /**
1640    * Wrapper for OpenGL ES 2.0 glViewport()
1641    */
1642   void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1643   {
1644     // check if its same as already set
1645     Rect<int> newViewport( x, y, width, height );
1646     if( mViewPort != newViewport )
1647     {
1648       // set new one
1649       LOG_GL("Viewport %d %d %d %d\n", x, y, width, height);
1650       CHECK_GL( mGlAbstraction, mGlAbstraction.Viewport(x, y, width, height) );
1651       mViewPort = newViewport; // remember new one
1652     }
1653   }
1654
1655   /**
1656    * Get the implementation defined MAX_TEXTURE_SIZE. This values is cached when the context is created
1657    * @return The implementation defined MAX_TEXTURE_SIZE
1658    */
1659   GLint CachedMaxTextureSize() const
1660   {
1661     return mMaxTextureSize;
1662   }
1663
1664   /**
1665    * Get the current viewport.
1666    * @return Viewport rectangle.
1667    */
1668   const Rect< int >& GetViewport();
1669
1670 private: // Implementation
1671
1672   /**
1673    * @return true if next draw operation will write to depth buffer
1674    */
1675   bool DepthBufferWriteEnabled() const
1676   {
1677     return mDepthBufferEnabled && mDepthMaskEnabled;
1678   }
1679
1680   /**
1681    * @return true if next draw operation will write to stencil buffer
1682    */
1683   bool StencilBufferWriteEnabled() const
1684   {
1685     return mStencilBufferEnabled && ( mStencilMask > 0 );
1686   }
1687
1688   /**
1689    * Flushes vertex attribute location changes to the driver
1690    */
1691   void FlushVertexAttributeLocations();
1692
1693   /**
1694    * Either enables or disables a vertex attribute location in the cache
1695    * The cahnges won't take affect until FlushVertexAttributeLocations is called
1696    * @param location attribute location
1697    * @param state attribute state
1698    */
1699   void SetVertexAttributeLocation(unsigned int location, bool state);
1700
1701   /**
1702    * Sets the initial GL state.
1703    */
1704   void InitializeGlState();
1705
1706 private: // Data
1707
1708   Integration::GlAbstraction& mGlAbstraction;
1709
1710   bool mGlContextCreated; ///< True if the OpenGL context has been created
1711
1712   // glEnable/glDisable states
1713   bool mColorMask;
1714   GLuint mStencilMask;
1715   bool mBlendEnabled;
1716   bool mDepthBufferEnabled;
1717   bool mDepthMaskEnabled;
1718   bool mDitherEnabled;
1719   bool mPolygonOffsetFillEnabled;
1720   bool mSampleAlphaToCoverageEnabled;
1721   bool mSampleCoverageEnabled;
1722   bool mScissorTestEnabled;
1723   bool mStencilBufferEnabled;
1724   bool mClearColorSet;
1725   bool mUsingDefaultBlendColor;
1726
1727   // glBindBuffer() state
1728   GLuint mBoundArrayBufferId;        ///< The ID passed to glBindBuffer(GL_ARRAY_BUFFER)
1729   GLuint mBoundElementArrayBufferId; ///< The ID passed to glBindBuffer(GL_ELEMENT_ARRAY_BUFFER)
1730   GLuint mBoundTransformFeedbackBufferId; ///< The ID passed to glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER)
1731
1732   // glBindTexture() state
1733   TextureUnit mActiveTextureUnit;
1734   GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ];  ///< The ID passed to glBindTexture()
1735
1736   // glBlendColor() state
1737   Vector4 mBlendColor; ///< Blend color
1738
1739   // glBlendFuncSeparate() state
1740   GLenum mBlendFuncSeparateSrcRGB;   ///< The srcRGB parameter passed to glBlendFuncSeparate()
1741   GLenum mBlendFuncSeparateDstRGB;   ///< The dstRGB parameter passed to glBlendFuncSeparate()
1742   GLenum mBlendFuncSeparateSrcAlpha; ///< The srcAlpha parameter passed to glBlendFuncSeparate()
1743   GLenum mBlendFuncSeparateDstAlpha; ///< The dstAlpha parameter passed to glBlendFuncSeparate()
1744
1745   // glBlendEquationSeparate state
1746   GLenum mBlendEquationSeparateModeRGB;    ///< Controls RGB blend mode
1747   GLenum mBlendEquationSeparateModeAlpha;  ///< Controls Alpha blend mode
1748
1749   // glStencilFunc() and glStencilOp() state.
1750   GLenum mStencilFunc;
1751   GLint mStencilFuncRef;
1752   GLuint mStencilFuncMask;
1753   GLenum mStencilOpFail;
1754   GLenum mStencilOpDepthFail;
1755   GLenum mStencilOpDepthPass;
1756
1757   GLenum mDepthFunction;  ///The depth function
1758
1759   GLint mMaxTextureSize;      ///< return value from GetIntegerv(GL_MAX_TEXTURE_SIZE)
1760   Vector4 mClearColor;        ///< clear color
1761
1762   // Face culling mode
1763   Dali::FaceCullingMode::Type mCullFaceMode;
1764
1765   // cached viewport size
1766   Rect< int > mViewPort;
1767
1768   // Vertex Attribute Buffer enable caching
1769   bool mVertexAttributeCachedState[ MAX_ATTRIBUTE_CACHE_SIZE ];    ///< Value cache for Enable Vertex Attribute
1770   bool mVertexAttributeCurrentState[ MAX_ATTRIBUTE_CACHE_SIZE ];   ///< Current state on the driver for Enable Vertex Attribute
1771
1772   FrameBufferStateCache mFrameBufferStateCache;   ///< frame buffer state cache
1773 };
1774
1775 } // namespace Internal
1776
1777 } // namespace Dali
1778
1779 #endif // __DALI_INTERNAL_CONTEXT_H__