#define __DALI_INTERNAL_CONTEXT_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
*/
// INTERNAL INCLUDES
-#include <dali/public-api/actors/renderable-actor.h>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/math/rect.h>
#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/rendering/renderer.h>
#include <dali/integration-api/debug.h>
#include <dali/integration-api/gl-abstraction.h>
#include <dali/integration-api/gl-defines.h>
#include <dali/internal/render/common/performance-monitor.h>
#include <dali/internal/render/gl-resources/texture-units.h>
+#include <dali/internal/render/gl-resources/frame-buffer-state-cache.h>
#include <dali/internal/render/gl-resources/gl-call-debug.h>
namespace Dali
class Context
{
public:
+
+ /**
+ * FrameBuffer Clear mode
+ */
+ enum ClearMode
+ {
+ FORCE_CLEAR, ///< always perform the glClear regardless of current state
+ CHECK_CACHED_VALUES ///< check the Frame buffers cached state to see if a clear is required
+ };
+
/**
* Size of the VertexAttributeArray enables
* GLES specification states that there's minimum of 8
*/
void BindFramebuffer(GLenum target, GLuint framebuffer)
{
+ mFrameBufferStateCache.SetCurrentFrameBuffer( framebuffer );
+
LOG_GL("BindFramebuffer %d %d\n", target, framebuffer);
CHECK_GL( mGlAbstraction, mGlAbstraction.BindFramebuffer(target, framebuffer) );
}
LOG_GL("BindTexture GL_TEXTURE_2D %d\n", texture);
CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(GL_TEXTURE_2D, texture) );
+ }
+ }
+
+ /**
+ * Wrapper for OpenGL ES 2.0 glBindTexture( target )
+ */
+ void BindTexture( int target, GLuint texture )
+ {
+ if (mBound2dTextureId[ mActiveTextureUnit ] != texture)
+ {
+ mBound2dTextureId[ mActiveTextureUnit ] = texture;
- INCREASE_COUNTER(PerformanceMonitor::TEXTURE_STATE_CHANGES);
+ LOG_GL("BindTexture target(%d) %d\n", target, texture);
+ CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(target, texture) );
}
}
/**
+ * Wrapper for OpenGL ES 2.0 glBindTexture(GL_TEXTURE_CUBE_MAP)
+ */
+ void BindCubeMapTexture( GLuint texture )
+ {
+ LOG_GL("BindTexture GL_TEXTURE_CUBE_MAP %d\n", texture);
+ CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(GL_TEXTURE_CUBE_MAP, texture) );
+ }
+
+ /**
* Wrapper for OpenGL ES 2.0 glBlendColor()
*/
void SetDefaultBlendColor()
{
- if( !mUsingDefaultBlendColor )
+ if( ! mUsingDefaultBlendColor )
{
- LOG_GL( "BlendColor %f %f %f %f\n", 0.0f, 0.0f, 0.0f, 0.0f );
- CHECK_GL( mGlAbstraction, mGlAbstraction.BlendColor( 0.0f, 0.0f, 0.0f, 0.0f ) );
+ SetCustomBlendColor( Color::TRANSPARENT );
mUsingDefaultBlendColor = true;
}
}
*/
void SetCustomBlendColor( const Vector4& color )
{
- LOG_GL( "BlendColor %f %f %f %f\n", color.r, color.g, color.b, color.a );
- CHECK_GL( mGlAbstraction, mGlAbstraction.BlendColor(color.r, color.g, color.b, color.a) );
- mUsingDefaultBlendColor = false;
+ if( mUsingDefaultBlendColor || mBlendColor != color )
+ {
+ LOG_GL( "BlendColor %f %f %f %f\n", color.r, color.g, color.b, color.a );
+ CHECK_GL( mGlAbstraction, mGlAbstraction.BlendColor( color.r, color.g, color.b, color.a ) );
+ mUsingDefaultBlendColor = false;
+ mBlendColor = color;
+ }
}
/**
/**
* Wrapper for OpenGL ES 2.0 glClear()
*/
- void Clear(GLbitfield mask)
+ void Clear(GLbitfield mask, ClearMode mode )
{
- LOG_GL("Clear %d\n", mask);
- CHECK_GL( mGlAbstraction, mGlAbstraction.Clear(mask) );
+ bool forceClear = (mode == FORCE_CLEAR );
+ mask = mFrameBufferStateCache.GetClearMask( mask, forceClear , mScissorTestEnabled );
+
+ if( mask > 0 )
+ {
+ LOG_GL("Clear %d\n", mask);
+ CHECK_GL( mGlAbstraction, mGlAbstraction.Clear( mask ) );
+ }
}
/**
* enables GL_CULL_FACE if in any of the face culling modes
* otherwise disables GL_CULL_FACE
*/
- void CullFace(CullFaceMode mode)
+ void CullFace( Dali::FaceCullingMode::Type mode )
{
// Avoid unnecessary calls to gl
if(mCullFaceMode != mode)
mCullFaceMode = mode;
switch(mode)
{
- case CullNone:
+ case Dali::FaceCullingMode::NONE:
{
LOG_GL("Disable GL_CULL_FACE\n");
CHECK_GL( mGlAbstraction, mGlAbstraction.Disable(GL_CULL_FACE) );
break;
}
- case CullFront:
+ case Dali::FaceCullingMode::FRONT:
{
LOG_GL("Enable GL_CULL_FACE\n");
CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
break;
}
- case CullBack:
+ case Dali::FaceCullingMode::BACK:
{
LOG_GL("Enable GL_CULL_FACE\n");
CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
break;
}
- case CullFrontAndBack:
+ case Dali::FaceCullingMode::FRONT_AND_BACK:
{
LOG_GL("Enable GL_CULL_FACE\n");
CHECK_GL( mGlAbstraction, mGlAbstraction.Enable(GL_CULL_FACE) );
*/
void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
+ mFrameBufferStateCache.FrameBuffersDeleted( n, framebuffers );
+
LOG_GL("DeleteFramebuffers %d %p\n", n, framebuffers);
CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteFramebuffers(n, framebuffers) );
}
*/
void DepthFunc(GLenum func)
{
- LOG_GL("DepthFunc %x\n", func);
- CHECK_GL( mGlAbstraction, mGlAbstraction.DepthFunc(func) );
+ if( func != mDepthFunction )
+ {
+ mDepthFunction = func;
+ LOG_GL("DepthFunc %x\n", func);
+ CHECK_GL( mGlAbstraction, mGlAbstraction.DepthFunc(func) );
+ }
}
/**
*/
void DrawArrays(GLenum mode, GLint first, GLsizei count)
{
+ mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
FlushVertexAttributeLocations();
LOG_GL("DrawArrays %x %d %d\n", mode, first, count);
*/
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{
+ mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
FlushVertexAttributeLocations();
LOG_GL("DrawArraysInstanced %x %d %d %d\n", mode, first, count, instanceCount);
*/
void DrawBuffers(GLsizei n, const GLenum* bufs)
{
+ mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
LOG_GL("DrawBuffers %d %p\n", n, bufs);
CHECK_GL( mGlAbstraction, mGlAbstraction.DrawBuffers(n, bufs) );
}
*/
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
{
+ mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
+
FlushVertexAttributeLocations();
LOG_GL("DrawElements %x %d %d %p\n", mode, count, type, indices);
*/
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instanceCount)
{
+ mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
+
FlushVertexAttributeLocations();
LOG_GL("DrawElementsInstanced %x %d %d %p %d\n", mode, count, type, indices, instanceCount);
*/
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices)
{
+ mFrameBufferStateCache.DrawOperation( mColorMask, DepthBufferWriteEnabled(), StencilBufferWriteEnabled() );
FlushVertexAttributeLocations();
LOG_GL("DrawRangeElements %x %u %u %d %d %p\n", mode, start, end, count, type, indices);
/**
* This method replaces glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST).
+ * Note GL_DEPTH_TEST means enable the depth buffer for writing and or testing.
+ * glDepthMask is used to enable / disable writing to depth buffer.
+ * glDepthFunc us used to control if testing is enabled and how it is performed ( default GL_LESS)
+ *
* @param[in] enable True if GL_DEPTH_TEST should be enabled.
*/
- void SetDepthTest(bool enable)
+ void EnableDepthBuffer( bool enable )
{
// Avoid unecessary calls to glEnable/glDisable
- if (enable != mDepthTestEnabled)
+ if( enable != mDepthBufferEnabled )
{
- mDepthTestEnabled = enable;
+ mDepthBufferEnabled = enable;
if (enable)
{
/**
* This method replaces glEnable(GL_STENCIL_TEST) and glDisable(GL_STENCIL_TEST).
+ * Note GL_STENCIL_TEST means enable the stencil buffer for writing and or testing.
+ * glStencilMask is used to control how bits are written to the stencil buffer.
+ * glStencilFunc is used to control if testing is enabled and how it is performed ( default GL_ALWAYS )
* @param[in] enable True if GL_STENCIL_TEST should be enabled.
*/
- void SetStencilTest(bool enable)
+ void EnableStencilBuffer(bool enable)
{
// Avoid unecessary calls to glEnable/glDisable
- if (enable != mStencilTestEnabled)
+ if( enable != mStencilBufferEnabled )
{
- mStencilTestEnabled = enable;
+ mStencilBufferEnabled = enable;
if (enable)
{
{
LOG_GL("GenFramebuffers %d %p\n", n, framebuffers);
CHECK_GL( mGlAbstraction, mGlAbstraction.GenFramebuffers(n, framebuffers) );
+
+ mFrameBufferStateCache.FrameBuffersCreated( n, framebuffers );
}
/**
*/
void StencilFunc(GLenum func, GLint ref, GLuint mask)
{
+
+
LOG_GL("StencilFunc %x %d %d\n", func, ref, mask);
CHECK_GL( mGlAbstraction, mGlAbstraction.StencilFunc(func, ref, mask) );
}
*/
const Rect< int >& GetViewport();
- /**
- * Set the frame count of render thread
- */
- inline void SetFrameCount(unsigned int frameCount)
- {
- mFrameCount = frameCount;
- }
-
- /**
- * Get the frame count
- */
- inline unsigned int GetFrameCount()
- {
- return mFrameCount;
- }
-
- /**
- * Increment the count of culled renderers
- */
- inline void IncrementCulledCount()
- {
- mCulledCount++;
- }
-
- /**
- * Clear the count of culled renderers
- */
- inline void ClearCulledCount()
- {
- mCulledCount = 0;
- }
-
- /**
- * Get the count of culled renderers in this frame
- */
- inline unsigned int GetCulledCount()
- {
- return mCulledCount;
- }
-
- /**
- * Increment the count of culled renderers
- */
- inline void IncrementRendererCount()
- {
- mRendererCount++;
- }
+private: // Implementation
/**
- * Clear the count of image renderers
+ * @return true if next draw operation will write to depth buffer
*/
- inline void ClearRendererCount()
+ bool DepthBufferWriteEnabled() const
{
- mRendererCount = 0;
+ return mDepthBufferEnabled && mDepthMaskEnabled;
}
/**
- * Get the count of image renderers in this frame
+ * @return true if next draw operation will write to stencil buffer
*/
- inline unsigned int GetRendererCount()
+ bool StencilBufferWriteEnabled() const
{
- return mRendererCount;
+ return mStencilBufferEnabled && ( mStencilMask > 0 );
}
-
-private: // Implementation
-
/**
* Flushes vertex attribute location changes to the driver
*/
void FlushVertexAttributeLocations();
/**
- * Reset the cached internal vertex attribute state
- */
- void ResetVertexAttributeState();
-
- /**
* Either enables or disables a vertex attribute location in the cache
* The cahnges won't take affect until FlushVertexAttributeLocations is called
* @param location attribute location
/**
* Sets the initial GL state.
*/
- void ResetGlState();
+ void InitializeGlState();
private: // Data
bool mColorMask;
GLuint mStencilMask;
bool mBlendEnabled;
- bool mDepthTestEnabled;
+ bool mDepthBufferEnabled;
bool mDepthMaskEnabled;
bool mDitherEnabled;
bool mPolygonOffsetFillEnabled;
bool mSampleAlphaToCoverageEnabled;
bool mSampleCoverageEnabled;
bool mScissorTestEnabled;
- bool mStencilTestEnabled;
+ bool mStencilBufferEnabled;
bool mClearColorSet;
+ bool mUsingDefaultBlendColor;
// glBindBuffer() state
GLuint mBoundArrayBufferId; ///< The ID passed to glBindBuffer(GL_ARRAY_BUFFER)
GLuint mBound2dTextureId[ MAX_TEXTURE_UNITS ]; ///< The ID passed to glBindTexture(GL_TEXTURE_2D)
// glBlendColor() state
- bool mUsingDefaultBlendColor;
+ Vector4 mBlendColor; ///< Blend color
// glBlendFuncSeparate() state
GLenum mBlendFuncSeparateSrcRGB; ///< The srcRGB parameter passed to glBlendFuncSeparate()
GLenum mBlendEquationSeparateModeRGB; ///< Controls RGB blend mode
GLenum mBlendEquationSeparateModeAlpha; ///< Controls Alpha blend mode
+ GLenum mDepthFunction; ///The depth function
+
GLint mMaxTextureSize; ///< return value from GetIntegerv(GL_MAX_TEXTURE_SIZE)
Vector4 mClearColor; ///< clear color
// Face culling mode
- CullFaceMode mCullFaceMode;
+ Dali::FaceCullingMode::Type mCullFaceMode;
// cached viewport size
Rect< int > mViewPort;
bool mVertexAttributeCachedState[ MAX_ATTRIBUTE_CACHE_SIZE ]; ///< Value cache for Enable Vertex Attribute
bool mVertexAttributeCurrentState[ MAX_ATTRIBUTE_CACHE_SIZE ]; ///< Current state on the driver for Enable Vertex Attribute
- unsigned int mFrameCount; ///< Number of render frames
- unsigned int mCulledCount; ///< Number of culled renderers per frame
- unsigned int mRendererCount; ///< Number of image renderers per frame
+ FrameBufferStateCache mFrameBufferStateCache; ///< frame buffer state cache
};
} // namespace Internal