Support screen and client rotation
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / context.h
index be2db89..a66cee1 100644 (file)
@@ -60,9 +60,10 @@ public:
    * Size of the VertexAttributeArray enables
    * GLES specification states that there's minimum of 8
    */
-  static const unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
+  static constexpr unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
 
-  static const unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
+  static constexpr unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
+  static constexpr unsigned int MAX_TEXTURE_TARGET = 3; // We support only GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP and GL_TEXTURE_EXTERNAL_OES now
 
   /**
    * Creates the Dali Context object for surface rendering only.
@@ -81,7 +82,7 @@ public:
    * @param glAbstraction the gl abstraction.
    * @param contexts The list of scene contexts (for surface rendering)
    */
-  Context( Integration::GlAbstraction& glAbstraction, std::vector< Context* >* contexts );
+  Context( Integration::GlAbstraction& glAbstraction, OwnerContainer< Context* >* contexts );
 
   /**
    * Destructor
@@ -133,6 +134,9 @@ public:
     DALI_LOG_INFO(Debug::Filter::gRender, Debug::General, "GL %s = %s\n", stringName, reinterpret_cast< const char * >( GetString( stringId ) ) );
   }
 
+  /**
+   * Reset the cached buffer ids.
+   */
   void ResetBufferCache()
   {
     // reset the cached buffer id's
@@ -143,13 +147,47 @@ public:
     mBoundTransformFeedbackBufferId = 0;
   }
 
+  /**
+   * Reset the cached texture ids.
+   */
   void ResetTextureCache()
   {
     // reset the cached texture id's in case the driver re-uses them
     // when creating new textures
-    for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
+    for(unsigned int i = 0; i < MAX_TEXTURE_UNITS; ++i)
     {
-       mBoundTextureId[ i ] = 0;
+      for(unsigned int j = 0; j < MAX_TEXTURE_TARGET; ++j)
+      {
+        mBoundTextureId[i][j] = 0;
+      }
+    }
+  }
+
+  /**
+   * Get an index of the cached texture list from the texture target.
+   * @param target The texture target
+   * @return The index of the cached texture list
+   */
+  static constexpr int16_t GetTextureIndexFromGlFormat(int target)
+  {
+    switch(target)
+    {
+      case GL_TEXTURE_2D:
+      {
+        return 0;
+      }
+      case GL_TEXTURE_CUBE_MAP:
+      {
+        return 1;
+      }
+      case GL_TEXTURE_EXTERNAL_OES:
+      {
+        return 2;
+      }
+      default:
+      {
+        return -1;
+      }
     }
   }
 
@@ -311,11 +349,8 @@ public:
    */
   void BindTextureForUnit( TextureUnit textureunit, int target, GLuint texture )
   {
-    if( mBoundTextureId[ textureunit ] != texture )
-    {
-      ActiveTexture( textureunit );
-      BindTexture( target, texture );
-    }
+    ActiveTexture(textureunit);
+    BindTexture(target, texture);
   }
 
   /**
@@ -323,12 +358,22 @@ public:
    */
   void BindTexture( int target, GLuint texture )
   {
-    if (mBoundTextureId[ mActiveTextureUnit ] != texture)
+    int16_t index = GetTextureIndexFromGlFormat(target);
+    if(index >= 0)
     {
-      mBoundTextureId[ mActiveTextureUnit ] = texture;
+      if(mBoundTextureId[ mActiveTextureUnit ][index] != texture)
+      {
+        mBoundTextureId[ mActiveTextureUnit ][index] = texture;
 
+        LOG_GL("BindTexture target(%d) %d\n", target, texture);
+        CHECK_GL(mGlAbstraction, mGlAbstraction.BindTexture(target, texture));
+      }
+    }
+    else
+    {
+      // Don't use cache
       LOG_GL("BindTexture target(%d) %d\n", target, texture);
-      CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(target, texture) );
+      CHECK_GL(mGlAbstraction, mGlAbstraction.BindTexture(target, texture));
     }
   }
 
@@ -363,8 +408,16 @@ public:
    */
   void BlendEquation(GLenum mode)
   {
-    // use BlendEquationSeparate to set the rgb and alpha modes the same
-    BlendEquationSeparate( mode, mode );
+    // DO NOT USE BlendEquationSeparate to set the same rgb and alpha modes
+    // KHR blending extensions require use of glBlendEquation
+
+    if( mBlendEquationSeparateModeRGB != mode || mBlendEquationSeparateModeAlpha != mode )
+    {
+      mBlendEquationSeparateModeRGB = mode;
+      mBlendEquationSeparateModeAlpha = mode;
+      LOG_GL("BlendEquation %d\n", mode);
+      CHECK_GL( mGlAbstraction, mGlAbstraction.BlendEquation( mode ) );
+    }
   }
 
   /**
@@ -1527,8 +1580,42 @@ public:
    */
   void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
   {
-    LOG_GL("Scissor %d %d %d %d\n", x, y, width, height);
-    CHECK_GL( mGlAbstraction, mGlAbstraction.Scissor(x, y, width, height) );
+    GLint cx, cy, cw, ch;
+
+    // scissor's value should be set based on the default system coordinates.
+    // when the surface is rotated, the input valus already were set with the rotated angle.
+    // So, re-calculation is needed.
+    if(mSurfaceOrientation == 90)
+    {
+      cx = mViewPort.height - (y + height);
+      cy = x;
+      cw = height;
+      ch = width;
+    }
+    else if(mSurfaceOrientation == 180)
+    {
+      cx = mViewPort.width - (x + width);
+      cy = mViewPort.height - (y + height);
+      cw = width;
+      ch = height;
+    }
+    else if(mSurfaceOrientation == 270)
+    {
+      cx = y;
+      cy = mViewPort.width - (x + width);
+      cw = height;
+      ch = width;
+    }
+    else
+    {
+      cx = x;
+      cy = y;
+      cw = width;
+      ch = height;
+    }
+
+    LOG_GL("Scissor %d %d %d %d\n", cx, cy, cw, ch);
+    CHECK_GL(mGlAbstraction, mGlAbstraction.Scissor(cx, cy, cw, ch));
   }
 
   /**
@@ -1682,7 +1769,7 @@ public:
   }
 
   /**
-   * Wrapper for OpenGL ES 3.0 glUnmapBubffer()
+   * Wrapper for OpenGL ES 3.0 glUnmapBuffer()
    */
   GLboolean UnmapBuffer(GLenum target)
   {
@@ -1690,27 +1777,54 @@ public:
     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.UnmapBuffer(target) );
     return val;
   }
+
   /**
    * Wrapper for OpenGL ES 2.0 glViewport()
    */
   void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
   {
     // check if its same as already set
-    Rect<int> newViewport( x, y, width, height );
+    GLsizei cw, ch;
+
+    // viewport's value shoud be set based on the default system size.
+    // when the surface is rotated, the input width and height already were swapped.
+    // So, re-swapping is needed.
+    if(mSurfaceOrientation == 90 || mSurfaceOrientation == 270)
+    {
+      cw = height;
+      ch = width;
+    }
+    else
+    {
+      cw = width;
+      ch = height;
+    }
+
+    // User uses the rotated viewport size.
+    Rect<int> newViewport(x, y, width, height);
 
     // Temporarily disable the viewport caching, as the implementation of GLES driver in Tizen platform
     // share a global viewport between multiple contexts, therefore glViewport has to be called every
     // time after glBindFramebuffer regardless of the same vewport size in the same context.
-//    if( mViewPort != newViewport )
+    //    if( mViewPort != newViewport )
     {
       // set new one
-      LOG_GL("Viewport %d %d %d %d\n", x, y, width, height);
-      CHECK_GL( mGlAbstraction, mGlAbstraction.Viewport(x, y, width, height) );
+      LOG_GL("Viewport %d %d %d %d\n", x, y, cw, ch);
+      CHECK_GL(mGlAbstraction, mGlAbstraction.Viewport(x, y, cw, ch));
       mViewPort = newViewport; // remember new one
     }
   }
 
   /**
+   * Wrapper for OpenGL ES 3.2 and GL_KHR_blend_equation_advanced extention glBlendBarrier()
+   */
+  void BlendBarrier()
+  {
+    LOG_GL( "BlendBarrier\n" );
+    CHECK_GL( mGlAbstraction, mGlAbstraction.BlendBarrier() );
+  }
+
+  /**
    * Get the implementation defined MAX_TEXTURE_SIZE. This values is cached when the context is created
    * @return The implementation defined MAX_TEXTURE_SIZE
    */
@@ -1719,6 +1833,12 @@ public:
     return mMaxTextureSize;
   }
 
+  void SetSurfaceOrientation(int orientation)
+  {
+    LOG_GL( "SetSurfaceOrientation: orientation: %d\n", orientation );
+    mSurfaceOrientation = orientation;
+  }
+
   /**
    * Get the current viewport.
    * @return Viewport rectangle.
@@ -1789,7 +1909,7 @@ private: // Data
 
   // glBindTexture() state
   TextureUnit mActiveTextureUnit;
-  GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ];  ///< The ID passed to glBindTexture()
+  GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ][MAX_TEXTURE_TARGET];  ///< The ID passed to glBindTexture()
 
   // glBlendColor() state
   Vector4 mBlendColor; ///< Blend color
@@ -1829,7 +1949,9 @@ private: // Data
 
   FrameBufferStateCache mFrameBufferStateCache;   ///< frame buffer state cache
 
-  std::vector< Context* >* mSceneContexts;      ///< The pointer of the container of contexts for surface rendering
+  OwnerContainer< Context* >* mSceneContexts;      ///< The pointer of the container of contexts for surface rendering
+
+  int mSurfaceOrientation;
 };
 
 } // namespace Internal