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 CreateActor( Vector3 position )
186 Actor actor = Actor::New();
187 actor.SetPosition( position );
192 Actor CreateBatchParent( Vector3 pos )
194 Actor actor = Actor::New();
195 actor.SetProperty( DevelActor::Property::BATCH_PARENT, true );
196 actor.SetPosition( pos );
197 Stage::GetCurrent().Add( actor );
201 void AddChildren( Actor parent, Actor* children, size_t size )
203 for( size_t i = 0; i < size; ++i )
205 parent.Add( children[i] );
211 int UtcDaliGeometryBatcherBatchLevel0(void)
214 TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
215 glAbstraction.EnableDrawCallTrace( true );
216 TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
219 TextureSet textureSets[1];
221 CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
222 Actor batchParent = CreateBatchParent( Vector3::ZERO );
223 batchParent.SetSize( Stage::GetCurrent().GetSize() );
226 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
227 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
228 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
229 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE )
232 app.SendNotification();
234 app.SendNotification();
237 // should be 1 draw call
239 int result = drawTrace.CountMethod( "DrawElements");
240 DALI_TEST_CHECK( result == 1 );
244 batchParent.Remove( children[0] );
248 app.SendNotification();
251 // test geometry for that batch, 1 batch, 3 children, 18 elements in the buffer
252 //Dali::Internal::Actor& actor = GetImplementation( children[1] );
253 MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
254 Dali::Internal::SceneGraph::GeometryBatcher* geometryBatcher = mockActor->GetNode()->mGeometryBatcher;
255 DALI_TEST_CHECK( geometryBatcher ); // must not be NULL
257 Dali::Internal::Render::Geometry* geometry = geometryBatcher->GetGeometry( 0 );
258 int elementCount = geometry->GetPropertyBuffer(0)->GetElementCount();
259 DALI_TEST_CHECK( elementCount == 18 );
261 // delete batch parent
262 Stage::GetCurrent().Remove( batchParent );
266 app.SendNotification();
272 int UtcDaliGeometryBatcherBatchMultipleTextureSet(void)
275 TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
276 glAbstraction.EnableDrawCallTrace( true );
277 TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
280 TextureSet textureSets[3];
281 CreateShadersAndTextureSets( shaders, 1, textureSets, 3 );
283 Actor batchParent = CreateBatchParent( Vector3::ZERO );
284 batchParent.SetSize( Stage::GetCurrent().GetSize() );
287 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
288 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
289 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
290 CreateActor( batchParent, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
291 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
292 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
293 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
294 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
295 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
296 CreateActor( batchParent, shaders[0], textureSets[1], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
297 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE ),
298 CreateActor( batchParent, shaders[0], textureSets[2], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE )
302 app.SendNotification();
304 app.SendNotification();
307 // should be 3 draw calls here
309 int result = drawTrace.CountMethod( "DrawElements");
310 DALI_TEST_CHECK( result == 3 );
313 // test assigned indices
315 bool indicesTest( true );
316 for( size_t i = 0; i < 12; ++i )
318 MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
319 if( mockActor->GetNode()->mBatchIndex == BATCH_NULL_HANDLE )
324 DALI_TEST_CHECK( indicesTest );
330 int UtcDaliGeometryBatcherSettingBatchParent(void)
335 TextureSet textureSets[1];
336 CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
338 Actor batchParent = CreateBatchParent( Vector3::ZERO );
339 batchParent.SetSize( Stage::GetCurrent().GetSize() );
340 app.SendNotification();
343 MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( batchParent ) );
344 DALI_TEST_CHECK( mockActor->IsNodeBatchParent() );
349 int UtcDaliGeometryBatcherBatchMultipleParents(void)
352 TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
353 glAbstraction.EnableDrawCallTrace( true );
354 TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
357 TextureSet textureSets[2];
358 CreateShadersAndTextureSets( shaders, 2, textureSets, 2 );
360 Actor batchParent0 = CreateBatchParent( Vector3::ZERO ); // Vector2
361 batchParent0.SetSize( Stage::GetCurrent().GetSize() );
362 Actor batchParent1 = CreateBatchParent( Vector3::ZERO ); // Vector3
363 batchParent1.SetSize( Stage::GetCurrent().GetSize() );
364 Actor batchParent2 = CreateBatchParent( Vector3::ZERO ); // Vector4
365 batchParent2.SetSize( Stage::GetCurrent().GetSize() );
367 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
368 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
369 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
370 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
371 CreateActor( batchParent0, shaders[0], textureSets[0], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE );
372 CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
373 CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 10.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
374 CreateActor( batchParent1, shaders[1], textureSets[1], Vector3( 20.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector3 );
375 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
376 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
377 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 30.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
378 CreateActor( batchParent2, shaders[0], textureSets[1], Vector3( 0.0f, 0.0f, 0.0f ), WHOLE_IMAGE, CreateBatchQuadGeometryVector4 );
381 app.SendNotification();
383 app.SendNotification();
386 // should be 3 draw calls here
388 int result = drawTrace.CountMethod( "DrawElements");
389 DALI_TEST_EQUALS( result, 3, TEST_LOCATION );
392 // delete batch parent
393 Stage::GetCurrent().Remove( batchParent1 );
394 batchParent1.Reset();
396 app.SendNotification();
398 // should be 2 draw calls here
400 int result = drawTrace.CountMethod( "DrawElements");
401 DALI_TEST_EQUALS( result, 2, TEST_LOCATION );