utc-Dali-Internal-FixedSizeMemoryPool.cpp
utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
utc-Dali-Internal-FrustumCulling.cpp
- utc-Dali-Internal-GeometryBatcher.cpp
)
LIST(APPEND TC_SOURCES
+++ /dev/null
-#include <dali/public-api/dali-core.h>
-#include <dali/devel-api/actors/actor-devel.h>
-#include <dali/devel-api/rendering/renderer-devel.h>
-#include <dali/internal/event/actors/actor-impl.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
-
-#include <dali-test-suite-utils.h>
-
-namespace
-{
-
-class MockActor : public Dali::Internal::Actor
-{
-public:
- inline const Dali::Internal::SceneGraph::Node* GetNode()
- {
- return mNode;
- }
-
- inline const bool IsNodeBatchParent()
- {
- return mNode->mIsBatchParent;
- }
-};
-
-Geometry CreateBatchQuadGeometryVector2( Vector4 texCoords )
-{
- const float halfWidth = 0.5f;
- const float halfHeight = 0.5f;
- struct QuadVertex {
- QuadVertex( const Vector2& vertexPosition, const Vector2& vertexTexCoords )
- : position( vertexPosition ),
- texCoords( vertexTexCoords )
- {}
- Vector2 position;
- Vector2 texCoords;
- };
-
- // special case, when texture takes whole space
- if( texCoords == Vector4::ZERO )
- {
- texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
- }
-
- QuadVertex quadVertexData[6] =
- {
- QuadVertex( Vector2(-halfWidth, -halfHeight ), Vector2(texCoords.x, texCoords.y) ),
- QuadVertex( Vector2( halfWidth, -halfHeight ), Vector2(texCoords.z, texCoords.y) ),
- QuadVertex( Vector2(-halfWidth, halfHeight ), Vector2(texCoords.x, texCoords.w) ),
- QuadVertex( Vector2( halfWidth, -halfHeight ), Vector2(texCoords.z, texCoords.y) ),
- QuadVertex( Vector2(-halfWidth, halfHeight ), Vector2(texCoords.x, texCoords.w) ),
- QuadVertex( Vector2( halfWidth, halfHeight ), Vector2(texCoords.z, texCoords.w) ),
- };
-
- Property::Map vertexFormat;
- vertexFormat[ "aPosition" ] = Property::VECTOR2;
- vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
- PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
- vertexBuffer.SetData( quadVertexData, 6 );
-
- // create geometry as normal, single quad
- Geometry geometry = Geometry::New();
- geometry.AddVertexBuffer( vertexBuffer );
- geometry.SetType( Geometry::TRIANGLES );
-
- return geometry;
-}
-
-Geometry CreateBatchQuadGeometryVector3( Vector4 texCoords )
-{
- const float halfWidth = 0.5f;
- const float halfHeight = 0.5f;
- struct QuadVertex {
- QuadVertex( const Vector3& vertexPosition, const Vector2& vertexTexCoords )
- : position( vertexPosition ),
- texCoords( vertexTexCoords )
- {}
- Vector3 position;
- Vector2 texCoords;
- };
-
- // special case, when texture takes whole space
- if( texCoords == Vector4::ZERO )
- {
- texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
- }
-
- QuadVertex quadVertexData[6] =
- {
- QuadVertex( Vector3(-halfWidth, -halfHeight, 0.0f ), Vector2(texCoords.x, texCoords.y) ),
- QuadVertex( Vector3( halfWidth, -halfHeight, 0.0f ), Vector2(texCoords.z, texCoords.y) ),
- QuadVertex( Vector3(-halfWidth, halfHeight, 0.0f ), Vector2(texCoords.x, texCoords.w) ),
- QuadVertex( Vector3( halfWidth, -halfHeight, 0.0f ), Vector2(texCoords.z, texCoords.y) ),
- QuadVertex( Vector3(-halfWidth, halfHeight, 0.0f ), Vector2(texCoords.x, texCoords.w) ),
- QuadVertex( Vector3( halfWidth, halfHeight, 0.0f ), Vector2(texCoords.z, texCoords.w) ),
- };
-
- Property::Map vertexFormat;
- vertexFormat[ "aPosition" ] = Property::VECTOR3;
- vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
- PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
- vertexBuffer.SetData( quadVertexData, 6 );
-
- // create geometry as normal, single quad
- Geometry geometry = Geometry::New();
- geometry.AddVertexBuffer( vertexBuffer );
- geometry.SetType( Geometry::TRIANGLES );
- return geometry;
-}
-
-Geometry CreateBatchQuadGeometryVector4( Vector4 texCoords )
-{
- const float halfWidth = 0.5f;
- const float halfHeight = 0.5f;
- struct QuadVertex {
- QuadVertex( const Vector4& vertexPosition, const Vector2& vertexTexCoords )
- : position( vertexPosition ),
- texCoords( vertexTexCoords )
- {}
- Vector4 position;
- Vector2 texCoords;
- };
-
- // special case, when texture takes whole space
- if( texCoords == Vector4::ZERO )
- {
- texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
- }
-
- QuadVertex quadVertexData[6] =
- {
- QuadVertex( Vector4(-halfWidth, -halfHeight, 0.0f, 1.0f ), Vector2(texCoords.x, texCoords.y) ),
- QuadVertex( Vector4( halfWidth, -halfHeight, 0.0f, 1.0f ), Vector2(texCoords.z, texCoords.y) ),
- QuadVertex( Vector4(-halfWidth, halfHeight, 0.0f, 1.0f ), Vector2(texCoords.x, texCoords.w) ),
- QuadVertex( Vector4( halfWidth, -halfHeight, 0.0f, 1.0f ), Vector2(texCoords.z, texCoords.y) ),
- QuadVertex( Vector4(-halfWidth, halfHeight, 0.0f, 1.0f ), Vector2(texCoords.x, texCoords.w) ),
- QuadVertex( Vector4( halfWidth, halfHeight, 0.0f, 1.0f ), Vector2(texCoords.z, texCoords.w) ),
- };
-
- Property::Map vertexFormat;
- vertexFormat[ "aPosition" ] = Property::VECTOR4;
- vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
- PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
- vertexBuffer.SetData( quadVertexData, 6 );
-
- // create geometry as normal, single quad
- Geometry geometry = Geometry::New();
- geometry.AddVertexBuffer( vertexBuffer );
- geometry.SetType( Geometry::TRIANGLES );
- return geometry;
-}
-
-
-void CreateShadersAndTextureSets( Shader* shaders, size_t shaderCount, TextureSet* textureSets, size_t textureSetCount )
-{
- for( size_t i = 0; i < shaderCount; ++i )
- {
- shaders[i] = Shader::New( "", "" );
- }
-
- for( size_t i = 0; i < textureSetCount; ++i )
- {
- textureSets[i] = TextureSet::New();
- }
-}
-
-Vector4 WHOLE_IMAGE( 0.0f, 0.0f, 1.0f, 1.0f );
-
-Actor CreateActor( Actor& parent, Shader& shader, TextureSet& textureSet, Vector3 position, Vector4 texCoords, Geometry(*geomfunc)(Vector4) = CreateBatchQuadGeometryVector2 )
-{
- Geometry geometry = geomfunc( texCoords );
- Renderer renderer = Renderer::New( geometry, shader );
-
- renderer.SetTextures( textureSet );
- renderer.SetProperty( Dali::DevelRenderer::Property::BATCHING_ENABLED, true );
-
- Actor actor = Actor::New();
- actor.SetPosition( position );
- parent.Add( actor );
- actor.AddRenderer( renderer );
- return actor;
-}
-
-Actor CreateBatchParent( Vector3 pos )
-{
- Actor actor = Actor::New();
- actor.SetProperty( DevelActor::Property::BATCH_PARENT, true );
- actor.SetPosition( pos );
- Stage::GetCurrent().Add( actor );
- return actor;
-}
-
-} // namespace
-
-int UtcDaliGeometryBatcherBatchLevel0(void)
-{
- TestApplication app;
- TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
- glAbstraction.EnableDrawCallTrace( true );
- TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
-
- Shader shaders[1];
- TextureSet textureSets[1];
-
- CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
- Actor batchParent = CreateBatchParent( Vector3::ZERO );
- batchParent.SetSize( Stage::GetCurrent().GetSize() );
-
- Actor children[] = {
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE )
- };
-
- app.SendNotification();
- app.Render( 16 );
- app.SendNotification();
- app.Render( 16 );
-
- // should be 1 draw call
- {
- int result = drawTrace.CountMethod( "DrawElements");
- DALI_TEST_CHECK( result == 1 );
- }
-
- // remove actor
- batchParent.Remove( children[0] );
- children[0].Reset();
-
- // update
- app.SendNotification();
- app.Render( 16 );
-
- // test geometry for that batch, 1 batch, 3 children, 18 elements in the buffer
- //Dali::Internal::Actor& actor = GetImplementation( children[1] );
- MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
- Dali::Internal::SceneGraph::GeometryBatcher* geometryBatcher = mockActor->GetNode()->mGeometryBatcher;
- DALI_TEST_CHECK( geometryBatcher ); // must not be NULL
-
- Dali::Internal::Render::Geometry* geometry = geometryBatcher->GetGeometry( 0 );
- int elementCount = geometry->GetPropertyBuffer(0)->GetElementCount();
- DALI_TEST_CHECK( elementCount == 18 );
-
- // delete batch parent
- Stage::GetCurrent().Remove( batchParent );
- batchParent.Reset();
-
- // update
- app.SendNotification();
- app.Render( 16 );
-
- END_TEST;
-}
-
-int UtcDaliGeometryBatcherBatchMultipleTextureSet(void)
-{
- TestApplication app;
- TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
- glAbstraction.EnableDrawCallTrace( true );
- TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
-
- Shader shaders[1];
- TextureSet textureSets[3];
- CreateShadersAndTextureSets( shaders, 1, textureSets, 3 );
-
- Actor batchParent = CreateBatchParent( Vector3::ZERO );
- batchParent.SetSize( Stage::GetCurrent().GetSize() );
-
- Actor children[] = {
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
- CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE )
- };
-
- // must update twice
- app.SendNotification();
- app.Render( 16 );
- app.SendNotification();
- app.Render( 16 );
-
- // should be 3 draw calls here
- {
- int result = drawTrace.CountMethod( "DrawElements");
- DALI_TEST_CHECK( result == 3 );
- }
-
- // test assigned indices
- {
- bool indicesTest( true );
- for( size_t i = 0; i < 12; ++i )
- {
- MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
- if( mockActor->GetNode()->mBatchIndex == BATCH_NULL_HANDLE )
- {
- indicesTest = false;
- }
- }
- DALI_TEST_CHECK( indicesTest );
- }
-
- END_TEST;
-}
-
-int UtcDaliGeometryBatcherSettingBatchParent(void)
-{
- TestApplication app;
-
- Shader shaders[1];
- TextureSet textureSets[1];
- CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
-
- Actor batchParent = CreateBatchParent( Vector3::ZERO );
- batchParent.SetSize( Stage::GetCurrent().GetSize() );
- app.SendNotification();
- app.Render( 16 );
-
- MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( batchParent ) );
- DALI_TEST_CHECK( mockActor->IsNodeBatchParent() );
-
- END_TEST;
-}
-
-int UtcDaliGeometryBatcherBatchMultipleParents(void)
-{
- TestApplication app;
- TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
- glAbstraction.EnableDrawCallTrace( true );
- TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
-
- Shader shaders[2];
- TextureSet textureSets[2];
- CreateShadersAndTextureSets( shaders, 2, textureSets, 2 );
-
- Actor batchParent0 = CreateBatchParent( Vector3::ZERO ); // Vector2
- batchParent0.SetSize( Stage::GetCurrent().GetSize() );
- Actor batchParent1 = CreateBatchParent( Vector3::ZERO ); // Vector3
- batchParent1.SetSize( Stage::GetCurrent().GetSize() );
- Actor batchParent2 = CreateBatchParent( Vector3::ZERO ); // Vector4
- batchParent2.SetSize( Stage::GetCurrent().GetSize() );
-
- CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
- CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
- CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
- CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
- CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
- CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
- CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
- CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
- CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
- CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
- CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
- CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
-
- // must update twice
- app.SendNotification();
- app.Render( 16 );
- app.SendNotification();
- app.Render( 16 );
-
- // should be 3 draw calls here
- {
- int result = drawTrace.CountMethod( "DrawElements");
- DALI_TEST_EQUALS( result, 3, TEST_LOCATION );
- }
-
- // delete batch parent
- Stage::GetCurrent().Remove( batchParent1 );
- batchParent1.Reset();
- drawTrace.Reset();
- app.SendNotification();
- app.Render( 16 );
- // should be 2 draw calls here
- {
- int result = drawTrace.CountMethod( "DrawElements");
- DALI_TEST_EQUALS( result, 2, TEST_LOCATION );
- }
-
- END_TEST;
-}
{ "minimumSize", Actor::Property::MINIMUM_SIZE, Property::VECTOR2 },
{ "maximumSize", Actor::Property::MAXIMUM_SIZE, Property::VECTOR2 },
{ "inheritPosition", Actor::Property::INHERIT_POSITION, Property::BOOLEAN },
- { "batchParent", DevelActor::Property::BATCH_PARENT, Property::BOOLEAN },
{ "clippingMode", Actor::Property::CLIPPING_MODE, Property::STRING },
};
const unsigned int PROPERTY_TABLE_COUNT = sizeof( PROPERTY_TABLE ) / sizeof( PROPERTY_TABLE[0] );
INHERIT_POSITION = Dali::Actor::Property::INHERIT_POSITION,
CLIPPING_MODE = Dali::Actor::Property::CLIPPING_MODE,
- /**
- * @brief name "batchParent", type BOOLEAN
- * @see Batching
- * @note The default value is 'false'
- */
- BATCH_PARENT = CLIPPING_MODE + 1,
- SIBLING_ORDER = CLIPPING_MODE + 2,
+ SIBLING_ORDER = CLIPPING_MODE + 1,
};
} // namespace Property
STENCIL_OPERATION_ON_FAIL = Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL,
STENCIL_OPERATION_ON_Z_FAIL = Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL,
STENCIL_OPERATION_ON_Z_PASS = Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS,
-
- /**
- * @brief name "batchingEnabled", type BOOLEAN
- * @see Batching
- * @note The default value is 'false'
- */
- BATCHING_ENABLED = STENCIL_OPERATION_ON_Z_PASS + 1
};
} // namespace Property
#include <dali/internal/update/common/discard-queue.h>
#include <dali/internal/update/common/texture-cache-dispatcher.h>
#include <dali/internal/update/manager/update-manager.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
#include <dali/internal/update/manager/render-task-processor.h>
#include <dali/internal/update/resources/resource-manager.h>
mTextureUploadedQueue(),
mNotificationManager(NULL),
mShaderFactory(NULL),
- mGeometryBatcher( NULL ),
mIsActive(true),
mProcessingEvent(false)
{
mTextureUploadedQueue = new LockedResourceQueue;
- mGeometryBatcher = new SceneGraph::GeometryBatcher();
-
mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
- mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mGeometryBatcher, *mTextureUploadedQueue );
+ mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mTextureUploadedQueue );
RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
TextureCache& textureCache = mRenderManager->GetTextureCache();
*mRenderManager,
renderQueue,
*mTextureCacheDispatcher,
- *mGeometryBatcher,
*mRenderTaskProcessor );
mRenderManager->SetShaderSaver( *mUpdateManager );
delete mUpdateManager;
delete mRenderManager;
delete mRenderTaskProcessor;
- delete mGeometryBatcher;
delete mTextureUploadedQueue;
}
class RenderManager;
class DiscardQueue;
class TextureCacheDispatcher;
-class GeometryBatcher;
class RenderTaskProcessor;
}
ShaderFactory* mShaderFactory; ///< Shader resource factory
ResourceManager* mResourceManager; ///< Asynchronous Resource Loading
IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller
- SceneGraph::GeometryBatcher* mGeometryBatcher; ///< Instance of the geometry batcher
SceneGraph::RenderTaskProcessor* mRenderTaskProcessor; ///< Handles the processing of render tasks
bool mIsActive : 1; ///< Whether Core is active or suspended
bool mProcessingEvent : 1; ///< True during ProcessEvents()
return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
}
-void Dali::Internal::MultiplyVectorBySize( Vec2& result, const Vec2 v, const Size3 s )
-{
- result[0] = v[0] * s[0];
- result[1] = v[1] * s[1];
-}
-
-void Dali::Internal::MultiplyVectorBySize( Vec3& result, const Vec3 v, const Size3 s )
-{
- result[0] = v[0] * s[0];
- result[1] = v[1] * s[1];
- result[2] = v[2] * s[2];
-}
-
-void Dali::Internal::MultiplyVectorBySize( Vec4& result, const Vec4 v, const Size3 s )
-{
- result[0] = v[0] * s[0];
- result[1] = v[1] * s[1];
- result[2] = v[2] * s[2];
- result[3] = 1.0f;
-}
-
-void Dali::Internal::MultiplyVectorByMatrix4( Vec2& result, const Mat4 m, const Vec2 v )
-{
- result[0] = v[0] * m[0] + v[1] * m[4] + m[12];
- result[1] = v[0] * m[1] + v[1] * m[5] + m[13];
-}
-
-void Dali::Internal::MultiplyVectorByMatrix4( Vec3& result, const Mat4 m, const Vec3 v )
-{
- result[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[12];
- result[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[13];
- result[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14];
-}
-
-void Dali::Internal::MultiplyVectorByMatrix4( Vec4& result, const Mat4 m, const Vec4 rhs )
-{
- result[0] = rhs[0] * m[0] + rhs[1] * m[4] + rhs[2] * m[8] + rhs[3] * m[12];
- result[1] = rhs[0] * m[1] + rhs[1] * m[5] + rhs[2] * m[9] + rhs[3] * m[13];
- result[2] = rhs[0] * m[2] + rhs[1] * m[6] + rhs[2] * m[10] + rhs[3] * m[14];
- result[3] = rhs[0] * m[3] + rhs[1] * m[7] + rhs[2] * m[11] + rhs[3] * m[15];
-}
-
-void Dali::Internal::MultiplyMatrices( float* result, const Mat4 lhs, const Mat4 rhs )
-{
- for( int i=0; i < 4; i++ )
- {
- // i<<2 gives the first vector / column
- int loc = i<<2;
- int loc1 = loc + 1;
- int loc2 = loc + 2;
- int loc3 = loc + 3;
- float value0 = lhs[loc];
- float value1 = lhs[loc1];
- float value2 = lhs[loc2];
- float value3 = lhs[loc3];
- result[loc] = (value0 * rhs[0]) +
- (value1 * rhs[4]) +
- (value2 * rhs[8]) +
- (value3 * rhs[12]);
-
- result[loc1] = (value0 * rhs[1]) +
- (value1 * rhs[5]) +
- (value2 * rhs[9]) +
- (value3 * rhs[13]);
-
- result[loc2] = (value0 * rhs[2]) +
- (value1 * rhs[6]) +
- (value2 * rhs[10])+
- (value3 * rhs[14]);
-
- result[loc3] = (value0 * rhs[3]) +
- (value1 * rhs[7]) +
- (value2 * rhs[11])+
- (value3 * rhs[15]);
- }
-}
namespace Internal
{
-typedef float Vec2[2];
typedef float Vec3[3];
typedef float Vec4[4];
typedef float Mat4[16];
-typedef Vec3 Size3;
/**
* @brief Applies a transformation matrix to a vector
*/
float Length( const Vec3 v );
-/**
- * @brief Transforms 2D vector by the Size3 and stores value in Vec2
- *
- * @param[out] result Vec2 type to store final value
- * @param[in] v Vector to transform
- * @param[in] s Size to transform with
- */
-void MultiplyVectorBySize( Vec2& result, const Vec2 v, const Size3 s );
-
-/**
- * @brief Transforms 3D vector by the Size3 and stores value in Vec3
- *
- * @param[out] result Vec3 type to store final value
- * @param[in] v Vector to transform
- * @param[in] s Size to transform with
- */
-void MultiplyVectorBySize( Vec3& result, const Vec3 v, const Size3 s );
-
-/**
- * @brief Transforms 4D vector by the Size3 and stores value in Vec4
- *
- * @param[out] result Vec4 type to store final value
- * @param[in] v Vector to transform
- * @param[in] s Size to transform with
- */
-void MultiplyVectorBySize( Vec4& result, const Vec4 v, const Size3 s );
-
-/**
- * @brief Multiplies 2D vector by the matrix
- *
- * @param[out] result Result of the multiplication
- * @param[in] m Matrix to use
- * @param[in] v Vector to multiply
- */
-void MultiplyVectorByMatrix4( Vec2& result, const Mat4 m, const Vec2 v );
-
-/**
- * @brief Multiplies 3D vector by the matrix
- *
- * @param[out] result Result of the multiplication
- * @param[in] m Matrix to use
- * @param[in] v Vector to multiply
- */
-void MultiplyVectorByMatrix4( Vec3& result, const Mat4 m, const Vec3 v );
-
-/**
- * @brief Multiplies 4D vector by the matrix
- *
- * @param[out] result Result of the multiplication
- * @param[in] m Matrix to use
- * @param[in] v Vector to multiply
- */
-void MultiplyVectorByMatrix4( Vec4& result, const Mat4 m, const Vec4 v );
-
-/**
- * @brief Multiplies two Mat4 matrices
- *
- * @param[out] result Result of multiplication
- * @param[in] lhs Left-hand-side matrix to use
- * @param[in] rhs Right-hand-side matrix to use
- */
-void MultiplyMatrices( float* result, const Mat4 lhs, const Mat4 rhs );
-
-
} // namespace Internal
} // namespace Dali
DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
-DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::DevelActor::Property::BATCH_PARENT )
DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER )
DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
mDrawMode( DrawMode::NORMAL ),
mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
mColorMode( Node::DEFAULT_COLOR_MODE ),
- mClippingMode( ClippingMode::DISABLED ),
- mIsBatchParent( false )
+ mClippingMode( ClippingMode::DISABLED )
{
}
break;
}
- case Dali::DevelActor::Property::BATCH_PARENT:
- {
- bool value;
-
- if( property.Get( value ) )
- {
- if( value != mIsBatchParent )
- {
- mIsBatchParent = value;
- SetIsBatchParentMessage( GetEventThreadServices(), *mNode, mIsBatchParent );
- }
- }
- break;
- }
-
case Dali::DevelActor::Property::SIBLING_ORDER:
{
int value;
break;
}
- case Dali::DevelActor::Property::BATCH_PARENT:
- {
- value = mIsBatchParent;
- break;
- }
-
case Dali::DevelActor::Property::SIBLING_ORDER:
{
value = static_cast<int>(mSiblingOrder);
static ActorContainer mNullChildren; ///< Empty container (shared by all actors, returned by GetChildren() const)
static unsigned int mActorCounter; ///< A counter to track the actor instance creation
-
- bool mIsBatchParent : 1; ///< Flag indicating that the actor is a batch parent
-
};
} // namespace Internal
DALI_PROPERTY( "stencilOperationOnFail", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL )
DALI_PROPERTY( "stencilOperationOnZFail", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL )
DALI_PROPERTY( "stencilOperationOnZPass", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS )
-DALI_PROPERTY( "batchingEnabled", BOOLEAN, true, false, false, Dali::DevelRenderer::Property::BATCHING_ENABLED )
DALI_PROPERTY_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX )
// Property string to enumeration tables:
return mPremultipledAlphaEnabled;
}
-bool Renderer::IsBatchingEnabled() const
-{
- return mBatchingEnabled;
-}
-
SceneGraph::Renderer* Renderer::GetRendererSceneObject()
{
return mSceneObject;
}
break;
}
- case Dali::DevelRenderer::Property::BATCHING_ENABLED:
- {
- bool enabled;
- if( propertyValue.Get( enabled ) )
- {
- if( mBatchingEnabled != enabled )
- {
- mBatchingEnabled = enabled;
- SetBatchingEnabledMessage( GetEventThreadServices(), *mSceneObject, mBatchingEnabled );
- }
- }
- break;
- }
}
}
value = mDepthWriteMode;
break;
}
- case Dali::DevelRenderer::Property::BATCHING_ENABLED:
- {
- value = mBatchingEnabled;
- break;
- }
case Dali::Renderer::Property::DEPTH_FUNCTION:
{
value = mDepthFunction;
mBlendMode( BlendMode::AUTO ),
mDepthWriteMode( DepthWriteMode::AUTO ),
mDepthTestMode( DepthTestMode::AUTO ),
- mPremultipledAlphaEnabled( false ),
- mBatchingEnabled( false )
+ mPremultipledAlphaEnabled( false )
{
}
bool IsPreMultipliedAlphaEnabled() const;
/**
- * Returns state of batching mode
- * @return batching mode state ( true if enabled )
- */
- bool IsBatchingEnabled() const;
-
- /**
* @brief Get the scene graph object
*
* @return the scene object
DepthWriteMode::Type mDepthWriteMode:2; ///< Local copy of the depth write mode
DepthTestMode::Type mDepthTestMode:2; ///< Local copy of the depth test mode
bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
- bool mBatchingEnabled : 1; ///< Flag indicating whether render is batchable or not
};
} // namespace Internal
$(internal_src_dir)/update/gestures/pan-gesture-profiling.cpp \
$(internal_src_dir)/update/gestures/scene-graph-pan-gesture.cpp \
$(internal_src_dir)/update/queue/update-message-queue.cpp \
- $(internal_src_dir)/update/manager/geometry-batcher.cpp \
$(internal_src_dir)/update/manager/render-instruction-processor.cpp \
$(internal_src_dir)/update/manager/render-task-processor.cpp \
$(internal_src_dir)/update/manager/transform-manager.cpp \
#include <dali/internal/render/gl-resources/context.h>
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
using Dali::Internal::SceneGraph::RenderItem;
using Dali::Internal::SceneGraph::RenderList;
using Dali::Internal::SceneGraph::RenderListContainer;
using Dali::Internal::SceneGraph::RenderInstruction;
-using Dali::Internal::SceneGraph::GeometryBatcher;
namespace Dali
{
}
/**
- * @brief Setup Batching and calculate if we should perform or skip the upcoming render.
- *
- * Check if the node has a valid batch index value ( set previously by
- * GeometryBatcher ). If so, then it queries the geometry object for this particular batch.
- * If not, it still checks if the batch parent is set as it is possible, batching may
- * fail (for example if vertex format or buffers are not set). In that case we need
- * to skip rendering, otherwise unwanted GPU buffers will get uploaded. This is very rare case.
- * @param[in] item The item to test / setup for batching
- * @param[in] geometryBatcher The instance of the Geometry Batcher
- * @return True if we should perform a render as normal. False if we should skip it due to batching.
- */
-inline bool SetupBatching( const RenderItem& item, GeometryBatcher* geometryBatcher )
-{
- bool performRender( true );
- uint32_t batchIndex( item.mNode->mBatchIndex );
-
- if( batchIndex != BATCH_NULL_HANDLE )
- {
- item.mBatchRenderGeometry = geometryBatcher->GetGeometry( batchIndex );
- }
- else
- {
- performRender = !( item.mNode->GetBatchParent() );
- item.mBatchRenderGeometry = NULL;
- }
-
- return performRender;
-}
-
-/**
* @brief Process a render-list.
* @param[in] renderList The render-list to process.
* @param[in] context The GL context.
* @param[in] buffer The current render buffer index (previous update buffer)
* @param[in] viewMatrix The view matrix from the appropriate camera.
* @param[in] projectionMatrix The projection matrix from the appropriate camera.
- * @param[in] geometryBatcher The instance of the geometry batcher
*/
inline void ProcessRenderList(
const RenderList& renderList,
SceneGraph::Shader& defaultShader,
BufferIndex bufferIndex,
const Matrix& viewMatrix,
- const Matrix& projectionMatrix,
- GeometryBatcher* geometryBatcher )
+ const Matrix& projectionMatrix )
{
DALI_PRINT_RENDER_LIST( renderList );
// The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
SetupStencilBuffer( item, context, usedStencilBuffer, lastStencilDepth, lastClippingId );
- // Setup Batching and calculate if we should perform or skip the upcoming render.
- const bool performRender( SetupBatching( item, geometryBatcher ) );
-
- // Render the item if it has not been skipped by batching.
- if( DALI_LIKELY( performRender ) )
- {
- item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader,
- item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix,
- item.mSize, item.mBatchRenderGeometry, !item.mIsOpaque );
- }
+ // Render the item
+ item.mRenderer->Render( context,
+ textureCache,
+ bufferIndex,
+ *item.mNode,
+ defaultShader,
+ item.mModelMatrix,
+ item.mModelViewMatrix,
+ viewMatrix,
+ projectionMatrix,
+ item.mSize,
+ !item.mIsOpaque );
}
}
Context& context,
SceneGraph::TextureCache& textureCache,
SceneGraph::Shader& defaultShader,
- GeometryBatcher& geometryBatcher,
BufferIndex bufferIndex )
{
DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
if( renderList && !renderList->IsEmpty() )
{
- ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix, &geometryBatcher );
+ ProcessRenderList( *renderList,
+ context,
+ textureCache,
+ defaultShader,
+ bufferIndex,
+ *viewMatrix,
+ *projectionMatrix );
}
}
}
class RenderInstruction;
class Shader;
class TextureCache;
-class GeometryBatcher;
}
namespace Render
* @param[in] context The GL context.
* @param[in] textureCache The texture cache used to get textures.
* @param[in] defaultShader The default shader.
- * @param[in] geometryBatcher The instace of geometry batcher.
* @param[in] bufferIndex The current render buffer index (previous update buffer)
*/
void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction,
Context& context,
SceneGraph::TextureCache& textureCache,
SceneGraph::Shader& defaultShader,
- SceneGraph::GeometryBatcher& geometryBatcher,
BufferIndex bufferIndex );
} // namespace Render
mSize(),
mRenderer( NULL ),
mNode( NULL ),
- mBatchRenderGeometry( NULL ),
mDepthIndex( 0 ),
- mIsOpaque( true ),
- mBatched( false )
+ mIsOpaque( true )
{
}
namespace Render
{
class Renderer;
-class RenderGeometry;
}
namespace SceneGraph
Vector3 mSize;
Render::Renderer* mRenderer;
Node* mNode;
- const void* mTextureSet; //< Used only for sorting
-
- mutable Render::Geometry* mBatchRenderGeometry;
-
+ const void* mTextureSet; //< Used for sorting only
int mDepthIndex;
bool mIsOpaque:1;
- bool mBatched:1;
private:
Impl( Integration::GlAbstraction& glAbstraction,
Integration::GlSyncAbstraction& glSyncAbstraction,
LockedResourceQueue& textureUploadedQ,
- TextureUploadedDispatcher& postProcessDispatcher,
- GeometryBatcher& geometryBatcher )
+ TextureUploadedDispatcher& postProcessDispatcher )
: context( glAbstraction ),
glSyncAbstraction( glSyncAbstraction ),
renderQueue(),
renderersAdded( false ),
firstRenderCompleted( false ),
defaultShader( NULL ),
- programController( glAbstraction ),
- geometryBatcher( geometryBatcher )
+ programController( glAbstraction )
{
}
Shader* defaultShader; ///< Default shader to use
ProgramController programController; ///< Owner of the GL programs
- SceneGraph::GeometryBatcher& geometryBatcher; ///< Instance of geometry batcher
};
RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction,
Integration::GlSyncAbstraction& glSyncAbstraction,
- SceneGraph::GeometryBatcher& geometryBatcher,
LockedResourceQueue& textureUploadedQ )
{
RenderManager* manager = new RenderManager;
- manager->mImpl = new Impl( glAbstraction, glSyncAbstraction, textureUploadedQ, *manager, geometryBatcher );
+ manager->mImpl = new Impl( glAbstraction,
+ glSyncAbstraction,
+ textureUploadedQ,
+ *manager );
return manager;
}
mImpl->context,
mImpl->textureCache,
defaultShader,
- mImpl->geometryBatcher,
mImpl->renderBufferIndex );
if( instruction.mRenderTracker && ( offscreen != NULL || instruction.mFrameBuffer != NULL ) )
class RenderInstructionContainer;
class Shader;
class PropertyBufferDataProvider;
-class GeometryBatcher;
/**
* RenderManager is responsible for rendering the result of the previous "update", which
* Construct a new RenderManager.
* @param[in] glAbstraction The GL abstraction used for rendering.
* @param[in] glSyncAbstraction The GL sync abstraction used fence sync creation/deletion.
- * @param[in] geometryBatcher The geometry batcher instance
* @param[out] resourcePostProcessQueue A queue for sending rendered texture ids to the update-thread.*
*/
static RenderManager* New( Integration::GlAbstraction& glAbstraction,
Integration::GlSyncAbstraction& glSyncAbstraction,
- SceneGraph::GeometryBatcher& geometryBatcher,
LockedResourceQueue& resourcePostProcessQueue );
/**
{
}
-void Geometry::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer)
+void Geometry::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
{
mVertexBuffers.PushBack( propertyBuffer );
mAttributesChanged = true;
mIndicesChanged = true;
}
-const Dali::Vector<unsigned short>* Geometry::GetIndexBuffer() const
-{
- return &mIndices;
-}
-
void Geometry::RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer )
{
size_t bufferCount = mVertexBuffers.Size();
}
}
-const Render::PropertyBuffer* Geometry::GetPropertyBuffer( size_t index ) const
-{
- if( index < mVertexBuffers.Size() )
- {
- return mVertexBuffers[ index ];
- }
- return NULL;
-}
-
void Geometry::GetAttributeLocationFromProgram( Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex ) const
{
attributeLocation.Clear();
void SetIndexBuffer( Dali::Vector<unsigned short>& indices );
/**
- * Obtains pointer to the storage of indexed elements
- * @return Pointer to the index buffer
- */
- const Dali::Vector<unsigned short>* GetIndexBuffer() const;
-
- /**
* Removes a PropertyBuffer from the geometry
* @param[in] propertyBuffer The property buffer to be removed
*/
void RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer );
/**
- * Returns property buffer at specified index
- * @param[in] index of the property buffer
- * @return pointer to the property buffer or NULL
- */
- const Render::PropertyBuffer* GetPropertyBuffer( size_t index ) const;
-
- /**
* Gets the attribute locations on the shader for the attributes defined in the geometry RenderBuffers
* @param[out] attributeLocation The vector where the attributes locations will be stored
* @param[in] program The program
mDataChanged = true;
}
-void PropertyBuffer::UpdateData()
-{
- mDataChanged = true;
-}
-
bool PropertyBuffer::Update( Context& context )
{
if( !mData || !mFormat || !mSize )
void SetData( Dali::Vector<char>* data, size_t size );
/**
- * @brief Sets flag to update data in the buffer when next PropertyBuffer::Update()
- * is called.
- */
- void UpdateData();
-
- /**
* @brief Set the number of elements
* @param[in] size The number of elements
*/
mDepthWriteMode( depthWriteMode ),
mDepthTestMode( depthTestMode ),
mUpdateAttributesLocation( true ),
- mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ),
- mBatchingEnabled( false )
+ mPremultipledAlphaEnabled( preMultipliedAlphaEnabled )
{
if( blendingBitmask != 0u )
{
return mStencilParameters.stencilOperationOnZPass;
}
-void Renderer::SetBatchingEnabled( bool batchingEnabled )
-{
- mBatchingEnabled = batchingEnabled;
-}
-
void Renderer::Render( Context& context,
SceneGraph::TextureCache& textureCache,
BufferIndex bufferIndex,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
const Vector3& size,
- Render::Geometry* externalGeometry,
bool blend )
{
// Get the program to use:
}
SetUniforms( bufferIndex, node, size, *program );
- Render::Geometry* geometry = externalGeometry ? externalGeometry : mGeometry;
- if( mUpdateAttributesLocation || geometry->AttributesChanged() )
+ if( mUpdateAttributesLocation || mGeometry->AttributesChanged() )
{
- geometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex );
+ mGeometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex );
mUpdateAttributesLocation = false;
}
- geometry->UploadAndDraw( context, bufferIndex, mAttributesLocation, mIndexedDrawFirstElement, mIndexedDrawElementsCount );
+ mGeometry->UploadAndDraw( context,
+ bufferIndex,
+ mAttributesLocation,
+ mIndexedDrawFirstElement,
+ mIndexedDrawElementsCount );
}
}
void SetGeometry( Render::Geometry* geometry );
/**
- * Retrieves the geometry used by the renderer
- * @return The geometry used by the renderer
- */
- Render::Geometry* GetGeometry() const
- {
- return mGeometry;
- }
-
- /**
* Second-phase construction.
* This is called when the renderer is inside render thread
* @param[in] context Context used by the renderer
StencilOperation::Type GetStencilOperationOnZPass() const;
/**
- * Sets batching mode on the renderer
- * @param[in] batchingEnabled batching state
- */
- void SetBatchingEnabled( bool batchingEnabled );
-
- /**
* Called to render during RenderManager::Render().
* @param[in] context The context used for rendering
* @param[in] textureCache The texture cache used to get textures
* @param[in] viewMatrix The view matrix.
* @param[in] projectionMatrix The projection matrix.
* @param[in] size Size of the render item
- * @param[in] externalGeometry Optional external geometry, if set the original geometry is ignored. If NULL, original geometry will be drawn as normal.
* @param[in] blend If true, blending is enabled
*/
void Render( Context& context,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
const Vector3& size,
- Render::Geometry* externalGeometry,
- bool blend);
+ bool blend );
/**
* Write the renderer's sort attributes to the passed in reference
DepthTestMode::Type mDepthTestMode:2; ///< The depth test mode
bool mUpdateAttributesLocation:1; ///< Indicates attribute locations have changed
bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
- bool mBatchingEnabled:1; ///< Flag indicating if the renderer is batchable
};
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/render/shaders/scene-graph-shader.h>
#include <dali/internal/update/render-tasks/scene-graph-camera.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
namespace Dali
{
mNodeQueue(),
mShaderQueue(),
mRendererQueue(),
- mCameraQueue(),
- mGeometryBatcher( NULL )
+ mCameraQueue()
{
}
// The Update for frame N+1 may occur in parallel with the rendering of frame N
// Queue the node for destruction in frame N+2
mNodeQueue[ updateBufferIndex ].PushBack( node );
-
- // If batching, then mark corresponding batch to be destroyed too
- if( node->GetIsBatchParent() )
- {
- mGeometryBatcher->RemoveBatchParent( node );
- }
- else if( node->GetBatchParent() )
- {
- if( node->mBatchIndex != BATCH_NULL_HANDLE )
- {
- mGeometryBatcher->RemoveNode( node );
- }
- }
-
}
void DiscardQueue::Add( BufferIndex updateBufferIndex, Shader* shader )
mCameraQueue[ updateBufferIndex ].Clear();
}
-void DiscardQueue::SetGeometryBatcher( GeometryBatcher* geometryBatcher )
-{
- mGeometryBatcher = geometryBatcher;
-}
-
} // namespace SceneGraph
} // namespace Internal
namespace SceneGraph
{
-class GeometryBatcher;
class RenderQueue;
class Shader;
class Camera;
*/
void Clear( BufferIndex updateBufferIndex );
- /**
- * Sets pointer to the GeometryBatcher instance
- * @param[in] geometryBatcher Instance of the GeometryBatcher
- */
- void SetGeometryBatcher( GeometryBatcher* geometryBatcher );
-
private:
// Undefined
ShaderQueue mShaderQueue[2];
RendererQueue mRendererQueue[2];
CameraQueue mCameraQueue[2];
-
-
- GeometryBatcher* mGeometryBatcher; ///< Geometry batcher needed to clean up batches upon node deletion
};
} // namespace SceneGraph
+++ /dev/null
-/*
- * 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.
- * 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/update/manager/geometry-batcher.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/render/common/render-item.h>
-#include <dali/internal/render/common/render-tracker.h>
-#include <dali/internal/render/common/render-instruction.h>
-#include <dali/internal/render/common/render-instruction-container.h>
-#include <dali/internal/render/shaders/scene-graph-shader.h>
-#include <dali/internal/render/renderers/render-renderer.h>
-#include <dali/internal/render/renderers/render-property-buffer.h>
-#include <dali/internal/render/renderers/render-geometry.h>
-#include <dali/internal/update/rendering/scene-graph-renderer.h>
-#include <dali/internal/update/controllers/scene-controller.h>
-#include <dali/internal/update/manager/update-manager.h>
-#include <dali/internal/common/math.h>
-
-namespace
-{
-
-// helper macros to deal with handles
-#define BATCH_LOCAL_INDEX(x) (x&0xFFFF)
-#define BATCH_PARENT_INDEX(x) ((x>>16)&0xFFFF)
-#define BATCH_INDEX_CREATE( batchParentIndex, batchIndex ) ( ( ( (batchParentIndex)&0xFFFF ) << 16 ) | ( (batchIndex)&0xFFFF ) )
-
-/**
- * The TransformVertexBufferInfo struct
- * Must be filled before transforming vertices
- */
-struct TransformVertexBufferData
-{
- void* destinationPtr; ///< pointer to the destination vertex buffer
- const void* sourcePtr; ///< pointer to the source vertex buffer
- float* transform; ///< transform relative to batch parent
- const float* worldMatrix; ///< model/world matrix of node being batched
- const float* parentInvWorldMatrix; ///< inv world matrix of batch parent
- unsigned componentSize; ///< size of component
- unsigned vertexCount; ///< number of vertices to process
- const float* size; ///< size of render item
-};
-
-/**
- * @brief function transforms vertices from 'source' and writes into 'destination'
- * @param[in,out] data Filled TransformVertexBufferInfo arguments structure
- */
-template <typename PositionType >
-void TransformVertexBuffer( TransformVertexBufferData& data )
-{
- const char* source = reinterpret_cast<const char*>( data.sourcePtr );
- char* destination = reinterpret_cast<char*>( data.destinationPtr );
-
- size_t componentSize = data.componentSize ? data.componentSize : sizeof( PositionType );
- const char* sourceEnd = source + data.vertexCount*componentSize;
- for( ; source < sourceEnd;
- destination += componentSize,
- source += componentSize
- )
- {
- Dali::Internal::MultiplyVectorBySize( *reinterpret_cast<PositionType*>(destination), *reinterpret_cast<const PositionType*>(source), data.size );
- Dali::Internal::MultiplyVectorByMatrix4( *reinterpret_cast<PositionType*>(destination), data.transform, *reinterpret_cast<PositionType*>(destination) );
- }
-}
-
-} //Unnamed namespace
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace SceneGraph
-{
-
-/**
- * @brief The VertexDescriptor struct
- * Holds details of vertex format used for batching
- */
-struct VertexDescriptor
-{
- VertexDescriptor()
- : mVertexComponentSize( 0 ),
- mVertexPositionType( Dali::Property::NONE ),
- mVertexFormat( NULL )
- {
- }
-
- unsigned int mVertexComponentSize; ///< Vertex component size in bytes
- Dali::Property::Type mVertexPositionType; ///< Vertex position type ( may be Vector2, Vector3, Vector4 )
- Dali::Internal::Render::PropertyBuffer::Format* mVertexFormat; ///< Vertex format cloned from the very first batched item
-};
-
-struct BatchKey
-{
- BatchKey()
- : batchParentNode( NULL ),
- shader( NULL ),
- textureSet( NULL ),
- depthIndex( 0 )
- {
- }
-
- ~BatchKey()
- {
- }
-
- BatchKey( Node* node )
- {
- MakeFromNode( node );
- }
-
- inline void MakeFromNode( Node* node )
- {
- Renderer* renderer = node->GetRendererAt( 0 );
- batchParentNode = node->GetBatchParent();
- shader = &renderer->GetShader();
- textureSet = renderer->GetTextures();
- depthIndex = renderer->GetDepthIndex();
- }
-
- inline bool operator==( const BatchKey& key )
- {
- return batchParentNode == key.batchParentNode && shader == key.shader && textureSet == key.textureSet && depthIndex == key.depthIndex;
- }
-
- inline bool operator!=( const BatchKey& key )
- {
- return !( *this == key );
- }
-
- const Node* batchParentNode; /// batch parent node that owns batch
- const Shader* shader; /// shader associated with the batch
- const TextureSet* textureSet; /// texture set used by the batch
- int depthIndex; /// depth index of the batch
-};
-
-/**
- * @brief The Batch struct
- * Stores details of single batch
- */
-struct Batch
-{
- Batch( const BatchKey& key, Render::Geometry* batchGeometry = NULL )
- : batchKey( key ),
- geometry( batchGeometry ),
- renderedFrame( 0 ),
- dirty( true )
- {}
-
-
- BatchKey batchKey; /// Unique batch key
- Vector<unsigned short> indices; /// index buffer per batch
- Render::Geometry* geometry; /// Batch geometry
- size_t renderedFrame; /// Flag used to determine if batch has already rendered during a frame
- bool dirty; /// 'dirty' flag per batch
-};
-
-typedef std::vector<Batch> BatchList;
-
-/**
- * @brief The BatchParent struct
- * Stores list of children of single batch parent
- */
-struct BatchParent
-{
- Node* node; /// Pointer to a node which is a parent for batch(es)
- Vector<Node*> batchedChildren; /// List of batchable children
- BatchList batches; /// List of batches which belong to this parent
- Render::PropertyBuffer* vertexBuffer; /// Vertex buffer shared by all batches for this parent
- bool needsUpdate; /// Flag indicating if batches should be updated
-};
-
-struct Impl
-{
- Impl()
- : batchParents(),
- updateManager( NULL ),
- currentFrame( 0 )
- {
- }
-
- int GetBatchKeyIndex( size_t batchParentIndex, const BatchKey& key )
- {
- BatchParent& batchParent = batchParents[ batchParentIndex ];
- for( size_t j = 0; j < batchParent.batches.size(); ++j )
- {
- if( batchParent.batches[j].batchKey == key )
- {
- return BATCH_INDEX_CREATE( batchParentIndex, j );
- }
- }
- return -1;
- }
-
- std::vector<BatchParent> batchParents; /// non-trivial type, hence std::vector
- UpdateManager* updateManager;
- size_t currentFrame;
-};
-
-GeometryBatcher::GeometryBatcher() :
- mImpl( NULL )
-{
- mImpl = new Impl();
-}
-
-void GeometryBatcher::SetUpdateManager( UpdateManager* updateManager )
-{
- mImpl->updateManager = updateManager;
-}
-
-GeometryBatcher::~GeometryBatcher()
-{
- delete mImpl;
-}
-
-bool GeometryBatcher::CloneVertexFormat( const Render::Geometry* sourceGeometry, VertexDescriptor& vertexDescriptor )
-{
- const Render::Geometry* geometry = sourceGeometry;
- const Render::PropertyBuffer::Format* format = geometry->GetPropertyBuffer( 0 )->GetFormat();
-
- if( !format )
- {
- return false;
- }
-
- Render::PropertyBuffer::Format* clonedVertexFormat = new Render::PropertyBuffer::Format( *format );
- Render::PropertyBuffer::Component& firstComponent = clonedVertexFormat->components[0];
-
- vertexDescriptor.mVertexPositionType = firstComponent.type;
- vertexDescriptor.mVertexComponentSize = clonedVertexFormat->size;
- vertexDescriptor.mVertexFormat = clonedVertexFormat;
-
- return true;
-}
-
-void GeometryBatcher::Update( BufferIndex bufferIndex )
-{
- if( !mImpl->batchParents.empty() )
- {
- std::vector<BatchParent>::iterator iter = mImpl->batchParents.begin();
- std::vector<BatchParent>::iterator end = mImpl->batchParents.end();
-
- // for each Batch Parent
- for( size_t batchParentIndex = 0; iter != end; ++iter, ++batchParentIndex )
- {
- BatchParent& batchParentData = *iter;
- // Skip update if batch parent doesn't need it
- if( !batchParentData.needsUpdate )
- {
- continue;
- }
-
- Node* batchParentNode = batchParentData.node;
-
- // Skip if batch parent doesn't have batched children
- size_t size = batchParentData.batchedChildren.Size();
- if( !size )
- {
- batchParentData.needsUpdate = false;
- continue;
- }
-
- bool batchingFailed( false );
- uint32_t batchKeyIndex( BATCH_NULL_HANDLE );
-
- BatchKey oldKey;
- BatchKey key;
- VertexDescriptor vertexDescriptor;
-
- // Destination vertex buffer per batch parent
- Vector<char>& vertexBufferDest = *( new Vector<char>() );
- Render::PropertyBuffer* batchVertexBuffer = new Render::PropertyBuffer();
-
- size_t currentElementIndex = 0;
-
- Matrix invWorldMatrix( batchParentNode->GetWorldMatrix( bufferIndex ) );
- invWorldMatrix.Invert();
-
- // For each batched child of this batch parent...
- for( size_t i = 0; i < size; ++i )
- {
- Node* node = batchParentData.batchedChildren[i];
-
- const SceneGraph::Renderer* renderer = node->GetRendererAt( 0 );
-
- // Geometry
- const Render::Geometry* geometry = &renderer->GetGeometry();
-
- // Generate batch key
- key.MakeFromNode( node );
-
- // format of first property buffer
- const Render::PropertyBuffer* vertexBuffer = geometry->GetPropertyBuffer( 0 );
-
- // Geometry of the node may not be ready, in that case we discard whole batch
- if( !vertexBuffer || ( !vertexDescriptor.mVertexFormat && !CloneVertexFormat( geometry, vertexDescriptor ) ) )
- {
- batchingFailed = true;
- break;
- }
-
- // Instantiate new batch
- if( oldKey != key )
- {
- oldKey = key;
- batchKeyIndex = mImpl->GetBatchKeyIndex( batchParentIndex, key );
-
- if( batchKeyIndex == BATCH_NULL_HANDLE )
- {
- // Create new batch geometry
- Render::Geometry* newGeometry = new Render::Geometry();
-
- Batch batch( key, newGeometry );
-
- // push new batch
- batchParentData.batches.push_back( batch );
-
- // rebuild handle
- batchKeyIndex = BATCH_INDEX_CREATE( batchParentIndex, batchParentData.batches.size()-1 );
-
- // Vertex buffer may be set before it's filled with data
- newGeometry->AddPropertyBuffer( batchVertexBuffer );
-
- // Register geometry with update manager
- mImpl->updateManager->AddGeometry( newGeometry );
- }
- }
-
- // Tell node which batch it belongs to
- node->mBatchIndex = batchKeyIndex;
-
- uint32_t localIndex = BATCH_LOCAL_INDEX( batchKeyIndex );
-
- if( !batchParentData.batches[ localIndex ].dirty )
- {
- continue;
- }
-
- const uint32_t vertexBufferSize = vertexBuffer->GetDataSize();
- const char* vertexDataSource = &vertexBuffer->GetData()[ 0 ];
-
- uint32_t currentSize = vertexBufferDest.Size();
- vertexBufferDest.Resize( currentSize + vertexBufferSize );
- char* vertexDataDest = &vertexBufferDest[ currentSize ];
-
- // copy data as they are
- std::copy( vertexDataSource, vertexDataSource + vertexBufferSize, vertexDataDest );
-
- // transform node
- const Matrix& worldMatrix = node->GetWorldMatrix( bufferIndex );
-
- // vertex count
- const unsigned int sourceVertexCount = vertexBufferSize / vertexDescriptor.mVertexComponentSize;
-
- // compute transform for the node
- TransformVertexBufferData transformParameters;
- transformParameters.destinationPtr = vertexDataDest;
- transformParameters.sourcePtr = vertexDataSource;
-
- // perform transformation
- Matrix transformMatrix;
- Dali::Internal::MultiplyMatrices( transformMatrix.AsFloat(), worldMatrix.AsFloat(), invWorldMatrix.AsFloat() );
- transformParameters.transform = transformMatrix.AsFloat();
- transformParameters.componentSize = vertexDescriptor.mVertexComponentSize;
- transformParameters.vertexCount = sourceVertexCount;
- transformParameters.size = node->GetSize( bufferIndex ).AsFloat();
-
- // Perform vertex transform based on the vertex format
- switch( vertexDescriptor.mVertexPositionType )
- {
- case Dali::Property::VECTOR2:
- {
- TransformVertexBuffer<Vec2>( transformParameters );
- break;
- }
- case Dali::Property::VECTOR3:
- {
- TransformVertexBuffer<Vec3>( transformParameters );
- break;
- }
- case Dali::Property::VECTOR4:
- {
- TransformVertexBuffer<Vec4>( transformParameters );
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( true && "Incorrect vertex format! Use Vector2, Vector3 or Vector4 as position!" );
- }
- }
-
- // update index buffer
- Batch& batch = batchParentData.batches[ localIndex ];
- uint32_t currentIndexOffset = batch.indices.Size();
- batch.indices.Resize( batch.indices.Size() + sourceVertexCount );
- for( size_t k = 0; k < sourceVertexCount; ++k )
- {
- size_t index = currentElementIndex + k;
- batch.indices[k + currentIndexOffset] = (unsigned short)index;
- }
-
- currentElementIndex += sourceVertexCount;
- }
-
- if( batchingFailed )
- {
- delete &vertexBufferDest;
- delete batchVertexBuffer;
- continue;
- }
-
- // Add shared property buffer
- mImpl->updateManager->AddPropertyBuffer( batchVertexBuffer );
- batchVertexBuffer->SetFormat( vertexDescriptor.mVertexFormat );
- batchVertexBuffer->SetData( &vertexBufferDest, vertexBufferDest.Size()/vertexDescriptor.mVertexComponentSize );
-
- batchParentData.needsUpdate = false;
- batchParentData.vertexBuffer = batchVertexBuffer;
-
- // Update index buffers for all batches own by that batch parent
- std::vector<Batch>::iterator iter = batchParentData.batches.begin();
- std::vector<Batch>::iterator end = batchParentData.batches.end();
- for( ; iter != end; ++iter )
- {
- Batch& batch = (*iter);
- batch.geometry->SetIndexBuffer( batch.indices );
- batch.dirty = false;
- }
- }
- }
- ++mImpl->currentFrame;
-}
-
-void GeometryBatcher::AddBatchParent( Node* node )
-{
- BatchParent batchParent;
- batchParent.node = node;
- batchParent.needsUpdate = true;
- batchParent.batchedChildren.Clear();
-
- mImpl->batchParents.push_back( batchParent );
-}
-
-void GeometryBatcher::RemoveBatchParent( Node* node )
-{
- for( size_t i = 0; i < mImpl->batchParents.size(); ++i )
- {
- BatchParent& batchParent = mImpl->batchParents[i];
- if( node == batchParent.node )
- {
- // tell children they're not batched anymore
- Vector<Node*>::Iterator iter = batchParent.batchedChildren.Begin();
- Vector<Node*>::Iterator end = batchParent.batchedChildren.End();
- for( ; iter != end; ++iter )
- {
- Node* child = *iter;
- child->mBatchIndex = BATCH_NULL_HANDLE;
- }
-
- // delete all resources that belongs to the batch parent
- for( size_t j = 0; j < batchParent.batches.size(); ++j )
- {
- Batch& batch = batchParent.batches[j];
- mImpl->updateManager->RemoveGeometry( batch.geometry );
- }
-
- // delete main vertex buffer
- mImpl->updateManager->RemovePropertyBuffer( batchParent.vertexBuffer );
-
- return;
- }
- }
-}
-
-void GeometryBatcher::AddNode( Node* node )
-{
- // look for batch parent
- Node* currentNode = node->GetParent();
- Node* batchParent = NULL;
- while( currentNode )
- {
- if( currentNode->mIsBatchParent )
- {
- batchParent = currentNode;
- }
- currentNode = currentNode->GetParent();
- }
-
- if( batchParent )
- {
- // find batch parent
- for( size_t i = 0; i < mImpl->batchParents.size(); ++i )
- {
- if( mImpl->batchParents[i].node == batchParent )
- {
- mImpl->batchParents[i].batchedChildren.PushBack( node );
- node->SetBatchParent( batchParent );
- mImpl->batchParents[i].needsUpdate = true;
- break;
- }
- }
- }
-}
-
-void GeometryBatcher::RemoveNode( Node* node )
-{
- if( node->mBatchIndex == BATCH_NULL_HANDLE )
- {
- return;
- }
-
- uint32_t parentIndex = BATCH_PARENT_INDEX( node->mBatchIndex );
-
- BatchParent& batchParent = mImpl->batchParents[ parentIndex ];
-
- // delete all batches from batch parent
- for( size_t i = 0; i < batchParent.batches.size(); ++i )
- {
- Batch& batch = batchParent.batches[ i ];
-
- // delete geometry
- mImpl->updateManager->RemoveGeometry( batch.geometry );
- }
-
- batchParent.batches.clear();
-
- // for all children reset batch index to BATCH_NULL_HANDLE
- for( size_t i = 0; i < batchParent.batchedChildren.Size(); )
- {
- Node* child = batchParent.batchedChildren[i];
-
- if( node == child )
- {
- batchParent.batchedChildren.Erase( batchParent.batchedChildren.Begin() + i );
- }
- else
- {
- child->mBatchIndex = BATCH_NULL_HANDLE;
- ++i;
- }
- }
-
- mImpl->updateManager->RemovePropertyBuffer( batchParent.vertexBuffer );
- batchParent.needsUpdate = true;
-}
-
-bool GeometryBatcher::HasRendered( uint32_t batchIndex )
-{
- return mImpl->batchParents[ BATCH_PARENT_INDEX( batchIndex ) ].batches[ BATCH_LOCAL_INDEX( batchIndex ) ].renderedFrame == mImpl->currentFrame;
-}
-
-void GeometryBatcher::SetRendered( uint32_t batchIndex )
-{
- mImpl->batchParents[ BATCH_PARENT_INDEX( batchIndex ) ].batches[ BATCH_LOCAL_INDEX( batchIndex ) ].renderedFrame = mImpl->currentFrame;
-}
-
-Render::Geometry* GeometryBatcher::GetGeometry( uint32_t batchIndex )
-{
- return mImpl->batchParents[ BATCH_PARENT_INDEX( batchIndex) ].batches[ BATCH_LOCAL_INDEX( batchIndex ) ].geometry;
-}
-
-} // namespace SceneGraph
-
-} // namespace Internal
-
-
-} // namespace Dali
+++ /dev/null
-#ifndef DALI_INTERNAL_SCENE_GRAPH_GEOMETRY_BATCHER_H
-#define DALI_INTERNAL_SCENE_GRAPH_GEOMETRY_BATCHER_H
-
-/*
- * 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.
- * 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.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/internal/render/renderers/render-property-buffer.h>
-#include <dali/internal/update/rendering/scene-graph-texture-set.h>
-#include <dali/internal/render/common/render-list.h>
-
-// PUBLIC INCLUDES
-#include <dali/public-api/common/dali-vector.h>
-
-/// Value used by a node to indicate the batch index as null or invalid
-#define BATCH_NULL_HANDLE 0xFFFFFFFF
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Render
-{
-class Geometry;
-}
-
-namespace SceneGraph
-{
-struct BatchInfo;
-struct BatchStreamMarker;
-
-class Node;
-class RenderInstructionContainer;
-
-class GeometryBatcher
-{
-
-public:
-
- /**
- * The constructor of GeometryBatcher
- */
- GeometryBatcher();
-
- /**
- * The destructor of GeometryBatcher
- */
- ~GeometryBatcher();
-
- /**
- * Assigns the update manager object
- * @param[in] updateManager Pointer to instance of update manager
- */
- void SetUpdateManager( UpdateManager* updateManager );
-
- /**
- * Updates all batches
- * @param[in] index Update buffer index
- */
- void Update( BufferIndex index );
-
- /**
- * @brief Add node to batch parents list
- * @param[in] node instance of a node to be added
- */
- void AddBatchParent( Node* node );
-
- /**
- * @brief Remove node from list of batch parents
- * @param[in] node valid instance of node to be removed
- */
- void RemoveBatchParent( Node* node );
-
- /**
- * @brief Add batchable node
- * @param[in] node valid instance of the node to be added
- */
- void AddNode( Node* node );
-
- /**
- * @brief Remove batchable node
- * @param[in] node valid instance of the node to be removed
- */
- void RemoveNode( Node* node );
-
- /**
- * @brief Return the geometry object associated with specified batch index
- * @param[in] batchIndex VALID index of the batch
- * @return instance of the batched geometry
- */
- Render::Geometry* GetGeometry( uint32_t batchIndex );
-
- /**
- * @brief Query if a batch at given index has been already rendered
- * @param batchIndex VALID index of a batch to query
- * @return true if batch has rendered, false otherwise
- */
- bool HasRendered( uint32_t batchIndex );
-
- /**
- * @brief Sets a batch at given index as rendered
- * @param batchIndex VALID index of a batch
- */
- void SetRendered( uint32_t batchIndex );
-
-private:
-
- GeometryBatcher( const GeometryBatcher& ); ///< Undefined
- GeometryBatcher& operator=( const GeometryBatcher& ); ///< Undefined
-
- /**
- * @brief Clones vertex format of source geometry and stores generated data in the batchInfo object
- * @param[in] sourceGeometry Geometry of the very first batched item
- * @param[out] batchInfo Batch info object used to store cloned vertex format
- * @return true on success, false otherwise
- */
- bool CloneVertexFormat( const Render::Geometry* sourceGeometry, struct VertexDescriptor& batchInfo );
-
-private:
-
- struct Impl* mImpl; ///< Pointer to an instance of geometry batcher implementation
-
-};
-
-} // SceneGraph
-
-} // Internal
-
-} // Dali
-
-
-#endif //DALI_INTERNAL_SCENE_GRAPH_GEOMETRY_BATCHER_H
-
#include <dali/internal/render/shaders/scene-graph-shader.h>
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/render/renderers/render-property-buffer.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
namespace
* @param renderable Node-Renderer pair
* @param viewMatrix used to calculate modelview matrix for the item
* @param camera The camera used to render
- * @param geometryBatcher The instance of the geometry batcher
* @param isLayer3d Whether we are processing a 3D layer or not
* @param cull Whether frustum culling is enabled or not
*/
Renderable& renderable,
const Matrix& viewMatrix,
SceneGraph::Camera& camera,
- GeometryBatcher& geometryBatcher,
bool isLayer3d,
bool cull )
{
- // Discard renderable early if it belongs to the batch which has been consumed in during frame.
- Node* renderableNode = renderable.mNode;
- const bool batchingValid( renderable.mRenderer->IsBatchingEnabled() && renderableNode->mBatchIndex != BATCH_NULL_HANDLE );
- if( batchingValid && geometryBatcher.HasRendered( renderableNode->mBatchIndex ) )
- {
- return;
- }
-
bool inside( true );
- const Node* batchParentNode = renderable.mNode->GetBatchParent();
- const Node* node = ( renderable.mRenderer->IsBatchingEnabled() && batchParentNode ) ?
- batchParentNode : renderableNode;
+ const Node* node = renderable.mNode;
if( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) )
{
if( inside )
{
- if( batchingValid )
- {
- geometryBatcher.SetRendered( renderableNode->mBatchIndex );
- }
-
Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode );
if( opacity != Renderer::TRANSPARENT )
{
* NodeRendererContainer Node-Renderer pairs
* @param viewMatrix used to calculate modelview matrix for the items
* @param camera The camera used to render
- * @param geometryBatcher The instance of the geometry batcher
* @param isLayer3d Whether we are processing a 3D layer or not
* @param cull Whether frustum culling is enabled or not
*/
RenderableContainer& renderers,
const Matrix& viewMatrix,
SceneGraph::Camera& camera,
- GeometryBatcher* geometryBatcher,
bool isLayer3d,
bool cull )
{
unsigned int rendererCount( renderers.Size() );
for( unsigned int i(0); i < rendererCount; ++i )
{
- AddRendererToRenderList( updateBufferIndex, renderList, renderers[i], viewMatrix, camera, *geometryBatcher, isLayer3d, cull );
+ AddRendererToRenderList( updateBufferIndex,
+ renderList,
+ renderers[i],
+ viewMatrix,
+ camera,
+ isLayer3d,
+ cull );
}
}
SortedLayerPointers& sortedLayers,
RenderTask& renderTask,
bool cull,
- GeometryBatcher& geometryBatcher,
bool hasClippingNodes,
RenderInstructionContainer& instructions )
{
if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) )
{
renderList->SetHasColorRenderItems( true );
- AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, &geometryBatcher, isLayer3D, cull );
+ AddRenderersToRenderList( updateBufferIndex,
+ *renderList,
+ renderables,
+ viewMatrix,
+ camera,
+ isLayer3D,
+ cull );
// We only use the clipping version of the sort comparitor if any clipping nodes exist within the RenderList.
SortRenderItems( updateBufferIndex, *renderList, layer, hasClippingNodes );
if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) )
{
renderList->SetHasColorRenderItems( false );
- AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, NULL, isLayer3D, cull );
+ AddRenderersToRenderList( updateBufferIndex,
+ *renderList,
+ renderables,
+ viewMatrix,
+ camera,
+ isLayer3D,
+ cull );
// Clipping hierarchy is irrelevant when sorting overlay items, so we specify using the non-clipping version of the sort comparitor.
SortRenderItems( updateBufferIndex, *renderList, layer, false );
class RenderTracker;
struct RenderItem;
class Shader;
-class GeometryBatcher;
struct RenderList;
class RenderTask;
class RenderInstructionContainer;
* @param[in] sortedLayers The layers containing lists of opaque/transparent renderables.
* @param[in] renderTask The rendering task information.
* @param[in] cull Whether frustum culling is enabled or not
- * @param[in] geometryBatcher The instance of the geometry batcher
* @param[in] hasClippingNodes Whether any clipping nodes exist within this layer, to optimize sorting if not
* @param[out] instructions The rendering instructions for the next frame.
*/
SortedLayerPointers& sortedLayers,
RenderTask& renderTask,
bool cull,
- GeometryBatcher& geometryBatcher,
bool hasClippingNodes,
RenderInstructionContainer& instructions );
RenderTaskList& renderTasks,
Layer& rootNode,
SortedLayerPointers& sortedLayers,
- GeometryBatcher& geometryBatcher,
RenderInstructionContainer& instructions )
{
RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks();
sortedLayers,
renderTask,
renderTask.GetCullMode(),
- geometryBatcher,
hasClippingNodes,
instructions );
}
sortedLayers,
renderTask,
renderTask.GetCullMode(),
- geometryBatcher,
hasClippingNodes,
instructions );
}
* @param[in] renderTasks The list of render-tasks.
* @param[in] rootNode The root node of the scene-graph.
* @param[in] sortedLayers The layers containing lists of opaque / transparent renderables.
- * @param[in] geometryBatcher The instance of the geometry batcher
* @param[out] instructions The instructions for rendering the next frame.
*/
void Process( BufferIndex updateBufferIndex,
RenderTaskList& renderTasks,
Layer& rootNode,
SortedLayerPointers& sortedLayers,
- GeometryBatcher& geometryBatcher,
RenderInstructionContainer& instructions );
private:
#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
#include <dali/internal/update/rendering/scene-graph-texture-set.h>
#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
#include <dali/internal/update/render-tasks/scene-graph-camera.h>
#include <dali/internal/render/common/render-instruction-container.h>
RenderManager& renderManager,
RenderQueue& renderQueue,
SceneGraphBuffers& sceneGraphBuffers,
- GeometryBatcher& geometryBatcher,
RenderTaskProcessor& renderTaskProcessor )
: renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
notificationManager( notificationManager ),
renderManager( renderManager ),
renderQueue( renderQueue ),
renderInstructions( renderManager.GetRenderInstructionContainer() ),
- geometryBatcher( geometryBatcher ),
renderTaskProcessor( renderTaskProcessor ),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
taskList( renderMessageDispatcher, resourceManager ),
renderers.SetSceneController( *sceneController );
- discardQueue.SetGeometryBatcher( &geometryBatcher );
-
// create first 'dummy' node
nodes.PushBack(0u);
}
RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
RenderQueue& renderQueue; ///< Used to queue messages for the next render
RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
- GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher
RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
RenderManager& renderManager,
RenderQueue& renderQueue,
TextureCacheDispatcher& textureCacheDispatcher,
- GeometryBatcher& geometryBatcher,
RenderTaskProcessor& renderTaskProcessor )
: mImpl(NULL)
{
renderManager,
renderQueue,
mSceneGraphBuffers,
- geometryBatcher,
renderTaskProcessor );
textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
- mImpl->geometryBatcher.SetUpdateManager( this );
}
UpdateManager::~UpdateManager()
{
mImpl->nodes.Insert((iter+1), node);
node->CreateTransform( &mImpl->transformManager );
- node->mGeometryBatcher = &mImpl->geometryBatcher;
break;
}
}
//Process Property Notifications
ProcessPropertyNotifications( bufferIndex );
- //Update geometry batcher
- mImpl->geometryBatcher.Update( bufferIndex );
-
//Process the RenderTasks; this creates the instructions for rendering the next frame.
//reset the update buffer index and make sure there is enough room in the instruction container
mImpl->renderInstructions.ResetAndReserve( bufferIndex,
mImpl->taskList,
*mImpl->root,
mImpl->sortedLayers,
- mImpl->geometryBatcher,
mImpl->renderInstructions );
// Process the system-level RenderTasks last
mImpl->systemLevelTaskList,
*mImpl->systemLevelRoot,
mImpl->systemLevelSortedLayers,
- mImpl->geometryBatcher,
mImpl->renderInstructions );
}
}
* @param[in] renderManager This is responsible for rendering the results of each "update".
* @param[in] renderQueue Used to queue messages for the next render.
* @param[in] textureCacheDispatcher Used for sending messages to texture cache.
- * @param[in] geometryBatcher Used when geometry batching is enabled.
* @param[in] renderTaskProcessor Handles RenderTasks and RenderInstrucitons.
*/
UpdateManager( NotificationManager& notificationManager,
RenderManager& renderManager,
RenderQueue& renderQueue,
TextureCacheDispatcher& textureCacheDispatcher,
- GeometryBatcher& geometryBatcher,
RenderTaskProcessor& renderTaskProcessor );
/**
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
#include <dali/internal/update/common/discard-queue.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/common/constants.h>
mWorldOrientation(), // Initialized to identity by default
mWorldMatrix(),
mWorldColor( Color::WHITE ),
- mGeometryBatcher( NULL ),
- mBatchIndex( BATCH_NULL_HANDLE ),
mClippingSortModifier( 0u ),
- mIsBatchParent( false ),
mParent( NULL ),
- mBatchParent( NULL ),
mExclusiveRenderTask( NULL ),
mChildren(),
mClippingDepth( 0u ),
}
mRenderer.PushBack( renderer );
-
- // Tell geometry batcher if should batch the child
- if( mRenderer.Size() == 1 && mRenderer[0]->mBatchingEnabled )
- {
- mGeometryBatcher->AddNode( this );
- }
}
void Node::RemoveRenderer( Renderer* renderer )
}
}
-void Node::SetBatchParent( Node* batchParentNode )
-{
- DALI_ASSERT_ALWAYS(!mIsRoot);
- mBatchParent = batchParentNode;
-}
-
-void Node::SetIsBatchParent( bool enabled )
-{
- if( mIsBatchParent != enabled )
- {
- mIsBatchParent = enabled;
-
- if( enabled )
- {
- mGeometryBatcher->AddBatchParent( this );
- }
- else
- {
- mGeometryBatcher->RemoveBatchParent( this );
- }
- }
-}
-
void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex )
{
DALI_ASSERT_ALWAYS(!mIsRoot);
class Layer;
class RenderTask;
class UpdateManager;
-class GeometryBatcher;
/**
* Flag whether property has changed, during the Update phase.
}
/**
- * @brief Turns on or off being a batch parent for the node
- * @param[in] enabled If true the node becomes a parent for batch of its children
- */
- void SetIsBatchParent( bool enabled );
-
- /**
* @brief Sets the sibling order of the node
* @param[in] order The new order
*/
*/
unsigned int GetDepthIndex(){ return mDepthIndex; }
- /**
- * @brief Tells if the node is a batch parent
- * @return True if node is a batch parent, false otherwise.
- */
- inline bool GetIsBatchParent()
- {
- return mIsBatchParent;
- }
-
- /**
- * Set the batch parent of a Node.
- * @param[in] batchParentNode The new batch parent.
- */
- void SetBatchParent( Node* batchParentNode );
-
- /**
- * Retrieve the batch parent of a Node.
- * @return The batch parent node, or NULL if the Node has not been added to the scene-graph.
- */
- Node* GetBatchParent() const
- {
- return mBatchParent;
- }
-
public:
/**
* @copydoc UniformMap::Add
TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix
InheritedColor mWorldColor; ///< Full inherited color
- GeometryBatcher* mGeometryBatcher; ///< A pointer to an instance of geometry batcher
- uint32_t mBatchIndex; ///< Batch 32bit handle, BATCH_NULL_HANDLE by default
uint32_t mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
- bool mIsBatchParent:1; ///< Marks node as a batch parent
-
protected:
Node* mParent; ///< Pointer to parent node (a child is owned by its parent)
- Node* mBatchParent; ///< Pointer to batch parent node
RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask
RendererContainer mRenderer; ///< Container of renderers; not owned
new (slot) LocalType( &node, &Node::RemoveRenderer, renderer );
}
-inline void SetIsBatchParentMessage( EventThreadServices& eventThreadServices, const Node& node, bool isBatchParent )
-{
- typedef MessageValue1< Node, bool > LocalType;
-
- // Reserve some memory inside the message queue
- unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
-
- // Construct message in the message queue memory; note that delete should not be called on the return value
- new (slot) LocalType( &node, &Node::SetIsBatchParent, isBatchParent );
-}
-
inline void SetDepthIndexMessage( EventThreadServices& eventThreadServices, const Node& node, unsigned int depthIndex )
{
typedef MessageValue1< Node, unsigned int > LocalType;
RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 17,
RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 18,
RESEND_WRITE_TO_COLOR_BUFFER = 1 << 19,
- RESEND_BATCHING_MODE = 1 << 20,
};
} // Anonymous namespace
mResourcesReady( false ),
mFinishedResourceAcquisition( false ),
mPremultipledAlphaEnabled( false ),
- mBatchingEnabled( false ),
mDepthIndex( 0 )
{
mUniformMapChanged[0] = false;
new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass );
}
- if( mResendFlag & RESEND_BATCHING_MODE )
- {
- typedef MessageValue1< Render::Renderer, bool > DerivedType;
- unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
- new (slot) DerivedType( mRenderer, &Render::Renderer::SetBatchingEnabled, mBatchingEnabled );
- }
-
mResendFlag = 0;
}
}
mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
}
-void Renderer::SetBatchingEnabled( bool batchingEnabled )
-{
- mBatchingEnabled = batchingEnabled;
- mResendFlag |= RESEND_BATCHING_MODE;
-}
-
//Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
{
void SetGeometry( Render::Geometry* geometry );
/**
- * Get the geometry of this renderer
- * @return the geometry this renderer uses
- */
- const Render::Geometry& GetGeometry() const
- {
- return *mGeometry;
- }
-
- /**
* Set the depth index
* @param[in] depthIndex the new depth index to use
*/
void SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass );
/**
- * Turns on batching feature for the renderer
- * @param[in] batchingEnabled if true, enables the batching mode for the renderer
- */
- void SetBatchingEnabled( bool batchingEnabled );
-
- /**
- * Tests whether batching feature is enabled for this renderer
- * @return batching state
- */
- bool IsBatchingEnabled() const
- {
- return mBatchingEnabled;
- }
-
- /**
* Prepare the object for rendering.
* This is called by the UpdateManager when an object is due to be rendered in the current frame.
* @param[in] updateBufferIndex The current update buffer index.
public:
- bool mBatchingEnabled:1; ///< Flag indicating whether the render supports batching
-
int mDepthIndex; ///< Used only in PrepareRenderInstructions
};
new (slot) LocalType( &renderer, &Renderer::SetStencilOperationOnZPass, stencilOperation );
}
-inline void SetBatchingEnabledMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, bool batchable )
-{
- typedef MessageValue1< Renderer, bool > LocalType;
-
- // Reserve some memory inside the message queue
- unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
-
- new (slot) LocalType( &renderer, &Renderer::SetBatchingEnabled, batchable );
-}
-
} // namespace SceneGraph
} // namespace Internal
} // namespace Dali