-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
// CLASS HEADER
#include <dali/internal/render/gl-resources/context.h>
// EXTERNAL INCLUDES
#include <algorithm>
-#include <limits>
+#include <cstring>
// INTERNAL INCLUDES
#include <dali/public-api/common/constants.h>
-#include <dali/internal/render/shaders/program.h>
+#include <dali/public-api/common/compile-time-assert.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>
+#include <dali/devel-api/rendering/texture-set.h>
namespace Dali
{
namespace // unnamed namespace
{
+DALI_COMPILE_TIME_ASSERT( TEXTURE_UNIT_LAST <= Context::MAX_TEXTURE_UNITS );
+
/**
* GL error strings
*/
{ 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)
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),
mBlendEquationSeparateModeRGB( GL_FUNC_ADD ),
mBlendEquationSeparateModeAlpha( GL_FUNC_ADD ),
mMaxTextureSize(0),
- mMaxTextureUnits(0),
mClearColor(Color::WHITE), // initial color, never used until it's been set by the user
- mCullFaceMode(CullNone),
- mViewPort( 0, 0, 0, 0 ),
- mCurrentProgram( NULL )
+ mCullFaceMode( Dali::Renderer::NONE ),
+ mViewPort( 0, 0, 0, 0 )
{
}
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;
}
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;
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 ) );
}
}
}
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
}
}
-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 = UNINITIALIZED_TEXTURE_UNIT;
+ 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);
-
- // 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 = Dali::Renderer::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( &mBound2dTextureId, 0, sizeof(mBound2dTextureId) );
+
+ 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"
"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