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