Merge "Remove dead code from tests." into devel/master
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-GeometryBatcher.cpp
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>
6
7 #include <dali-test-suite-utils.h>
8
9 namespace
10 {
11
12 class MockActor : public Dali::Internal::Actor
13 {
14 public:
15   inline const Dali::Internal::SceneGraph::Node* GetNode()
16   {
17     return mNode;
18   }
19
20   inline const bool IsNodeBatchParent()
21   {
22     return mNode->mIsBatchParent;
23   }
24 };
25
26 Geometry CreateBatchQuadGeometryVector2( Vector4 texCoords )
27 {
28   const float halfWidth = 0.5f;
29   const float halfHeight = 0.5f;
30   struct QuadVertex {
31     QuadVertex( const Vector2& vertexPosition, const Vector2& vertexTexCoords )
32       : position( vertexPosition ),
33         texCoords( vertexTexCoords )
34     {}
35     Vector2 position;
36     Vector2 texCoords;
37   };
38
39   // special case, when texture takes whole space
40   if( texCoords == Vector4::ZERO )
41   {
42     texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
43   }
44
45   QuadVertex quadVertexData[6] =
46   {
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) ),
53   };
54
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 );
60
61   // create geometry as normal, single quad
62   Geometry geometry = Geometry::New();
63   geometry.AddVertexBuffer( vertexBuffer );
64   geometry.SetType( Geometry::TRIANGLES );
65
66   return geometry;
67 }
68
69 Geometry CreateBatchQuadGeometryVector3( Vector4 texCoords )
70 {
71   const float halfWidth = 0.5f;
72   const float halfHeight = 0.5f;
73   struct QuadVertex {
74     QuadVertex( const Vector3& vertexPosition, const Vector2& vertexTexCoords )
75       : position( vertexPosition ),
76         texCoords( vertexTexCoords )
77     {}
78     Vector3 position;
79     Vector2 texCoords;
80   };
81
82   // special case, when texture takes whole space
83   if( texCoords == Vector4::ZERO )
84   {
85     texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
86   }
87
88   QuadVertex quadVertexData[6] =
89   {
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) ),
96   };
97
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 );
103
104   // create geometry as normal, single quad
105   Geometry geometry = Geometry::New();
106   geometry.AddVertexBuffer( vertexBuffer );
107   geometry.SetType( Geometry::TRIANGLES );
108   return geometry;
109 }
110
111 Geometry CreateBatchQuadGeometryVector4( Vector4 texCoords )
112 {
113   const float halfWidth = 0.5f;
114   const float halfHeight = 0.5f;
115   struct QuadVertex {
116     QuadVertex( const Vector4& vertexPosition, const Vector2& vertexTexCoords )
117       : position( vertexPosition ),
118         texCoords( vertexTexCoords )
119     {}
120     Vector4 position;
121     Vector2 texCoords;
122   };
123
124   // special case, when texture takes whole space
125   if( texCoords == Vector4::ZERO )
126   {
127     texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
128   }
129
130   QuadVertex quadVertexData[6] =
131   {
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) ),
138   };
139
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 );
145
146   // create geometry as normal, single quad
147   Geometry geometry = Geometry::New();
148   geometry.AddVertexBuffer( vertexBuffer );
149   geometry.SetType( Geometry::TRIANGLES );
150   return geometry;
151 }
152
153
154 void CreateShadersAndTextureSets( Shader* shaders, size_t shaderCount, TextureSet* textureSets, size_t textureSetCount )
155 {
156   for( size_t i = 0; i < shaderCount; ++i )
157   {
158     shaders[i] = Shader::New( "", "" );
159   }
160
161   for( size_t i = 0; i < textureSetCount; ++i )
162   {
163     textureSets[i] = TextureSet::New();
164   }
165 }
166
167 Vector4 WHOLE_IMAGE( 0.0f, 0.0f, 1.0f, 1.0f );
168
169 Actor CreateActor( Actor& parent, Shader& shader, TextureSet& textureSet, Vector3 position, Vector4 texCoords, Geometry(*geomfunc)(Vector4) = CreateBatchQuadGeometryVector2 )
170 {
171   Geometry geometry = geomfunc( texCoords );
172   Renderer renderer = Renderer::New( geometry, shader );
173
174   renderer.SetTextures( textureSet );
175   renderer.SetProperty( Dali::DevelRenderer::Property::BATCHING_ENABLED, true );
176
177   Actor actor = Actor::New();
178   actor.SetPosition( position );
179   parent.Add( actor );
180   actor.AddRenderer( renderer );
181   return actor;
182 }
183
184 Actor CreateBatchParent( Vector3 pos )
185 {
186   Actor actor = Actor::New();
187   actor.SetProperty( DevelActor::Property::BATCH_PARENT, true );
188   actor.SetPosition( pos );
189   Stage::GetCurrent().Add( actor );
190   return actor;
191 }
192
193 } // namespace
194
195 int UtcDaliGeometryBatcherBatchLevel0(void)
196 {
197   TestApplication app;
198   TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
199   glAbstraction.EnableDrawCallTrace( true );
200   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
201
202   Shader shaders[1];
203   TextureSet textureSets[1];
204
205   CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
206   Actor batchParent = CreateBatchParent( Vector3::ZERO );
207   batchParent.SetSize( Stage::GetCurrent().GetSize() );
208
209   Actor children[] = {
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 )
214   };
215
216   app.SendNotification();
217   app.Render( 16 );
218   app.SendNotification();
219   app.Render( 16 );
220
221   // should be 1 draw call
222   {
223     int result = drawTrace.CountMethod( "DrawElements");
224     DALI_TEST_CHECK( result == 1 );
225   }
226
227   // remove actor
228   batchParent.Remove( children[0] );
229   children[0].Reset();
230
231   // update
232   app.SendNotification();
233   app.Render( 16 );
234
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
240
241   Dali::Internal::Render::Geometry* geometry = geometryBatcher->GetGeometry( 0 );
242   int elementCount = geometry->GetPropertyBuffer(0)->GetElementCount();
243   DALI_TEST_CHECK( elementCount == 18 );
244
245   // delete batch parent
246   Stage::GetCurrent().Remove( batchParent );
247   batchParent.Reset();
248
249   // update
250   app.SendNotification();
251   app.Render( 16 );
252
253   END_TEST;
254 }
255
256 int UtcDaliGeometryBatcherBatchMultipleTextureSet(void)
257 {
258   TestApplication app;
259   TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
260   glAbstraction.EnableDrawCallTrace( true );
261   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
262
263   Shader shaders[1];
264   TextureSet textureSets[3];
265   CreateShadersAndTextureSets( shaders, 1, textureSets, 3 );
266
267   Actor batchParent = CreateBatchParent( Vector3::ZERO );
268   batchParent.SetSize( Stage::GetCurrent().GetSize() );
269
270   Actor children[] = {
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 )
283   };
284
285   // must update twice
286   app.SendNotification();
287   app.Render( 16 );
288   app.SendNotification();
289   app.Render( 16 );
290
291   // should be 3 draw calls here
292   {
293     int result = drawTrace.CountMethod( "DrawElements");
294     DALI_TEST_CHECK( result == 3 );
295   }
296
297   // test assigned indices
298   {
299     bool indicesTest( true );
300     for( size_t i = 0; i < 12; ++i )
301     {
302       MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( children[1] ) );
303       if( mockActor->GetNode()->mBatchIndex == BATCH_NULL_HANDLE )
304       {
305         indicesTest = false;
306       }
307     }
308     DALI_TEST_CHECK( indicesTest );
309   }
310
311   END_TEST;
312 }
313
314 int UtcDaliGeometryBatcherSettingBatchParent(void)
315 {
316   TestApplication app;
317
318   Shader shaders[1];
319   TextureSet textureSets[1];
320   CreateShadersAndTextureSets( shaders, 1, textureSets, 1 );
321
322   Actor batchParent = CreateBatchParent( Vector3::ZERO );
323   batchParent.SetSize( Stage::GetCurrent().GetSize() );
324   app.SendNotification();
325   app.Render( 16 );
326
327   MockActor* mockActor = static_cast<MockActor*>( &GetImplementation( batchParent ) );
328   DALI_TEST_CHECK( mockActor->IsNodeBatchParent() );
329
330   END_TEST;
331 }
332
333 int UtcDaliGeometryBatcherBatchMultipleParents(void)
334 {
335   TestApplication app;
336   TestGlAbstraction& glAbstraction = app.GetGlAbstraction();
337   glAbstraction.EnableDrawCallTrace( true );
338   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
339
340   Shader shaders[2];
341   TextureSet textureSets[2];
342   CreateShadersAndTextureSets( shaders, 2, textureSets, 2 );
343
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() );
350
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 );
363
364   // must update twice
365   app.SendNotification();
366   app.Render( 16 );
367   app.SendNotification();
368   app.Render( 16 );
369
370   // should be 3 draw calls here
371   {
372     int result = drawTrace.CountMethod( "DrawElements");
373     DALI_TEST_EQUALS( result, 3, TEST_LOCATION );
374   }
375
376   // delete batch parent
377   Stage::GetCurrent().Remove( batchParent1 );
378   batchParent1.Reset();
379   drawTrace.Reset();
380   app.SendNotification();
381   app.Render( 16 );
382   // should be 2 draw calls here
383   {
384     int result = drawTrace.CountMethod( "DrawElements");
385     DALI_TEST_EQUALS( result, 2, TEST_LOCATION );
386   }
387
388   END_TEST;
389 }