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