Remove RenderSurface from Core
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / context.cpp
index 5138ca3..ead1be3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 // EXTERNAL INCLUDES
 #include <algorithm>
-#include <limits>
+#include <cstring>
+#include <type_traits>
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/constants.h>
-#include <dali/public-api/common/compile-time-assert.h>
-#include <dali/internal/render/shaders/program.h>
+#include <dali/public-api/rendering/texture-set.h>
 #include <dali/integration-api/platform-abstraction.h>
-#include <dali/internal/render/common/render-manager.h>
 #include <dali/integration-api/debug.h>
+#include <dali/internal/render/common/render-manager.h>
 
 namespace Dali
 {
@@ -39,7 +39,7 @@ namespace Internal
 namespace // unnamed namespace
 {
 
-DALI_COMPILE_TIME_ASSERT( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS );
+static_assert( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS, "TEXTURE_UNIT_LAST is greater than Context::MAX_TEXTURE_UNITS" );
 
 /**
  * GL error strings
@@ -58,64 +58,61 @@ errorStrings errors[] =
    { GL_OUT_OF_MEMORY,      "GL_OUT_OF_MEMORY" }
 };
 
-/*
- * Called by std::for_each from ~Context
- */
-void deletePrograms(std::pair< std::size_t, Program* > hashProgram)
-{
-  DALI_ASSERT_DEBUG( hashProgram.second );
-  delete hashProgram.second;
-}
-
 } // unnamed namespace
 
 #ifdef DEBUG_ENABLED
-Debug::Filter* Context::gGlLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT");
-Debug::Filter* gContextLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT_META");
+Debug::Filter* gContextLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT_STATE");
 #endif
 
-Context::Context(Integration::GlAbstraction& glAbstraction)
+Context::Context( Integration::GlAbstraction& glAbstraction )
+: Context( glAbstraction, nullptr )
+{
+}
+
+Context::Context( Integration::GlAbstraction& glAbstraction, std::vector< Context* >* contexts )
 : mGlAbstraction(glAbstraction),
   mGlContextCreated(false),
   mColorMask(true),
   mStencilMask(0xFF),
   mBlendEnabled(false),
-  mDepthTestEnabled(false),
+  mDepthBufferEnabled(false),
   mDepthMaskEnabled(false),
   mDitherEnabled(true), // This the only GL capability which defaults to true
   mPolygonOffsetFillEnabled(false),
   mSampleAlphaToCoverageEnabled(false),
   mSampleCoverageEnabled(false),
   mScissorTestEnabled(false),
-  mStencilTestEnabled(false),
+  mStencilBufferEnabled(false),
   mClearColorSet(false),
+  mUsingDefaultBlendColor(true),
   mBoundArrayBufferId(0),
   mBoundElementArrayBufferId(0),
   mBoundTransformFeedbackBufferId(0),
   mActiveTextureUnit( TEXTURE_UNIT_LAST ),
-  mUsingDefaultBlendColor(true),
+  mBlendColor(Color::TRANSPARENT),
   mBlendFuncSeparateSrcRGB(GL_ONE),
   mBlendFuncSeparateDstRGB(GL_ZERO),
   mBlendFuncSeparateSrcAlpha(GL_ONE),
   mBlendFuncSeparateDstAlpha(GL_ZERO),
   mBlendEquationSeparateModeRGB( GL_FUNC_ADD ),
   mBlendEquationSeparateModeAlpha( GL_FUNC_ADD ),
+  mStencilFunc( GL_ALWAYS ),
+  mStencilFuncRef( 0 ),
+  mStencilFuncMask( 0xFFFFFFFF ),
+  mStencilOpFail( GL_KEEP ),
+  mStencilOpDepthFail( GL_KEEP ),
+  mStencilOpDepthPass( GL_KEEP ),
+  mDepthFunction( GL_LESS ),
   mMaxTextureSize(0),
   mClearColor(Color::WHITE),    // initial color, never used until it's been set by the user
-  mCullFaceMode(CullNone),
+  mCullFaceMode( FaceCullingMode::NONE ),
   mViewPort( 0, 0, 0, 0 ),
-  mCurrentProgram( NULL ),
-  mFrameCount( 0 ),
-  mCulledCount( 0 ),
-  mRendererCount( 0 )
+  mSceneContexts( contexts )
 {
 }
 
 Context::~Context()
 {
-  // release the cached programs
-  std::for_each(mProgramCache.begin(), mProgramCache.end(), deletePrograms);
-  mProgramCache.clear();
 }
 
 void Context::GlContextCreated()
@@ -127,22 +124,16 @@ void Context::GlContextCreated()
   mGlContextCreated = true;
 
   // Set the initial GL state, and check it.
-  ResetGlState();
+  InitializeGlState();
 
-  // Programs now load on demand
+#ifdef DEBUG_ENABLED
+  PrintCurrentState();
+#endif
 }
 
 void Context::GlContextDestroyed()
 {
   DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
-  SetCurrentProgram( NULL );
-  // Inform programs they are no longer valid
-  const ProgramContainer::iterator endp = mProgramCache.end();
-  for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp )
-  {
-    (*itp).second->GlContextDestroyed();
-  }
-
   mGlContextCreated = false;
 }
 
@@ -158,32 +149,6 @@ const char* Context::ErrorToString( GLenum errorCode )
   return "Unknown Open GLES error";
 }
 
-void Context::ResetProgramMatrices()
-{
-  const ProgramContainer::iterator endp = mProgramCache.end();
-  for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp )
-  {
-    (*itp).second->SetProjectionMatrix( NULL );
-    (*itp).second->SetViewMatrix( NULL );
-  }
-}
-
-Program* Context::GetCachedProgram( std::size_t hash ) const
-{
-  std::map< std::size_t, Program* >::const_iterator iter = mProgramCache.find(hash);
-
-  if (iter != mProgramCache.end())
-  {
-     return iter->second;
-  }
-  return NULL;
-}
-
-void Context::CacheProgram( std::size_t hash, Program* pointer )
-{
-  mProgramCache[ hash ] = pointer;
-}
-
 const Rect< int >& Context::GetViewport()
 {
   return mViewPort;
@@ -203,12 +168,12 @@ void Context::FlushVertexAttributeLocations()
       if (mVertexAttributeCurrentState[ i ] )
       {
         LOG_GL("EnableVertexAttribArray %d\n", i);
-        CHECK_GL( *this, mGlAbstraction.EnableVertexAttribArray( i ) );
+        CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( i ) );
       }
       else
       {
         LOG_GL("DisableVertexAttribArray %d\n", i);
-        CHECK_GL( *this, mGlAbstraction.DisableVertexAttribArray( i ) );
+        CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( i ) );
       }
     }
   }
@@ -224,12 +189,12 @@ void Context::SetVertexAttributeLocation(unsigned int location, bool state)
     if ( state )
     {
        LOG_GL("EnableVertexAttribArray %d\n", location);
-       CHECK_GL( *this, mGlAbstraction.EnableVertexAttribArray( location ) );
+       CHECK_GL( mGlAbstraction, mGlAbstraction.EnableVertexAttribArray( location ) );
     }
     else
     {
       LOG_GL("DisableVertexAttribArray %d\n", location);
-      CHECK_GL( *this, mGlAbstraction.DisableVertexAttribArray( location ) );
+      CHECK_GL( mGlAbstraction, mGlAbstraction.DisableVertexAttribArray( location ) );
     }
   }
   else
@@ -240,131 +205,66 @@ void Context::SetVertexAttributeLocation(unsigned int location, bool state)
   }
 }
 
-void Context::ResetVertexAttributeState()
+void Context::InitializeGlState()
 {
-  // reset attribute cache
-  for( unsigned int i=0; i < MAX_ATTRIBUTE_CACHE_SIZE; ++i )
-  {
-    mVertexAttributeCachedState[ i ] = false;
-    mVertexAttributeCurrentState[ i ] = false;
-
-    LOG_GL("DisableVertexAttribArray %d\n", i);
-    CHECK_GL( *this, mGlAbstraction.DisableVertexAttribArray( i ) );
-  }
-}
-
-void Context::ResetGlState()
-{
-  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::ResetGlState()\n");
+  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::InitializeGlState()\n");
   DALI_ASSERT_DEBUG(mGlContextCreated);
 
   mClearColorSet = false;
-  // Render manager will call clear in next render
-
-  // Reset internal state and Synchronize it with real OpenGL context.
-  // This may seem like overkill, but the GL context is not owned by dali-core,
-  // and no assumptions should be made about the initial state.
   mColorMask = true;
-  mGlAbstraction.ColorMask( true, true, true, true );
-
   mStencilMask = 0xFF;
-  mGlAbstraction.StencilMask( 0xFF );
-
   mBlendEnabled = false;
-  mGlAbstraction.Disable(GL_BLEND);
-
-  mDepthTestEnabled = false;
-  mGlAbstraction.Disable(GL_DEPTH_TEST);
-
+  mDepthBufferEnabled = false;
   mDepthMaskEnabled = false;
-  mGlAbstraction.DepthMask(GL_FALSE);
-
-  mDitherEnabled = false; // This the only GL capability which defaults to true
-  mGlAbstraction.Disable(GL_DITHER);
-
   mPolygonOffsetFillEnabled = false;
-  mGlAbstraction.Disable(GL_POLYGON_OFFSET_FILL);
-
   mSampleAlphaToCoverageEnabled = false;
-  mGlAbstraction.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
-
   mSampleCoverageEnabled = false;
-  mGlAbstraction.Disable(GL_SAMPLE_COVERAGE);
-
   mScissorTestEnabled = false;
-  mGlAbstraction.Disable(GL_SCISSOR_TEST);
-
-  mStencilTestEnabled = false;
-  mGlAbstraction.Disable(GL_STENCIL_TEST);
+  mStencilBufferEnabled = false;
+  mDitherEnabled = false; // This and GL_MULTISAMPLE are the only GL capability which defaults to true
+  mGlAbstraction.Disable(GL_DITHER);
 
   mBoundArrayBufferId = 0;
-  LOG_GL("BindBuffer GL_ARRAY_BUFFER 0\n");
-  mGlAbstraction.BindBuffer(GL_ARRAY_BUFFER, mBoundArrayBufferId);
-
   mBoundElementArrayBufferId = 0;
-  LOG_GL("BindBuffer GL_ELEMENT_ARRAY_BUFFER 0\n");
-  mGlAbstraction.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBoundElementArrayBufferId);
-
-#ifndef EMSCRIPTEN // not in WebGL
   mBoundTransformFeedbackBufferId = 0;
-  LOG_GL("BindBuffer GL_TRANSFORM_FEEDBACK_BUFFER 0\n");
-  mGlAbstraction.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mBoundTransformFeedbackBufferId);
-#endif
-
-  mActiveTextureUnit = TEXTURE_UNIT_LAST;
+  mActiveTextureUnit = TEXTURE_UNIT_IMAGE;
 
-  mUsingDefaultBlendColor = true;
-  mGlAbstraction.BlendColor( 0.0f, 0.0f, 0.0f, 0.0f );
+  mUsingDefaultBlendColor = true; //Default blend color is (0,0,0,0)
 
   mBlendFuncSeparateSrcRGB = GL_ONE;
   mBlendFuncSeparateDstRGB = GL_ZERO;
   mBlendFuncSeparateSrcAlpha = GL_ONE;
   mBlendFuncSeparateDstAlpha = GL_ZERO;
-  mGlAbstraction.BlendFuncSeparate( mBlendFuncSeparateSrcRGB, mBlendFuncSeparateDstRGB,
-                                    mBlendFuncSeparateSrcAlpha, mBlendFuncSeparateDstAlpha );
 
   // initial state is GL_FUNC_ADD for both RGB and Alpha blend modes
   mBlendEquationSeparateModeRGB = GL_FUNC_ADD;
   mBlendEquationSeparateModeAlpha = GL_FUNC_ADD;
-  mGlAbstraction.BlendEquationSeparate( mBlendEquationSeparateModeRGB, mBlendEquationSeparateModeAlpha);
 
-  mCullFaceMode = CullNone;
-  mGlAbstraction.Disable(GL_CULL_FACE);
-  mGlAbstraction.FrontFace(GL_CCW);
-  mGlAbstraction.CullFace(GL_BACK);
-
-  // rebind texture units to 0
-  for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
-  {
-    mBound2dTextureId[ i ] = 0;
-    // set active texture
-    mGlAbstraction.ActiveTexture( GL_TEXTURE0 + i );
-    mGlAbstraction.BindTexture(GL_TEXTURE_2D, mBound2dTextureId[ i ] );
-  }
+  mCullFaceMode = FaceCullingMode::NONE; //By default cullface is disabled, front face is set to CCW and cull face is set to back
 
   // get maximum texture size
   mGlAbstraction.GetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
 
-  GLint numProgramBinaryFormats;
-  mGlAbstraction.GetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &numProgramBinaryFormats);
-  if( GL_NO_ERROR == mGlAbstraction.GetError() && 0 != numProgramBinaryFormats )
-  {
-    mProgramBinaryFormats.Resize(numProgramBinaryFormats);
-    mGlAbstraction.GetIntegerv(GL_PROGRAM_BINARY_FORMATS_OES, &mProgramBinaryFormats[0]);
-  }
-
   // reset viewport, this will be set to something useful when rendering
   mViewPort.x = mViewPort.y = mViewPort.width = mViewPort.height = 0;
 
-  ResetVertexAttributeState();
+  //Initialze vertex attribute cache
+  memset( &mVertexAttributeCachedState, 0, sizeof(mVertexAttributeCachedState) );
+  memset( &mVertexAttributeCurrentState, 0, sizeof(mVertexAttributeCurrentState) );
+
+  //Initialize bound 2d texture cache
+  memset( &mBoundTextureId, 0, sizeof(mBoundTextureId) );
+
+  mFrameBufferStateCache.Reset();
 }
 
-#ifdef DALI_CONTEXT_LOGGING
+#ifdef DEBUG_ENABLED
 
 void Context::PrintCurrentState()
 {
-  DALI_LOG_INFO(SceneGraph::Context::gGlLogFilter, Debug::General,
-                "----------------- Context State BEGIN -----------------\n"
+  const char* cullFaceModes[] = { "CullNone", "CullFront", "CullBack", "CullFrontAndBack" };
+  DALI_LOG_INFO( gContextLogFilter, Debug::General,
+                "\n----------------- Context State BEGIN -----------------\n"
                 "Blend = %s\n"
                 "Cull Face = %s\n"
                 "Depth Test = %s\n"
@@ -377,14 +277,15 @@ void Context::PrintCurrentState()
                 "Stencil Test = %s\n"
                 "----------------- Context State END -----------------\n",
                 mBlendEnabled ? "Enabled" : "Disabled",
-                mDepthTestEnabled ? "Enabled" : "Disabled",
+                cullFaceModes[ mCullFaceMode ],
+                mDepthBufferEnabled ? "Enabled" : "Disabled",
                 mDepthMaskEnabled ? "Enabled" : "Disabled",
                 mDitherEnabled ? "Enabled" : "Disabled",
                 mPolygonOffsetFillEnabled ? "Enabled" : "Disabled",
                 mSampleAlphaToCoverageEnabled ? "Enabled" : "Disabled",
                 mSampleCoverageEnabled ? "Enabled" : "Disabled",
                 mScissorTestEnabled ? "Enabled" : "Disabled",
-                mStencilTestEnabled ? "Enabled" : "Disabled");
+                mStencilBufferEnabled ? "Enabled" : "Disabled");
 }
 
 #endif // DALI_CONTEXT_LOGGING