Support screen and client rotation
[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     // DO NOT USE BlendEquationSeparate to set the same rgb and alpha modes
412     // KHR blending extensions require use of glBlendEquation
413
414     if( mBlendEquationSeparateModeRGB != mode || mBlendEquationSeparateModeAlpha != mode )
415     {
416       mBlendEquationSeparateModeRGB = mode;
417       mBlendEquationSeparateModeAlpha = mode;
418       LOG_GL("BlendEquation %d\n", mode);
419       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendEquation( mode ) );
420     }
421   }
422
423   /**
424    * Wrapper for OpenGL ES 2.0 glBlendEquationSeparate()
425    */
426   void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
427   {
428     if( ( modeRGB != mBlendEquationSeparateModeRGB ) ||
429         ( modeAlpha != mBlendEquationSeparateModeAlpha ) )
430     {
431       mBlendEquationSeparateModeRGB = modeRGB;
432       mBlendEquationSeparateModeAlpha = modeAlpha;
433       LOG_GL("BlendEquationSeparate %d %d\n", modeRGB, modeAlpha);
434       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendEquationSeparate(modeRGB, modeAlpha) );
435     }
436   }
437
438   /**
439    * Wrapper for OpenGL ES 2.0 glBlendFunc()
440    */
441   void BlendFunc(GLenum sfactor, GLenum dfactor)
442   {
443     // reuse the BlendFuncSeparate as thats what the DDK does anyways
444     BlendFuncSeparate( sfactor, dfactor, sfactor, dfactor );
445   }
446
447   /**
448    * Wrapper for OpenGL ES 2.0 glBlendFuncSeparate()
449    */
450   void BlendFuncSeparate( GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha )
451   {
452     if( ( mBlendFuncSeparateSrcRGB != srcRGB )||( mBlendFuncSeparateDstRGB != dstRGB )||
453         ( mBlendFuncSeparateSrcAlpha != srcAlpha )||( mBlendFuncSeparateDstAlpha != dstAlpha ) )
454     {
455       mBlendFuncSeparateSrcRGB = srcRGB;
456       mBlendFuncSeparateDstRGB = dstRGB;
457       mBlendFuncSeparateSrcAlpha = srcAlpha;
458       mBlendFuncSeparateDstAlpha = dstAlpha;
459
460       LOG_GL( "BlendFuncSeparate %d %d %d %d\n", srcRGB, dstRGB, srcAlpha, dstAlpha );
461       CHECK_GL( mGlAbstraction, mGlAbstraction.BlendFuncSeparate( srcRGB, dstRGB, srcAlpha, dstAlpha ) );
462     }
463   }
464
465   /**
466    * Wrapper for OpenGL ES 3.0 glBlitFramebuffer()
467    */
468   void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
469   {
470     LOG_GL( "BlitFramebuffer %d %d %d %d %d %d %d %d %x %d\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter );
471     CHECK_GL( mGlAbstraction, mGlAbstraction.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter ) );
472   }
473
474   /**
475    * Wrapper for OpenGL ES 2.0 glBufferData()
476    */
477   void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage)
478   {
479     LOG_GL("BufferData %d %d %p %d\n", target, size, data, usage);
480     CHECK_GL( mGlAbstraction, mGlAbstraction.BufferData(target, size, data, usage) );
481   }
482
483   /**
484    * Wrapper for OpenGL ES 2.0 glBufferSubData()
485    */
486   void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data)
487   {
488     LOG_GL("BufferSubData %d %d %d %p\n", target, offset, size, data);
489     CHECK_GL( mGlAbstraction, mGlAbstraction.BufferSubData(target, offset, size, data) );
490   }
491
492   /**
493    * Wrapper for OpenGL ES 2.0  glCheckFramebufferStatus()
494    */
495   GLenum CheckFramebufferStatus(GLenum target)
496   {
497     LOG_GL("CheckFramebufferStatus %d\n", target);
498     GLenum value = CHECK_GL( mGlAbstraction, mGlAbstraction.CheckFramebufferStatus(target) );
499     return value;
500   }
501
502   /**
503    * Wrapper for OpenGL ES 2.0 glClear()
504    */
505   void Clear(GLbitfield mask, ClearMode mode )
506   {
507     bool forceClear = (mode == FORCE_CLEAR );
508     mask = mFrameBufferStateCache.GetClearMask( mask, forceClear , mScissorTestEnabled );
509
510     if( mask > 0 )
511     {
512       LOG_GL("Clear %d\n", mask);
513       CHECK_GL( mGlAbstraction, mGlAbstraction.Clear( mask ) );
514     }
515   }
516
517   /**
518    * Wrapper for OpenGL ES 2.0 glClearColor()
519    */
520   void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
521   {
522     Vector4 newCol(red,green,blue,alpha);
523
524     if (!mClearColorSet || mClearColor !=newCol )
525     {
526       LOG_GL("ClearColor %f %f %f %f\n", red, green, blue, alpha);
527       CHECK_GL( mGlAbstraction, mGlAbstraction.ClearColor(red, green, blue, alpha) );
528
529       mClearColorSet = true;
530       mClearColor = newCol;
531     }
532   }
533
534   /**
535    * Wrapper for OpenGL ES 2.0 glClearDepthf()
536    */
537   void ClearDepthf(GLclampf depth)
538   {
539     LOG_GL("ClearDepthf %f\n", depth);
540     CHECK_GL( mGlAbstraction, mGlAbstraction.ClearDepthf(depth) );
541   }
542
543   /**
544    * Wrapper for OpenGL ES 2.0 glClearStencil()
545    */
546   void ClearStencil(GLint s)
547   {
548     LOG_GL("ClearStencil %d\n", s);
549     CHECK_GL( mGlAbstraction, mGlAbstraction.ClearStencil(s) );
550   }
551
552   /**
553    * Wrapper for OpenGL ES 2.0 glColorMask()
554    * @note This has been optimized to a single boolean value (masking individual channels is not required)
555    */
556   void ColorMask( bool flag )
557   {
558     // only change state if needed
559     if( flag != mColorMask )
560     {
561       mColorMask = flag;
562       LOG_GL("ColorMask %s %s %s %s\n", flag ? "True" : "False", flag ? "True" : "False", flag ? "True" : "False", flag ? "True" : "False");
563       CHECK_GL( mGlAbstraction, mGlAbstraction.ColorMask(flag, flag, flag, flag) );
564     }
565   }
566
567   /**
568    * Wrapper for OpenGL ES 2.0 glCompressedTexImage2D()
569    */
570   void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
571                             GLint border, GLsizei imageSize, const void* data)
572   {
573     LOG_GL("CompressedTexImage2D %d %d %x %d %d %d %d %p\n", target, level, internalformat, width, height, border, imageSize, data);
574     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data) );
575   }
576
577   /**
578    * Wrapper for OpenGL ES 3.0 glCompressedTexImage3D()
579    */
580   void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
581                             GLint border, GLsizei imageSize, const void* data)
582   {
583     LOG_GL("CompressedTexImage3D %d %d %x %d %d %d %d %d %p\n", target, level, internalformat, width, height, depth, border, imageSize, data);
584     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data) );
585   }
586
587   /**
588    * Wrapper for OpenGL ES 2.0 glCompressedTexSubImage2D()
589    */
590   void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
591                                GLenum format, GLsizei imageSize, const void* data)
592   {
593     LOG_GL("CompressedTexSubImage2D %x %d %d %d %d %d %x %d %p\n", target, level, xoffset, yoffset, width, height, format, imageSize, data);
594     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) );
595   }
596
597   /**
598    * Wrapper for OpenGL ES 3.0 glCompressedTexSubImage3D()
599    */
600   void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
601                                GLsizei width, GLsizei height, GLsizei depth,
602                                GLenum format, GLsizei imageSize, const void* data)
603   {
604     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);
605     CHECK_GL( mGlAbstraction, mGlAbstraction.CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data) );
606   }
607
608   /**
609    * Wrapper for OpenGL ES 2.0 glCopyTexImage2D()
610    */
611   void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
612   {
613     LOG_GL("CopyTexImage2D %x %d %x %d %d %d %d %d\n", target, level, internalformat, x, y, width, height, border);
614     CHECK_GL( mGlAbstraction, mGlAbstraction.CopyTexImage2D(target, level, internalformat, x, y, width, height, border) );
615   }
616
617   /**
618    * Wrapper for OpenGL ES 2.0 glCopyTexSubImage2D()
619    */
620   void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
621   {
622     LOG_GL("CopyTexSubImage2D %x %d %d %d %d %d %d %d\n", target, level, xoffset, yoffset, x, y, width, height);
623     CHECK_GL( mGlAbstraction, mGlAbstraction.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) );
624   }
625
626   /**
627    * Wrapper for OpenGL ES 3.0 glCopyTexSubImage3D()
628    */
629   void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
630   {
631     LOG_GL("CopyTexSubImage3D %x %d %d %d %d %d %d %d %d\n", target, level, xoffset, yoffset, zoffset, x, y, width, height);
632     CHECK_GL( mGlAbstraction, mGlAbstraction.CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height) );
633   }
634
635   /**
636    * Wrapper for OpenGL ES 2.0 glCullFace()
637    * enables GL_CULL_FACE if in any of the face culling modes
638    * otherwise disables GL_CULL_FACE
639    */
640   void CullFace( Dali::FaceCullingMode::Type mode )
641   {
642     // Avoid unnecessary calls to gl
643     if(mCullFaceMode != mode)
644     {
645       mCullFaceMode = mode;
646       switch(mode)
647       {
648         case Dali::FaceCullingMode::NONE:
649         {
650           LOG_GL("Disable GL_CULL_FACE\n");
651           CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_CULL_FACE) );
652           break;
653         }
654
655         case Dali::FaceCullingMode::FRONT:
656         {
657           LOG_GL("Enable GL_CULL_FACE\n");
658           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
659           LOG_GL("Enable GL_FRONT\n");
660           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_FRONT) );
661           break;
662         }
663
664         case Dali::FaceCullingMode::BACK:
665         {
666           LOG_GL("Enable GL_CULL_FACE\n");
667           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
668           LOG_GL("Enable GL_BACK\n");
669           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_BACK) );
670           break;
671         }
672
673         case Dali::FaceCullingMode::FRONT_AND_BACK:
674         {
675           LOG_GL("Enable GL_CULL_FACE\n");
676           CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
677           LOG_GL("Enable GL_FRONT_AND_BACK\n");
678           CHECK_GL( mGlAbstraction, mGlAbstraction.CullFace(GL_FRONT_AND_BACK) );
679           break;
680         }
681
682         default:
683           break;
684       }
685     }
686   }
687
688   /**
689    * Wrapper for OpenGL ES 2.0 glDeleteBuffers()
690    */
691   void DeleteBuffers(GLsizei n, const GLuint* buffers)
692   {
693     if( this->IsGlContextCreated() )
694     {
695       LOG_GL("DeleteBuffers %d %p\n", n, buffers);
696       CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteBuffers(n, buffers) );
697     }
698
699     ResetBufferCache();
700
701     // Need to reset the buffer cache in the surface contexts
702     // This will only be executed by the surfaceless context when there are contexts for surface rendering
703     if ( mSceneContexts )
704     {
705       for ( auto&& context : *mSceneContexts )
706       {
707         if ( context )
708         {
709           context->ResetBufferCache();
710         }
711       }
712     }
713   }
714
715   /**
716    * Wrapper for OpenGL ES 2.0 glDeleteFramebuffers()
717    */
718   void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
719   {
720     mFrameBufferStateCache.FrameBuffersDeleted( n, framebuffers );
721
722     LOG_GL("DeleteFramebuffers %d %p\n", n, framebuffers);
723     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteFramebuffers(n, framebuffers) );
724   }
725
726   /**
727    * Wrapper for OpenGL ES 3.0 glDeleteQueries()
728    */
729   void DeleteQueries(GLsizei n, GLuint* ids)
730   {
731     LOG_GL("DeleteQueries %d %p\n", n, ids);
732     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteQueries(n, ids) );
733   }
734
735   /**
736    * Wrapper for OpenGL ES 2.0 glDeleteRenderbuffers()
737    */
738   void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
739   {
740     LOG_GL("DeleteRenderbuffers %d %p\n", n, renderbuffers);
741     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteRenderbuffers(n, renderbuffers) );
742   }
743
744   /**
745    * Wrapper for OpenGL ES 2.0 glDeleteTextures()
746    */
747   void DeleteTextures(GLsizei n, const GLuint* textures)
748   {
749     LOG_GL("DeleteTextures %d %p\n", n, textures);
750     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteTextures(n, textures) );
751
752     ResetTextureCache();
753
754     // Need to reset the texture cache in the scene contexts
755     // This will only be executed by the surfaceless context when there are contexts for surface rendering
756     if ( mSceneContexts )
757     {
758       for ( auto&& context : *mSceneContexts )
759       {
760         if ( context )
761         {
762           context->ResetTextureCache();
763         }
764       }
765     }
766   }
767
768   /**
769    * Wrapper for OpenGL ES 3.0 glDeleteTransformFeedbacks()
770    */
771   void DeleteTransformFeedbacks(GLsizei n, GLuint* ids)
772   {
773     LOG_GL("DeleteTransformFeedbacks %d %p\n", n, ids);
774     CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteTransformFeedbacks(n, ids) );
775   }
776
777   /**
778    * Wrapper for OpenGL ES 2.0 glDepthFunc()
779    */
780   void DepthFunc(GLenum func)
781   {
782     if( func != mDepthFunction )
783     {
784       mDepthFunction = func;
785       LOG_GL("DepthFunc %x\n", func);
786       CHECK_GL( mGlAbstraction, mGlAbstraction.DepthFunc(func) );
787     }
788   }
789
790   /**
791    * Wrapper for OpenGL ES 2.0 glDepthMask()
792    */
793   void DepthMask(GLboolean flag)
794   {
795     bool booleanFlag = flag != GL_FALSE;
796     // only change state if needed
797     if( booleanFlag != mDepthMaskEnabled )
798     {
799       mDepthMaskEnabled = booleanFlag;
800       LOG_GL("DepthMask %s\n", booleanFlag ? "True" : "False");
801       CHECK_GL( mGlAbstraction, mGlAbstraction.DepthMask( mDepthMaskEnabled ) );
802     }
803   }
804
805   /**
806    * Wrapper for OpenGL ES 2.0 glDepthRangef()
807    */
808   void DepthRangef(GLclampf zNear, GLclampf zFar)
809   {
810     LOG_GL("DepthRangef %f %f\n", zNear, zFar);
811     CHECK_GL( mGlAbstraction, mGlAbstraction.DepthRangef(zNear, zFar) );
812   }
813
814   /**
815    * The wrapper for OpenGL ES 2.0 glDisable() has been replaced by SetBlend, SetCullFace, SetDepthTest,
816    * SetDither, SetPolygonOffsetFill, SetSampleAlphaToCoverage, SetSampleCoverage, SetScissorTest & SetStencilTest.
817    */
818
819   /**
820    * Wrapper for OpenGL ES 2.0 glDrawArrays()
821    */
822   void DrawArrays(GLenum mode, GLint first, GLsizei count)
823   {
824     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
825     FlushVertexAttributeLocations();
826
827     LOG_GL("DrawArrays %x %d %d\n", mode, first, count);
828     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawArrays(mode, first, count) );
829   }
830
831   /**
832    * Wrapper for OpenGL ES 3.0 glDrawArraysInstanced()
833    */
834   void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
835   {
836     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
837     FlushVertexAttributeLocations();
838
839     LOG_GL("DrawArraysInstanced %x %d %d %d\n", mode, first, count, instanceCount);
840     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawArraysInstanced(mode, first, count,instanceCount) );
841   }
842
843   /**
844    * Wrapper for OpenGL ES 3.0 glDrawBuffers()
845    */
846   void DrawBuffers(GLsizei n, const GLenum* bufs)
847   {
848     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
849     LOG_GL("DrawBuffers %d %p\n", n, bufs);
850     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawBuffers(n, bufs) );
851   }
852
853   /**
854    * Wrapper for OpenGL ES 2.0 glDrawElements()
855    */
856   void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
857   {
858     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
859
860     FlushVertexAttributeLocations();
861
862     LOG_GL("DrawElements %x %d %d %p\n", mode, count, type, indices);
863     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawElements(mode, count, type, indices) );
864   }
865
866   /**
867    * Wrapper for OpenGL ES 3.0 glDrawElementsInstanced()
868    */
869   void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instanceCount)
870   {
871     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
872
873     FlushVertexAttributeLocations();
874
875     LOG_GL("DrawElementsInstanced %x %d %d %p %d\n", mode, count, type, indices, instanceCount);
876     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawElementsInstanced(mode, count, type, indices, instanceCount) );
877   }
878
879   /**
880    * Wrapper for OpenGL ES 3.0 glDrawRangeElements()
881    */
882   void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
883   {
884     mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
885     FlushVertexAttributeLocations();
886
887     LOG_GL("DrawRangeElements %x %u %u %d %d %p\n", mode, start, end, count, type, indices);
888     CHECK_GL( mGlAbstraction, mGlAbstraction.DrawRangeElements(mode, start, end, count, type, indices) );
889   }
890
891   /**
892    * Wrapper for OpenGL ES 3.0 glGenQuerieS()
893    */
894   void GenQueries(GLsizei n, GLuint* ids)
895   {
896     LOG_GL("GenQueries %d %p\n", n, ids);
897     CHECK_GL( mGlAbstraction, mGlAbstraction.GenQueries(n, ids) );
898   }
899
900   /**
901    * Wrapper for OpenGL ES 3.0 glGenTransformFeedbacks()
902    */
903   void GenTransformFeedbacks(GLsizei n, GLuint* ids)
904   {
905     LOG_GL("GenTransformFeedbacks %d %p\n", n, ids);
906     CHECK_GL( mGlAbstraction, mGlAbstraction.GenTransformFeedbacks(n, ids) );
907   }
908
909   /**
910    * @return the current buffer bound for a given target
911    */
912   GLuint GetCurrentBoundArrayBuffer(GLenum target)
913   {
914     GLuint result(0);
915     switch(target)
916     {
917       case GL_ARRAY_BUFFER:
918       {
919         result = mBoundArrayBufferId;
920         break;
921       }
922       case GL_ELEMENT_ARRAY_BUFFER:
923       {
924         result = mBoundElementArrayBufferId;
925         break;
926       }
927       case GL_TRANSFORM_FEEDBACK_BUFFER:
928       {
929         result = mBoundTransformFeedbackBufferId;
930         break;
931       }
932       default:
933       {
934         DALI_ASSERT_DEBUG(0 && "target buffer type not supported");
935       }
936     }
937     return result;
938   }
939
940   void EnableVertexAttributeArray( GLuint location )
941   {
942     SetVertexAttributeLocation( location, true);
943   }
944
945   void DisableVertexAttributeArray( GLuint location )
946   {
947     SetVertexAttributeLocation( location, false);
948   }
949
950   /**
951    * Wrapper for OpenGL ES 3.0 glVertexAttribDivisor()
952    */
953   void VertexAttribDivisor ( GLuint index, GLuint divisor )
954   {
955     LOG_GL("VertexAttribDivisor(%d, %d)\n", index, divisor );
956     CHECK_GL( mGlAbstraction, mGlAbstraction.VertexAttribDivisor( index, divisor ) );
957   }
958
959   /**
960    * Wrapper for OpenGL ES 2.0 glVertexAttribPointer()
961    */
962   void VertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr )
963   {
964     LOG_GL("VertexAttribPointer(%d, %d, %d, %d, %d, %x)\n", index, size, type, normalized, stride, ptr );
965     CHECK_GL( mGlAbstraction, mGlAbstraction.VertexAttribPointer( index, size, type, normalized, stride, ptr ) );
966   }
967
968   /**
969    * Wrapper for OpenGL ES 3.0 glInvalidateFramebuffer()
970    */
971   void InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
972   {
973     LOG_GL("InvalidateFramebuffer\n");
974     CHECK_GL( mGlAbstraction, mGlAbstraction.InvalidateFramebuffer(target, numAttachments, attachments) );
975   }
976
977   /**
978    * The wrapper for OpenGL ES 2.0 glEnable() has been replaced by SetBlend, SetCullFace, SetDepthTest,
979    * SetDither, SetPolygonOffsetFill, SetSampleAlphaToCoverage, SetSampleCoverage, SetScissorTest & SetStencilTest.
980    */
981
982   /**
983    * This method replaces glEnable(GL_BLEND) and glDisable(GL_BLEND).
984    * @param[in] enable True if GL_BLEND should be enabled.
985    */
986   void SetBlend(bool enable)
987   {
988     // Avoid unecessary calls to glEnable/glDisable
989     if (enable != mBlendEnabled)
990     {
991       mBlendEnabled = enable;
992
993       if (enable)
994       {
995         LOG_GL("Enable GL_BLEND\n");
996         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_BLEND) );
997       }
998       else
999       {
1000         LOG_GL("Disable GL_BLEND\n");
1001         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_BLEND) );
1002       }
1003     }
1004   }
1005
1006   /**
1007    * This method replaces glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST).
1008    * Note GL_DEPTH_TEST means enable the depth buffer for writing and or testing.
1009    * glDepthMask is used to enable / disable writing to depth buffer.
1010    * glDepthFunc us used to control if testing is enabled and how it is performed ( default GL_LESS)
1011    *
1012    * @param[in] enable True if GL_DEPTH_TEST should be enabled.
1013    */
1014   void EnableDepthBuffer( bool enable )
1015   {
1016     // Avoid unecessary calls to glEnable/glDisable
1017     if( enable != mDepthBufferEnabled )
1018     {
1019       mDepthBufferEnabled = enable;
1020
1021       if (enable)
1022       {
1023         LOG_GL("Enable GL_DEPTH_TEST\n");
1024         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_DEPTH_TEST) );
1025       }
1026       else
1027       {
1028         LOG_GL("Disable GL_DEPTH_TEST\n");
1029         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_DEPTH_TEST) );
1030       }
1031     }
1032   }
1033
1034   /**
1035    * This method replaces glEnable(GL_DITHER) and glDisable(GL_DITHER).
1036    * @param[in] enable True if GL_DITHER should be enabled.
1037    */
1038   void SetDither(bool enable)
1039   {
1040     // Avoid unecessary calls to glEnable/glDisable
1041     if (enable != mDitherEnabled)
1042     {
1043       mDitherEnabled = enable;
1044
1045       if (enable)
1046       {
1047         LOG_GL("Enable GL_DITHER\n");
1048         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_DITHER) );
1049       }
1050       else
1051       {
1052         LOG_GL("Disable GL_DITHER\n");
1053         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_DITHER) );
1054       }
1055     }
1056   }
1057
1058   /**
1059    * This method replaces glEnable(GL_POLYGON_OFFSET_FILL) and glDisable(GL_POLYGON_OFFSET_FILL).
1060    * @param[in] enable True if GL_POLYGON_OFFSET_FILL should be enabled.
1061    */
1062   void SetPolygonOffsetFill(bool enable)
1063   {
1064     // Avoid unecessary calls to glEnable/glDisable
1065     if (enable != mPolygonOffsetFillEnabled)
1066     {
1067       mPolygonOffsetFillEnabled = enable;
1068
1069       if (enable)
1070       {
1071         LOG_GL("Enable GL_POLYGON_OFFSET_FILL\n");
1072         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_POLYGON_OFFSET_FILL) );
1073       }
1074       else
1075       {
1076         LOG_GL("Disable GL_POLYGON_OFFSET_FILL\n");
1077         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL) );
1078       }
1079     }
1080   }
1081
1082   /**
1083    * This method replaces glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) and glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE).
1084    * @param[in] enable True if GL_SAMPLE_ALPHA_TO_COVERAGE should be enabled.
1085    */
1086   void SetSampleAlphaToCoverage(bool enable)
1087   {
1088     // Avoid unecessary calls to glEnable/glDisable
1089     if (enable != mSampleAlphaToCoverageEnabled)
1090     {
1091       mSampleAlphaToCoverageEnabled = enable;
1092
1093       if (enable)
1094       {
1095         LOG_GL("Enable GL_SAMPLE_ALPHA_TO_COVERAGE\n");
1096         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE) );
1097       }
1098       else
1099       {
1100         LOG_GL("Disable GL_SAMPLE_ALPHA_TO_COVERAGE\n");
1101         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE) );
1102       }
1103     }
1104   }
1105
1106   /**
1107    * This method replaces glEnable(GL_SAMPLE_COVERAGE) and glDisable(GL_SAMPLE_COVERAGE).
1108    * @param[in] enable True if GL_SAMPLE_COVERAGE should be enabled.
1109    */
1110   void SetSampleCoverage(bool enable)
1111   {
1112     // Avoid unecessary calls to glEnable/glDisable
1113     if (enable != mSampleCoverageEnabled)
1114     {
1115       mSampleCoverageEnabled = enable;
1116
1117       if (enable)
1118       {
1119         LOG_GL("Enable GL_SAMPLE_COVERAGE\n");
1120         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SAMPLE_COVERAGE) );
1121       }
1122       else
1123       {
1124         LOG_GL("Disable GL_SAMPLE_COVERAGE\n");
1125         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SAMPLE_COVERAGE) );
1126       }
1127     }
1128   }
1129
1130   /**
1131    * This method replaces glEnable(GL_SCISSOR_TEST) and glDisable(GL_SCISSOR_TEST).
1132    * @param[in] enable True if GL_SCISSOR_TEST should be enabled.
1133    */
1134   void SetScissorTest(bool enable)
1135   {
1136     // Avoid unecessary calls to glEnable/glDisable
1137     if (enable != mScissorTestEnabled)
1138     {
1139       mScissorTestEnabled = enable;
1140
1141       if (enable)
1142       {
1143         LOG_GL("Enable GL_SCISSOR_TEST\n");
1144         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_SCISSOR_TEST) );
1145       }
1146       else
1147       {
1148         LOG_GL("Disable GL_SCISSOR_TEST\n");
1149         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_SCISSOR_TEST) );
1150       }
1151     }
1152   }
1153
1154   /**
1155    * This method replaces glEnable(GL_STENCIL_TEST) and glDisable(GL_STENCIL_TEST).
1156    * Note GL_STENCIL_TEST means enable the stencil buffer for writing and or testing.
1157    * glStencilMask is used to control how bits are written to the stencil buffer.
1158    * glStencilFunc is used to control if testing is enabled and how it is performed ( default GL_ALWAYS )
1159    * @param[in] enable True if GL_STENCIL_TEST should be enabled.
1160    */
1161   void EnableStencilBuffer(bool enable)
1162   {
1163     // Avoid unecessary calls to glEnable/glDisable
1164     if( enable != mStencilBufferEnabled )
1165     {
1166       mStencilBufferEnabled = enable;
1167
1168       if (enable)
1169       {
1170         LOG_GL("Enable GL_STENCIL_TEST\n");
1171         CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_STENCIL_TEST) );
1172       }
1173       else
1174       {
1175         LOG_GL("Disable GL_STENCIL_TEST\n");
1176         CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_STENCIL_TEST) );
1177       }
1178     }
1179   }
1180
1181   /**
1182    * Wrapper for OpenGL ES 3.0 glEndQuery()
1183    */
1184   void EndQuery(GLenum target)
1185   {
1186     LOG_GL("EndQuery %d\n", target);
1187     CHECK_GL( mGlAbstraction, mGlAbstraction.EndQuery(target) );
1188   }
1189
1190   /**
1191    * Wrapper for OpenGL ES 3.0 glEndTransformFeedback()
1192    */
1193   void EndTransformFeedback()
1194   {
1195     LOG_GL("EndTransformFeedback\n");
1196     CHECK_GL( mGlAbstraction, mGlAbstraction.EndTransformFeedback() );
1197   }
1198
1199   /**
1200    * Wrapper for OpenGL ES 2.0 glFinish()
1201    */
1202   void Finish(void)
1203   {
1204     LOG_GL("Finish\n");
1205     CHECK_GL( mGlAbstraction, mGlAbstraction.Finish() );
1206   }
1207
1208   /**
1209    * Wrapper for OpenGL ES 2.0 glFlush()
1210    */
1211   void Flush(void)
1212   {
1213     LOG_GL("Flush\n");
1214     CHECK_GL( mGlAbstraction, mGlAbstraction.Flush() );
1215   }
1216
1217   /**
1218    * Wrapper for OpenGL ES 2.0 glFramebufferRenderbuffer()
1219    */
1220   void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1221   {
1222     LOG_GL("FramebufferRenderbuffer %x %x %x %d\n", target, attachment, renderbuffertarget, renderbuffer);
1223     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) );
1224   }
1225
1226   /**
1227    * Wrapper for OpenGL ES 2.0 glFramebufferTexture2D()
1228    */
1229   void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1230   {
1231     LOG_GL("FramebufferTexture2D %x %x %x %d %d\n", target, attachment, textarget, texture, level);
1232     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferTexture2D(target, attachment, textarget, texture, level) );
1233   }
1234
1235   /**
1236    * Wrapper for OpenGL ES 3.0 glFramebufferTextureLayer()
1237    */
1238   void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
1239   {
1240     LOG_GL("FramebufferTextureLayer %x %x %d %d %d\n", target, attachment, texture, level, layer);
1241     CHECK_GL( mGlAbstraction, mGlAbstraction.FramebufferTextureLayer(target, attachment, texture, level, layer) );
1242   }
1243
1244   /**
1245    * Wrapper for OpenGL ES 2.0 glFrontFace()
1246    */
1247   void FrontFace(GLenum mode)
1248   {
1249     LOG_GL("FrontFace %x\n", mode);
1250     CHECK_GL( mGlAbstraction, mGlAbstraction.FrontFace(mode) );
1251   }
1252
1253   /**
1254    * Wrapper for OpenGL ES 2.0 glGenBuffers()
1255    */
1256   void GenBuffers(GLsizei n, GLuint* buffers)
1257   {
1258     LOG_GL("GenBuffers %d\n", n, buffers);
1259     CHECK_GL( mGlAbstraction, mGlAbstraction.GenBuffers(n, buffers) );
1260   }
1261
1262   /**
1263    * Wrapper for OpenGL ES 2.0 glGenerateMipmap()
1264    */
1265   void GenerateMipmap(GLenum target)
1266   {
1267     LOG_GL("GenerateMipmap %x\n", target);
1268     CHECK_GL( mGlAbstraction, mGlAbstraction.GenerateMipmap(target) );
1269   }
1270
1271   /**
1272    * Wrapper for OpenGL ES 2.0 glGenFramebuffers()
1273    */
1274   void GenFramebuffers(GLsizei n, GLuint* framebuffers)
1275   {
1276     LOG_GL("GenFramebuffers %d %p\n", n, framebuffers);
1277     CHECK_GL( mGlAbstraction, mGlAbstraction.GenFramebuffers(n, framebuffers) );
1278
1279     mFrameBufferStateCache.FrameBuffersCreated( n, framebuffers );
1280   }
1281
1282   /**
1283    * Wrapper for OpenGL ES 2.0 glGenRenderbuffers()
1284    */
1285   void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1286   {
1287     LOG_GL("GenRenderbuffers %d %p\n", n, renderbuffers);
1288     CHECK_GL( mGlAbstraction, mGlAbstraction.GenRenderbuffers(n, renderbuffers) );
1289   }
1290
1291   /**
1292    * Wrapper for OpenGL ES 2.0 glGenTextures()
1293    */
1294   void GenTextures(GLsizei n, GLuint* textures)
1295   {
1296     LOG_GL("GenTextures %d %p\n", n, textures);
1297     CHECK_GL( mGlAbstraction, mGlAbstraction.GenTextures(n, textures) );
1298   }
1299
1300   /**
1301    * Wrapper for OpenGL ES 2.0 glGetBooleanv()
1302    */
1303   void GetBooleanv(GLenum pname, GLboolean* params)
1304   {
1305     LOG_GL("GetBooleanv %x\n", pname);
1306     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBooleanv(pname, params) );
1307   }
1308
1309   /**
1310    * Wrapper for OpenGL ES 2.0 glGetBufferParameteriv()
1311    */
1312   void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1313   {
1314     LOG_GL("GetBufferParameteriv %x %x %p\n", target, pname, params);
1315     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBufferParameteriv(target, pname, params) );
1316   }
1317
1318   /**
1319    * Wrapper for OpenGL ES 3.0 glGetBufferPointer()
1320    */
1321   void GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
1322   {
1323     LOG_GL("GetBufferPointerv %x %x %p\n", target, pname, params);
1324     CHECK_GL( mGlAbstraction, mGlAbstraction.GetBufferPointerv(target, pname, params) );
1325   }
1326
1327   /**
1328    * Wrapper for OpenGL ES 2.0 glGetError()
1329    */
1330   GLenum GetError(void)
1331   {
1332     // Not worth logging here
1333     return mGlAbstraction.GetError();
1334   }
1335
1336   /**
1337    * Wrapper for OpenGL ES 2.0 glGetFloatv()
1338    */
1339   void GetFloatv(GLenum pname, GLfloat* params)
1340   {
1341     LOG_GL("GetFloatv %x\n", pname);
1342     CHECK_GL( mGlAbstraction, mGlAbstraction.GetFloatv(pname, params) );
1343   }
1344
1345   /**
1346    * Wrapper for OpenGL ES 2.0 glGetFramebufferAttachmentParameteriv()
1347    */
1348   void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1349   {
1350     LOG_GL("GetFramebufferAttachmentParameteriv %x %x %x\n", target, attachment, pname);
1351     CHECK_GL( mGlAbstraction, mGlAbstraction.GetFramebufferAttachmentParameteriv(target, attachment, pname, params) );
1352   }
1353
1354   /**
1355    * Wrapper for OpenGL ES 2.0 glGetIntegerv()
1356    */
1357   void GetIntegerv(GLenum pname, GLint* params)
1358   {
1359     LOG_GL("GetIntegerv %x\n", pname);
1360     CHECK_GL( mGlAbstraction, mGlAbstraction.GetIntegerv(pname, params) );
1361   }
1362
1363   /**
1364    * Wrapper for OpenGL ES 3.0 glGetQueryiv()
1365    */
1366   void GetQueryiv(GLenum target, GLenum pname, GLint* params)
1367   {
1368     LOG_GL("GetQueryiv %x %x\n", target, pname);
1369     CHECK_GL( mGlAbstraction, mGlAbstraction.GetQueryiv(target, pname, params) );
1370   }
1371
1372   /**
1373    * Wrapper for OpenGL ES 3.0 glGetQueryObjectuiv()
1374    */
1375   void GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
1376   {
1377     LOG_GL("GetQueryObjectuiv %u %x %p\n", id, pname, params);
1378     CHECK_GL( mGlAbstraction, mGlAbstraction.GetQueryObjectuiv(id, pname, params) );
1379   }
1380
1381   /**
1382    * Wrapper for OpenGL ES 2.0 glGetRenderbufferParameteriv()
1383    */
1384   void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
1385   {
1386     LOG_GL("GetRenderbufferParameteriv %x %x\n", target, pname);
1387     CHECK_GL( mGlAbstraction, mGlAbstraction.GetRenderbufferParameteriv(target, pname, params) );
1388   }
1389
1390   /**
1391    * Wrapper for OpenGL ES 2.0 glGetString()
1392    */
1393   const GLubyte* GetString(GLenum name)
1394   {
1395     LOG_GL("GetString %x\n", name);
1396     const GLubyte* str = CHECK_GL( mGlAbstraction, mGlAbstraction.GetString(name) );
1397     return str;
1398   }
1399
1400   /**
1401    * Wrapper for OpenGL ES 2.0 glGetTexParameterfv()
1402    */
1403   void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
1404   {
1405     LOG_GL("GetTexParameterfv %x %x\n", target, pname);
1406     CHECK_GL( mGlAbstraction, mGlAbstraction.GetTexParameterfv(target, pname, params) );
1407   }
1408
1409   /**
1410    * Wrapper for OpenGL ES 2.0 glGetTexParameteriv()
1411    */
1412   void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
1413   {
1414     LOG_GL("GetTexParameteriv %x %x\n", target, pname);
1415     CHECK_GL( mGlAbstraction, mGlAbstraction.GetTexParameteriv(target, pname, params) );
1416   }
1417
1418   /**
1419    * Wrapper for OpenGL ES 2.0 glHint()
1420    */
1421   void Hint(GLenum target, GLenum mode)
1422   {
1423     LOG_GL("Hint %x %x\n", target, mode);
1424     CHECK_GL( mGlAbstraction, mGlAbstraction.Hint(target, mode) );
1425   }
1426
1427   /**
1428    * Wrapper for OpenGL ES 2.0 glIsBuffer()
1429    */
1430   GLboolean IsBuffer(GLuint buffer)
1431   {
1432     LOG_GL("IsBuffer %d\n", buffer);
1433     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsBuffer(buffer) );
1434     return val;
1435   }
1436
1437   /**
1438    * Wrapper for OpenGL ES 2.0 glIsEnabled()
1439    */
1440   GLboolean IsEnabled(GLenum cap)
1441   {
1442     LOG_GL("IsEnabled %x\n", cap);
1443     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsEnabled(cap) );
1444     return val;
1445   }
1446
1447   /**
1448    * Wrapper for OpenGL ES 2.0 glIsFramebuffer()
1449    */
1450   GLboolean IsFramebuffer(GLuint framebuffer)
1451   {
1452     LOG_GL("IsFramebuffer %d\n", framebuffer);
1453     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsFramebuffer(framebuffer) );
1454     return val;
1455   }
1456
1457   /**
1458    * Wrapper for OpenGL ES 3.0 glIsQuery()
1459    */
1460   GLboolean IsQuery(GLuint id)
1461   {
1462     LOG_GL("IsQuery %u\n", id);
1463     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsQuery(id) );
1464     return val;
1465   }
1466
1467   /**
1468    * Wrapper for OpenGL ES 2.0 glIsRenderbuffer()
1469    */
1470   GLboolean IsRenderbuffer(GLuint renderbuffer)
1471   {
1472     LOG_GL("IsRenderbuffer %d\n", renderbuffer);
1473     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsRenderbuffer(renderbuffer) );
1474     return val;
1475   }
1476
1477   /**
1478    * Wrapper for OpenGL ES 2.0 glIsTexture()
1479    */
1480   GLboolean IsTexture(GLuint texture)
1481   {
1482     LOG_GL("IsTexture %d\n", texture);
1483     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsTexture(texture) );
1484     return val;
1485   }
1486
1487   /**
1488    * Wrapper for OpenGL ES 3.0 glIsTransformFeedback()
1489    */
1490   GLboolean IsTransformFeedback(GLuint id)
1491   {
1492     LOG_GL("IsTransformFeedback %u\n", id);
1493     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.IsTransformFeedback(id) );
1494     return val;
1495   }
1496
1497   /**
1498    * Wrapper for OpenGL ES 2.0 glLineWidth()
1499    */
1500   void LineWidth(GLfloat width)
1501   {
1502     LOG_GL("LineWidth %f\n", width);
1503     CHECK_GL( mGlAbstraction, mGlAbstraction.LineWidth(width) );
1504   }
1505
1506   /**
1507    * Wrapper for OpenGL ES 3.0 glPauseTransformFeedback()
1508    */
1509   void PauseTransformFeedback()
1510   {
1511     LOG_GL("PauseTransformFeedback\n");
1512     CHECK_GL( mGlAbstraction, mGlAbstraction.PauseTransformFeedback() );
1513   }
1514
1515   /**
1516    * Wrapper for OpenGL ES 2.0 glPixelStorei()
1517    */
1518   void PixelStorei(GLenum pname, GLint param)
1519   {
1520     LOG_GL("PixelStorei %x %d\n", pname, param);
1521     CHECK_GL( mGlAbstraction, mGlAbstraction.PixelStorei(pname, param) );
1522   }
1523
1524   /**
1525    * Wrapper for OpenGL ES 2.0 glPolygonOffset()
1526    */
1527   void PolygonOffset(GLfloat factor, GLfloat units)
1528   {
1529     LOG_GL("PolygonOffset %f %f\n", factor, units);
1530     CHECK_GL( mGlAbstraction, mGlAbstraction.PolygonOffset(factor, units) );
1531   }
1532
1533   /**
1534    * Wrapper for OpenGL ES 2.0 glReadPixels()
1535    */
1536   void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
1537   {
1538     LOG_GL("ReadPixels %d %d %d %d %x %x\n", x, y, width, height, format, type);
1539     CHECK_GL( mGlAbstraction, mGlAbstraction.ReadPixels(x, y, width, height, format, type, pixels) );
1540   }
1541
1542   /**
1543    * Wrapper for OpenGL ES 2.0 glRenderbufferStorage()
1544    */
1545   void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
1546   {
1547     LOG_GL("RenderbufferStorage %x %x %d %d\n", target, internalformat, width, height);
1548     CHECK_GL( mGlAbstraction, mGlAbstraction.RenderbufferStorage(target, internalformat, width, height) );
1549   }
1550
1551   /**
1552    * Wrapper for OpenGL ES 3.0 glRenderbufferStorageMultisample()
1553    */
1554   void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
1555   {
1556     LOG_GL("RenderbufferStorageMultisample %x %u %x %d %d\n", target, samples, internalformat, width, height);
1557     CHECK_GL( mGlAbstraction, mGlAbstraction.RenderbufferStorageMultisample(target, samples, internalformat, width, height) );
1558   }
1559
1560   /**
1561    * Wrapper for OpenGL ES 3.0 glResumeTransformFeedback()
1562    */
1563   void ResumeTransformFeedback()
1564   {
1565     LOG_GL("ResumeTransformFeedback\n");
1566     CHECK_GL( mGlAbstraction, mGlAbstraction.ResumeTransformFeedback() );
1567   }
1568
1569   /**
1570    * Wrapper for OpenGL ES 2.0 glSampleCoverage()
1571    */
1572   void SampleCoverage(GLclampf value, GLboolean invert)
1573   {
1574     LOG_GL("SampleCoverage %f %s\n", value, invert ? "True" : "False");
1575     CHECK_GL( mGlAbstraction, mGlAbstraction.SampleCoverage(value, invert) );
1576   }
1577
1578   /**
1579    * Wrapper for OpenGL ES 2.0 glScissor()
1580    */
1581   void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1582   {
1583     GLint cx, cy, cw, ch;
1584
1585     // scissor's value should be set based on the default system coordinates.
1586     // when the surface is rotated, the input valus already were set with the rotated angle.
1587     // So, re-calculation is needed.
1588     if(mSurfaceOrientation == 90)
1589     {
1590       cx = mViewPort.height - (y + height);
1591       cy = x;
1592       cw = height;
1593       ch = width;
1594     }
1595     else if(mSurfaceOrientation == 180)
1596     {
1597       cx = mViewPort.width - (x + width);
1598       cy = mViewPort.height - (y + height);
1599       cw = width;
1600       ch = height;
1601     }
1602     else if(mSurfaceOrientation == 270)
1603     {
1604       cx = y;
1605       cy = mViewPort.width - (x + width);
1606       cw = height;
1607       ch = width;
1608     }
1609     else
1610     {
1611       cx = x;
1612       cy = y;
1613       cw = width;
1614       ch = height;
1615     }
1616
1617     LOG_GL("Scissor %d %d %d %d\n", cx, cy, cw, ch);
1618     CHECK_GL(mGlAbstraction, mGlAbstraction.Scissor(cx, cy, cw, ch));
1619   }
1620
1621   /**
1622    * Wrapper for OpenGL ES 2.0 glStencilFunc()
1623    */
1624   void StencilFunc(GLenum func, GLint ref, GLuint mask)
1625   {
1626     if( ( func != mStencilFunc ) || ( ref != mStencilFuncRef ) || ( mask != mStencilFuncMask ) )
1627     {
1628       mStencilFunc = func;
1629       mStencilFuncRef = ref;
1630       mStencilFuncMask = mask;
1631
1632       LOG_GL("StencilFunc %x %d %d\n", func, ref, mask);
1633       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFunc(func, ref, mask) );
1634     }
1635   }
1636
1637   /**
1638    * Wrapper for OpenGL ES 2.0 glStencilFuncSeparate()
1639    */
1640   void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
1641   {
1642     LOG_GL("StencilFuncSeparate %x %x %d %d\n", face, func, ref, mask);
1643     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFuncSeparate(face, func, ref, mask) );
1644   }
1645
1646   /**
1647    * Wrapper for OpenGL ES 2.0 glStencilMask()
1648    */
1649   void StencilMask(GLuint mask)
1650   {
1651     if( mask != mStencilMask )
1652     {
1653       mStencilMask = mask;
1654
1655       LOG_GL("StencilMask %d\n", mask);
1656       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilMask(mask) );
1657     }
1658   }
1659
1660   /**
1661    * Wrapper for OpenGL ES 2.0 glStencilMaskSeparate()
1662    */
1663   void StencilMaskSeparate(GLenum face, GLuint mask)
1664   {
1665     LOG_GL("StencilMaskSeparate %x %d\n", face, mask);
1666     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilMaskSeparate(face, mask) );
1667   }
1668
1669   /**
1670    * Wrapper for OpenGL ES 2.0 glStencilOp()
1671    */
1672   void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
1673   {
1674     if( ( fail != mStencilOpFail ) || ( zfail != mStencilOpDepthFail ) || ( zpass != mStencilOpDepthPass ) )
1675     {
1676       mStencilOpFail = fail;
1677       mStencilOpDepthFail = zfail;
1678       mStencilOpDepthPass = zpass;
1679
1680       LOG_GL("StencilOp %x %x %x\n", fail, zfail, zpass);
1681       CHECK_GL( mGlAbstraction, mGlAbstraction.StencilOp(fail, zfail, zpass) );
1682     }
1683   }
1684
1685   /**
1686    * Wrapper for OpenGL ES 2.0 glStencilOpSeparate()
1687    */
1688   void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
1689   {
1690     LOG_GL("StencilOpSeparate %x %x %x %x\n", face, fail, zfail, zpass);
1691     CHECK_GL( mGlAbstraction, mGlAbstraction.StencilOpSeparate(face, fail, zfail, zpass) );
1692   }
1693
1694   /**
1695    * Wrapper for OpenGL ES 2.0 glTexImage2D()
1696    */
1697   void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
1698                   GLint border, GLenum format, GLenum type, const void* pixels)
1699   {
1700     LOG_GL("TexImage2D %x %d %d %dx%d %d %x %x %p\n", target, level, internalformat, width, height, border, format, type, pixels);
1701     CHECK_GL( mGlAbstraction, mGlAbstraction.TexImage2D(target, level, internalformat, width, height, border, format, type, pixels) );
1702   }
1703
1704   /**
1705    * Wrapper for OpenGL ES 3.0 glTexImage3D()
1706    */
1707   void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth,
1708                   GLint border, GLenum format, GLenum type, const void* pixels)
1709   {
1710     LOG_GL("TexImage3D %x %d %d %dx%dx%d %d %x %x %p\n", target, level, internalformat, width, height, depth, border, format, type, pixels);
1711     CHECK_GL( mGlAbstraction, mGlAbstraction.TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) );
1712   }
1713
1714   /**
1715    * Wrapper for OpenGL ES 2.0 glTexParameterf()
1716    */
1717   void TexParameterf(GLenum target, GLenum pname, GLfloat param)
1718   {
1719     LOG_GL("TexParameterf %x %x %f\n", target, pname, param);
1720     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameterf(target, pname, param) );
1721   }
1722
1723   /**
1724    * Wrapper for OpenGL ES 2.0 glTexParameterfv()
1725    */
1726   void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
1727   {
1728     LOG_GL("TexParameterfv %x %x\n", target, pname);
1729     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameterfv(target, pname, params) );
1730   }
1731
1732   /**
1733    * Wrapper for OpenGL ES 2.0 glTexParameteri()
1734    */
1735   void TexParameteri(GLenum target, GLenum pname, GLint param)
1736   {
1737     LOG_GL("TexParameteri %x %x %d\n", target, pname, param);
1738     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameteri(target, pname, param) );
1739   }
1740
1741   /**
1742    * Wrapper for OpenGL ES 2.0 glTexParameteriv()
1743    */
1744   void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
1745   {
1746     LOG_GL("TexParameteriv %x %x\n", target, pname);
1747     CHECK_GL( mGlAbstraction, mGlAbstraction.TexParameteriv(target, pname, params) );
1748   }
1749
1750   /**
1751    * Wrapper for OpenGL ES 2.0 glTexSubImage2D()
1752    */
1753   void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1754                      GLenum format, GLenum type, const void* pixels)
1755   {
1756     LOG_GL("TexSubImage2D %x %d %d %d %d %d %x %x %p\n", target, level, xoffset, yoffset, width, height, format, type, pixels);
1757     CHECK_GL( mGlAbstraction, mGlAbstraction.TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) );
1758   }
1759
1760   /**
1761    * Wrapper for OpenGL ES 3.0 glTexSubImage3D()
1762    */
1763   void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
1764                      GLsizei width, GLsizei height, GLsizei depth,
1765                      GLenum format, GLenum type, const void* pixels)
1766   {
1767     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);
1768     CHECK_GL( mGlAbstraction, mGlAbstraction.TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) );
1769   }
1770
1771   /**
1772    * Wrapper for OpenGL ES 3.0 glUnmapBuffer()
1773    */
1774   GLboolean UnmapBuffer(GLenum target)
1775   {
1776     LOG_GL("UnmapBuffer %x \n", target);
1777     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.UnmapBuffer(target) );
1778     return val;
1779   }
1780
1781   /**
1782    * Wrapper for OpenGL ES 2.0 glViewport()
1783    */
1784   void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1785   {
1786     // check if its same as already set
1787     GLsizei cw, ch;
1788
1789     // viewport's value shoud be set based on the default system size.
1790     // when the surface is rotated, the input width and height already were swapped.
1791     // So, re-swapping is needed.
1792     if(mSurfaceOrientation == 90 || mSurfaceOrientation == 270)
1793     {
1794       cw = height;
1795       ch = width;
1796     }
1797     else
1798     {
1799       cw = width;
1800       ch = height;
1801     }
1802
1803     // User uses the rotated viewport size.
1804     Rect<int> newViewport(x, y, width, height);
1805
1806     // Temporarily disable the viewport caching, as the implementation of GLES driver in Tizen platform
1807     // share a global viewport between multiple contexts, therefore glViewport has to be called every
1808     // time after glBindFramebuffer regardless of the same vewport size in the same context.
1809     //    if( mViewPort != newViewport )
1810     {
1811       // set new one
1812       LOG_GL("Viewport %d %d %d %d\n", x, y, cw, ch);
1813       CHECK_GL(mGlAbstraction, mGlAbstraction.Viewport(x, y, cw, ch));
1814       mViewPort = newViewport; // remember new one
1815     }
1816   }
1817
1818   /**
1819    * Wrapper for OpenGL ES 3.2 and GL_KHR_blend_equation_advanced extention glBlendBarrier()
1820    */
1821   void BlendBarrier()
1822   {
1823     LOG_GL( "BlendBarrier\n" );
1824     CHECK_GL( mGlAbstraction, mGlAbstraction.BlendBarrier() );
1825   }
1826
1827   /**
1828    * Get the implementation defined MAX_TEXTURE_SIZE. This values is cached when the context is created
1829    * @return The implementation defined MAX_TEXTURE_SIZE
1830    */
1831   GLint CachedMaxTextureSize() const
1832   {
1833     return mMaxTextureSize;
1834   }
1835
1836   void SetSurfaceOrientation(int orientation)
1837   {
1838     LOG_GL( "SetSurfaceOrientation: orientation: %d\n", orientation );
1839     mSurfaceOrientation = orientation;
1840   }
1841
1842   /**
1843    * Get the current viewport.
1844    * @return Viewport rectangle.
1845    */
1846   const Rect< int >& GetViewport();
1847
1848 private: // Implementation
1849
1850   /**
1851    * @return true if next draw operation will write to depth buffer
1852    */
1853   bool DepthBufferWriteEnabled() const
1854   {
1855     return mDepthBufferEnabled && mDepthMaskEnabled;
1856   }
1857
1858   /**
1859    * @return true if next draw operation will write to stencil buffer
1860    */
1861   bool StencilBufferWriteEnabled() const
1862   {
1863     return mStencilBufferEnabled && ( mStencilMask > 0 );
1864   }
1865
1866   /**
1867    * Flushes vertex attribute location changes to the driver
1868    */
1869   void FlushVertexAttributeLocations();
1870
1871   /**
1872    * Either enables or disables a vertex attribute location in the cache
1873    * The cahnges won't take affect until FlushVertexAttributeLocations is called
1874    * @param location attribute location
1875    * @param state attribute state
1876    */
1877   void SetVertexAttributeLocation(unsigned int location, bool state);
1878
1879   /**
1880    * Sets the initial GL state.
1881    */
1882   void InitializeGlState();
1883
1884 private: // Data
1885
1886   Integration::GlAbstraction& mGlAbstraction;
1887
1888   bool mGlContextCreated; ///< True if the OpenGL context has been created
1889
1890   // glEnable/glDisable states
1891   bool mColorMask;
1892   GLuint mStencilMask;
1893   bool mBlendEnabled;
1894   bool mDepthBufferEnabled;
1895   bool mDepthMaskEnabled;
1896   bool mDitherEnabled;
1897   bool mPolygonOffsetFillEnabled;
1898   bool mSampleAlphaToCoverageEnabled;
1899   bool mSampleCoverageEnabled;
1900   bool mScissorTestEnabled;
1901   bool mStencilBufferEnabled;
1902   bool mClearColorSet;
1903   bool mUsingDefaultBlendColor;
1904
1905   // glBindBuffer() state
1906   GLuint mBoundArrayBufferId;        ///< The ID passed to glBindBuffer(GL_ARRAY_BUFFER)
1907   GLuint mBoundElementArrayBufferId; ///< The ID passed to glBindBuffer(GL_ELEMENT_ARRAY_BUFFER)
1908   GLuint mBoundTransformFeedbackBufferId; ///< The ID passed to glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER)
1909
1910   // glBindTexture() state
1911   TextureUnit mActiveTextureUnit;
1912   GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ][MAX_TEXTURE_TARGET];  ///< The ID passed to glBindTexture()
1913
1914   // glBlendColor() state
1915   Vector4 mBlendColor; ///< Blend color
1916
1917   // glBlendFuncSeparate() state
1918   GLenum mBlendFuncSeparateSrcRGB;   ///< The srcRGB parameter passed to glBlendFuncSeparate()
1919   GLenum mBlendFuncSeparateDstRGB;   ///< The dstRGB parameter passed to glBlendFuncSeparate()
1920   GLenum mBlendFuncSeparateSrcAlpha; ///< The srcAlpha parameter passed to glBlendFuncSeparate()
1921   GLenum mBlendFuncSeparateDstAlpha; ///< The dstAlpha parameter passed to glBlendFuncSeparate()
1922
1923   // glBlendEquationSeparate state
1924   GLenum mBlendEquationSeparateModeRGB;    ///< Controls RGB blend mode
1925   GLenum mBlendEquationSeparateModeAlpha;  ///< Controls Alpha blend mode
1926
1927   // glStencilFunc() and glStencilOp() state.
1928   GLenum mStencilFunc;
1929   GLint mStencilFuncRef;
1930   GLuint mStencilFuncMask;
1931   GLenum mStencilOpFail;
1932   GLenum mStencilOpDepthFail;
1933   GLenum mStencilOpDepthPass;
1934
1935   GLenum mDepthFunction;  ///The depth function
1936
1937   GLint mMaxTextureSize;      ///< return value from GetIntegerv(GL_MAX_TEXTURE_SIZE)
1938   Vector4 mClearColor;        ///< clear color
1939
1940   // Face culling mode
1941   Dali::FaceCullingMode::Type mCullFaceMode;
1942
1943   // cached viewport size
1944   Rect< int > mViewPort;
1945
1946   // Vertex Attribute Buffer enable caching
1947   bool mVertexAttributeCachedState[ MAX_ATTRIBUTE_CACHE_SIZE ];    ///< Value cache for Enable Vertex Attribute
1948   bool mVertexAttributeCurrentState[ MAX_ATTRIBUTE_CACHE_SIZE ];   ///< Current state on the driver for Enable Vertex Attribute
1949
1950   FrameBufferStateCache mFrameBufferStateCache;   ///< frame buffer state cache
1951
1952   OwnerContainer< Context* >* mSceneContexts;      ///< The pointer of the container of contexts for surface rendering
1953
1954   int mSurfaceOrientation;
1955 };
1956
1957 } // namespace Internal
1958
1959 } // namespace Dali
1960
1961 #endif // DALI_INTERNAL_CONTEXT_H