Remove RenderSurface from Core
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / context.cpp
index 6dc4384..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/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>
-
-using namespace std;
+#include <dali/internal/render/common/render-manager.h>
 
 namespace Dali
 {
@@ -40,6 +39,8 @@ namespace Internal
 namespace // unnamed namespace
 {
 
+static_assert( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS, "TEXTURE_UNIT_LAST is greater than Context::MAX_TEXTURE_UNITS" );
+
 /**
  * GL error strings
  */
@@ -57,89 +58,82 @@ 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;
-}
-
-const unsigned int UNINITIALIZED_TEXTURE_UNIT = std::numeric_limits<unsigned int>::max();// GL_MAX_TEXTURE_UNITS can't be used because it's depreciated in gles2
-
 } // 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_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( UNINITIALIZED_TEXTURE_UNIT ),
-  mUsingDefaultBlendColor(true),
+  mActiveTextureUnit( TEXTURE_UNIT_LAST ),
+  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),
-  mMaxTextureUnits(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 )
+  mSceneContexts( contexts )
 {
 }
 
 Context::~Context()
 {
-  // release the cached programs
-  std::for_each(mProgramCache.begin(), mProgramCache.end(), deletePrograms);
-  mProgramCache.clear();
 }
 
 void Context::GlContextCreated()
 {
+  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
+
   DALI_ASSERT_DEBUG(!mGlContextCreated);
 
   mGlContextCreated = true;
 
   // Set the initial GL state, and check it.
-  ResetGlState();
+  InitializeGlState();
 
-  const ProgramContainer::iterator endp = mProgramCache.end();
-  for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp )
-  {
-    (*itp).second->GlContextCreated();
-  }
+#ifdef DEBUG_ENABLED
+  PrintCurrentState();
+#endif
 }
 
 void Context::GlContextDestroyed()
 {
-  const ProgramContainer::iterator endp = mProgramCache.end();
-  for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp )
-  {
-    (*itp).second->GlContextDestroyed();
-  }
-
+  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
   mGlContextCreated = false;
 }
 
@@ -155,22 +149,6 @@ const char* Context::ErrorToString( GLenum errorCode )
   return "Unknown Open GLES error";
 }
 
-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;
@@ -190,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 ) );
       }
     }
   }
@@ -211,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
@@ -227,135 +205,66 @@ void Context::SetVertexAttributeLocation(unsigned int location, bool state)
   }
 }
 
-void Context::ResetVertexAttributeState()
-{
-  // 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()
+void Context::InitializeGlState()
 {
+  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_IMAGE;
 
-  mActiveTextureUnit = UNINITIALIZED_TEXTURE_UNIT;
-
-  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);
-
-  // get max texture units
-  mGlAbstraction.GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxTextureUnits);
-  DALI_ASSERT_DEBUG(mMaxTextureUnits > 7);  // according to GLES 2.0 specification
-  mBound2dTextureId.reserve(mMaxTextureUnits);
-  // rebind texture units
-  for( int i=0; i < mMaxTextureUnits; ++i )
-  {
-    mBound2dTextureId[ i ] = 0;
-    // set active texture
-    mGlAbstraction.ActiveTexture( GL_TEXTURE0 + i );
-    // bind the previous texture
-    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"
@@ -368,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