1 #include <dali/public-api/dali-core.h>
2 #include <dali/devel-api/actors/actor-devel.h>
3 #include <dali/devel-api/rendering/renderer-devel.h>
4 #include <dali/internal/event/actors/actor-impl.h>
5 #include <dali/internal/update/manager/geometry-batcher.h>
7 #include <dali-test-suite-utils.h>
12 class MockActor : public Dali::Internal::Actor
15 inline const Dali::Internal::SceneGraph::Node* GetNode()
20 inline const bool IsNodeBatchParent()
22 return mNode->mIsBatchParent;
26 Geometry CreateBatchQuadGeometryVector2( Vector4 texCoords )
28 const float halfWidth = 0.5f;
29 const float halfHeight = 0.5f;
31 QuadVertex( const Vector2& vertexPosition, const Vector2& vertexTexCoords )
32 : position( vertexPosition ),
33 texCoords( vertexTexCoords )
39 // special case, when texture takes whole space
40 if( texCoords == Vector4::ZERO )
42 texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
45 QuadVertex quadVertexData[6] =
47 QuadVertex( Vector2(-halfWidth, -halfHeight ), Vector2(texCoords.x, texCoords.y) ),
48 QuadVertex( Vector2( halfWidth, -halfHeight ), Vector2(texCoords.z, texCoords.y) ),
49 QuadVertex( Vector2(-halfWidth, halfHeight ), Vector2(texCoords.x, texCoords.w) ),
50 QuadVertex( Vector2( halfWidth, -halfHeight ), Vector2(texCoords.z, texCoords.y) ),
51 QuadVertex( Vector2(-halfWidth, halfHeight ), Vector2(texCoords.x, texCoords.w) ),
52 QuadVertex( Vector2( halfWidth, halfHeight ), Vector2(texCoords.z, texCoords.w) ),
55 Property::Map vertexFormat;
56 vertexFormat[ "aPosition" ] = Property::VECTOR2;
57 vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
58 PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
59 vertexBuffer.SetData( quadVertexData, 6 );
61 // create geometry as normal, single quad
62 Geometry geometry = Geometry::New();
63 geometry.AddVertexBuffer( vertexBuffer );
64 geometry.SetType( Geometry::TRIANGLES );
69 Geometry CreateBatchQuadGeometryVector3( Vector4 texCoords )
71 const float halfWidth = 0.5f;
72 const float halfHeight = 0.5f;
74 QuadVertex( const Vector3& vertexPosition, const Vector2& vertexTexCoords )
75 : position( vertexPosition ),
76 texCoords( vertexTexCoords )
82 // special case, when texture takes whole space
83 if( texCoords == Vector4::ZERO )
85 texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
88 QuadVertex quadVertexData[6] =
90 QuadVertex( Vector3(-halfWidth, -halfHeight, 0.0f ), Vector2(texCoords.x, texCoords.y) ),
91 QuadVertex( Vector3( halfWidth, -halfHeight, 0.0f ), Vector2(texCoords.z, texCoords.y) ),
92 QuadVertex( Vector3(-halfWidth, halfHeight, 0.0f ), Vector2(texCoords.x, texCoords.w) ),
93 QuadVertex( Vector3( halfWidth, -halfHeight, 0.0f ), Vector2(texCoords.z, texCoords.y) ),
94 QuadVertex( Vector3(-halfWidth, halfHeight, 0.0f ), Vector2(texCoords.x, texCoords.w) ),
95 QuadVertex( Vector3( halfWidth, halfHeight, 0.0f ), Vector2(texCoords.z, texCoords.w) ),
98 Property::Map vertexFormat;
99 vertexFormat[ "aPosition" ] = Property::VECTOR3;
100 vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
101 PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
102 vertexBuffer.SetData( quadVertexData, 6 );
104 // create geometry as normal, single quad
105 Geometry geometry = Geometry::New();
106 geometry.AddVertexBuffer( vertexBuffer );
107 geometry.SetType( Geometry::TRIANGLES );
111 Geometry CreateBatchQuadGeometryVector4( Vector4 texCoords )
113 const float halfWidth = 0.5f;
114 const float halfHeight = 0.5f;
116 QuadVertex( const Vector4& vertexPosition, const Vector2& vertexTexCoords )
117 : position( vertexPosition ),
118 texCoords( vertexTexCoords )
124 // special case, when texture takes whole space
125 if( texCoords == Vector4::ZERO )
127 texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
130 QuadVertex quadVertexData[6] =
132 QuadVertex( Vector4(-halfWidth, -halfHeight, 0.0f, 1.0f ), Vector2(texCoords.x, texCoords.y) ),
133 QuadVertex( Vector4( halfWidth, -halfHeight, 0.0f, 1.0f ), Vector2(texCoords.z, texCoords.y) ),
134 QuadVertex( Vector4(-halfWidth, halfHeight, 0.0f, 1.0f ), Vector2(texCoords.x, texCoords.w) ),
135 QuadVertex( Vector4( halfWidth, -halfHeight, 0.0f, 1.0f ), Vector2(texCoords.z, texCoords.y) ),
136 QuadVertex( Vector4(-halfWidth, halfHeight, 0.0f, 1.0f ), Vector2(texCoords.x, texCoords.w) ),
137 QuadVertex( Vector4( halfWidth, halfHeight, 0.0f, 1.0f ), Vector2(texCoords.z, texCoords.w) ),
140 Property::Map vertexFormat;
141 vertexFormat[ "aPosition" ] = Property::VECTOR4;
142 vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
143 PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
144 vertexBuffer.SetData( quadVertexData, 6 );
146 // create geometry as normal, single quad
147 Geometry geometry = Geometry::New();
148 geometry.AddVertexBuffer( vertexBuffer );
149 geometry.SetType( Geometry::TRIANGLES );
154 void CreateShadersAndTextureSets( Shader* shaders, size_t shaderCount, TextureSet* textureSets, size_t textureSetCount )
156 for( size_t i = 0; i < shaderCount; ++i )
158 shaders[i] = Shader::New( "", "" );
161 for( size_t i = 0; i < textureSetCount; ++i )
163 textureSets[i] = TextureSet::New();
167 Vector4 WHOLE_IMAGE( 0.0f, 0.0f, 1.0f, 1.0f );
169 Actor CreateActor( Actor& parent, Shader& shader, TextureSet& textureSet, Vector3 position, Vector4 texCoords, Geometry(*geomfunc)(Vector4) = CreateBatchQuadGeometryVector2 )
171 Geometry geometry = geomfunc( texCoords );
172 Renderer renderer = Renderer::New( geometry, shader );
174 renderer.SetTextures( textureSet );
175 renderer.SetProperty( Dali::DevelRenderer::Property::BATCHING_ENABLED, true );
177 Actor actor = Actor::New();
178 actor.SetPosition( position );
180 actor.AddRenderer( renderer );
184 Actor CreateBatchParent( Vector3 pos )
186 Actor actor = Actor::New();
187 actor.SetProperty( DevelActor::Property::BATCH_PARENT, true );
188 actor.SetPosition( pos );
189 Stage::GetCurrent().Add( actor );
195 int UtcDaliGeometryBatcherBatchLevel0(void)
198 TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
199 glAbstraction.EnableDrawCallTrace( true );
200 TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
203 TextureSet textureSets[1];
205 CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
206 Actor batchParent = CreateBatchParent( Vector3::ZERO );
207 batchParent.SetSize( Stage::GetCurrent().GetSize() );
210 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
211 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
212 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
213 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE )
216 app.SendNotification();
218 app.SendNotification();
221 // should be 1 draw call
223 int result = drawTrace.CountMethod( "DrawElements");
224 DALI_TEST_CHECK( result == 1 );
228 batchParent.Remove( children[0] );
232 app.SendNotification();
235 // test geometry for that batch, 1 batch, 3 children, 18 elements in the buffer
236 //Dali::Internal::Actor& actor = GetImplementation( children[1] );
237 MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
238 Dali::Internal::SceneGraph::GeometryBatcher* geometryBatcher = mockActor->GetNode()->mGeometryBatcher;
239 DALI_TEST_CHECK( geometryBatcher ); // must not be NULL
241 Dali::Internal::Render::Geometry* geometry = geometryBatcher->GetGeometry( 0 );
242 int elementCount = geometry->GetPropertyBuffer(0)->GetElementCount();
243 DALI_TEST_CHECK( elementCount == 18 );
245 // delete batch parent
246 Stage::GetCurrent().Remove( batchParent );
250 app.SendNotification();
256 int UtcDaliGeometryBatcherBatchMultipleTextureSet(void)
259 TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
260 glAbstraction.EnableDrawCallTrace( true );
261 TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
264 TextureSet textureSets[3];
265 CreateShadersAndTextureSets( shaders, 1, textureSets, 3 );
267 Actor batchParent = CreateBatchParent( Vector3::ZERO );
268 batchParent.SetSize( Stage::GetCurrent().GetSize() );
271 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
272 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
273 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
274 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
275 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
276 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
277 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
278 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
279 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
280 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
281 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
282 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE )
286 app.SendNotification();
288 app.SendNotification();
291 // should be 3 draw calls here
293 int result = drawTrace.CountMethod( "DrawElements");
294 DALI_TEST_CHECK( result == 3 );
297 // test assigned indices
299 bool indicesTest( true );
300 for( size_t i = 0; i < 12; ++i )
302 MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
303 if( mockActor->GetNode()->mBatchIndex == BATCH_NULL_HANDLE )
308 DALI_TEST_CHECK( indicesTest );
314 int UtcDaliGeometryBatcherSettingBatchParent(void)
319 TextureSet textureSets[1];
320 CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
322 Actor batchParent = CreateBatchParent( Vector3::ZERO );
323 batchParent.SetSize( Stage::GetCurrent().GetSize() );
324 app.SendNotification();
327 MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( batchParent ) );
328 DALI_TEST_CHECK( mockActor->IsNodeBatchParent() );
333 int UtcDaliGeometryBatcherBatchMultipleParents(void)
336 TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
337 glAbstraction.EnableDrawCallTrace( true );
338 TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
341 TextureSet textureSets[2];
342 CreateShadersAndTextureSets( shaders, 2, textureSets, 2 );
344 Actor batchParent0 = CreateBatchParent( Vector3::ZERO ); // Vector2
345 batchParent0.SetSize( Stage::GetCurrent().GetSize() );
346 Actor batchParent1 = CreateBatchParent( Vector3::ZERO ); // Vector3
347 batchParent1.SetSize( Stage::GetCurrent().GetSize() );
348 Actor batchParent2 = CreateBatchParent( Vector3::ZERO ); // Vector4
349 batchParent2.SetSize( Stage::GetCurrent().GetSize() );
351 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
352 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
353 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
354 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
355 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
356 CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
357 CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
358 CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
359 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
360 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
361 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
362 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
365 app.SendNotification();
367 app.SendNotification();
370 // should be 3 draw calls here
372 int result = drawTrace.CountMethod( "DrawElements");
373 DALI_TEST_EQUALS( result, 3, TEST_LOCATION );
376 // delete batch parent
377 Stage::GetCurrent().Remove( batchParent1 );
378 batchParent1.Reset();
380 app.SendNotification();
382 // should be 2 draw calls here
384 int result = drawTrace.CountMethod( "DrawElements");
385 DALI_TEST_EQUALS( result, 2, TEST_LOCATION );