2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali/devel-api/rendering/renderer.h>
20 #include <dali/public-api/common/dali-common.h>
21 #include <dali/integration-api/resource-policies.h>
22 #include <dali/integration-api/debug.h>
26 using namespace Dali::Toolkit;
31 const char* IMAGE_PATH[] = {
32 DALI_IMAGE_DIR "gallery-medium-1.jpg",
33 DALI_IMAGE_DIR "gallery-medium-2.jpg",
34 DALI_IMAGE_DIR "gallery-medium-3.jpg",
35 DALI_IMAGE_DIR "gallery-medium-4.jpg",
36 DALI_IMAGE_DIR "gallery-medium-5.jpg",
37 DALI_IMAGE_DIR "gallery-medium-6.jpg",
38 DALI_IMAGE_DIR "gallery-medium-7.jpg",
39 DALI_IMAGE_DIR "gallery-medium-8.jpg",
40 DALI_IMAGE_DIR "gallery-medium-9.jpg",
41 DALI_IMAGE_DIR "gallery-medium-10.jpg",
42 DALI_IMAGE_DIR "gallery-medium-11.jpg",
43 DALI_IMAGE_DIR "gallery-medium-12.jpg",
44 DALI_IMAGE_DIR "gallery-medium-13.jpg",
45 DALI_IMAGE_DIR "gallery-medium-14.jpg",
46 DALI_IMAGE_DIR "gallery-medium-15.jpg",
47 DALI_IMAGE_DIR "gallery-medium-16.jpg",
48 DALI_IMAGE_DIR "gallery-medium-17.jpg",
49 DALI_IMAGE_DIR "gallery-medium-18.jpg",
50 DALI_IMAGE_DIR "gallery-medium-19.jpg",
51 DALI_IMAGE_DIR "gallery-medium-20.jpg",
52 DALI_IMAGE_DIR "gallery-medium-21.jpg",
53 DALI_IMAGE_DIR "gallery-medium-22.jpg",
54 DALI_IMAGE_DIR "gallery-medium-23.jpg",
55 DALI_IMAGE_DIR "gallery-medium-24.jpg",
56 DALI_IMAGE_DIR "gallery-medium-25.jpg",
57 DALI_IMAGE_DIR "gallery-medium-26.jpg",
58 DALI_IMAGE_DIR "gallery-medium-27.jpg",
59 DALI_IMAGE_DIR "gallery-medium-28.jpg",
60 DALI_IMAGE_DIR "gallery-medium-29.jpg",
61 DALI_IMAGE_DIR "gallery-medium-30.jpg",
62 DALI_IMAGE_DIR "gallery-medium-31.jpg",
63 DALI_IMAGE_DIR "gallery-medium-32.jpg",
64 DALI_IMAGE_DIR "gallery-medium-33.jpg",
65 DALI_IMAGE_DIR "gallery-medium-34.jpg",
66 DALI_IMAGE_DIR "gallery-medium-35.jpg",
67 DALI_IMAGE_DIR "gallery-medium-36.jpg",
68 DALI_IMAGE_DIR "gallery-medium-37.jpg",
69 DALI_IMAGE_DIR "gallery-medium-38.jpg",
70 DALI_IMAGE_DIR "gallery-medium-39.jpg",
71 DALI_IMAGE_DIR "gallery-medium-40.jpg",
72 DALI_IMAGE_DIR "gallery-medium-41.jpg",
73 DALI_IMAGE_DIR "gallery-medium-42.jpg",
74 DALI_IMAGE_DIR "gallery-medium-43.jpg",
75 DALI_IMAGE_DIR "gallery-medium-44.jpg",
76 DALI_IMAGE_DIR "gallery-medium-45.jpg",
77 DALI_IMAGE_DIR "gallery-medium-46.jpg",
78 DALI_IMAGE_DIR "gallery-medium-47.jpg",
79 DALI_IMAGE_DIR "gallery-medium-48.jpg",
80 DALI_IMAGE_DIR "gallery-medium-49.jpg",
81 DALI_IMAGE_DIR "gallery-medium-50.jpg",
82 DALI_IMAGE_DIR "gallery-medium-51.jpg",
83 DALI_IMAGE_DIR "gallery-medium-52.jpg",
84 DALI_IMAGE_DIR "gallery-medium-53.jpg",
87 const unsigned int NUM_IMAGES = sizeof(IMAGE_PATH) / sizeof(char*);
89 const float ANIMATION_TIME ( 5.0f ); // animation length in seconds
91 struct VertexWithTexture
97 VertexWithTexture gQuadWithTexture[] = {
98 { Vector2( -0.5f, -0.5f ), Vector2( 0.0f, 0.0f ) },
99 { Vector2( 0.5f, -0.5f ), Vector2( 1.0f, 0.0f ) },
100 { Vector2( -0.5f, 0.5f ), Vector2( 0.0f, 1.0f ) },
101 { Vector2( 0.5f, 0.5f ), Vector2( 1.0f, 1.0f ) }
104 const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
105 attribute mediump vec2 aPosition;\n
106 attribute mediump vec2 aTexCoord;\n
107 uniform mediump mat4 uMvpMatrix;\n
108 uniform mediump vec3 uSize;\n
109 varying mediump vec2 vTexCoord;\n
112 vec4 position = vec4(aPosition,0.0,1.0)*vec4(uSize,1.0);\n
113 gl_Position = uMvpMatrix * position;\n
114 vTexCoord = aTexCoord;\n
118 const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
119 uniform lowp vec4 uColor;\n
120 uniform sampler2D sTexture;\n
121 varying mediump vec2 vTexCoord;\n
125 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
132 static Geometry mesh;
135 PropertyBuffer vertexBuffer;
136 Property::Map vertexFormat;
137 vertexFormat["aPosition"] = Property::VECTOR2;
138 vertexFormat["aTexCoord"] = Property::VECTOR2;
140 //Create a vertex buffer for vertex positions and texture coordinates
141 vertexBuffer = PropertyBuffer::New( vertexFormat, 4u );
142 vertexBuffer.SetData( gQuadWithTexture );
144 //Create the geometry
145 mesh = Geometry::New();
146 mesh.AddVertexBuffer( vertexBuffer );
147 mesh.SetGeometryType(Geometry::TRIANGLE_STRIP );
152 Renderer CreateRenderer( unsigned int index )
154 static Renderer renderers[NUM_IMAGES];
155 if( !renderers[index] )
157 //Create the renderer
158 Shader shader = Shader::New( VERTEX_SHADER_TEXTURE, FRAGMENT_SHADER_TEXTURE );
159 Image image = ResourceImage::New(IMAGE_PATH[index]);
160 Sampler textureSampler = Sampler::New( image, "sTexture" );
161 Material material = Material::New( shader );
162 material.AddSampler(textureSampler);
163 material.SetBlendMode( BlendingMode::OFF );
164 renderers[index] = Renderer::New( QuadMesh(), material );
166 return renderers[index];
169 Actor CreateMeshActor( unsigned int index)
171 Renderer renderer = CreateRenderer(index);
172 Actor meshActor = Actor::New();
173 meshActor.AddRenderer( renderer );
177 bool gUseMesh(false);
178 bool gUseImageView(false);
179 unsigned int gRowsPerPage(25);
180 unsigned int gColumnsPerPage( 25 );
181 unsigned int gPageCount(13);
185 // Test application to compare performance between ImageActor and ImageView
186 // By default, the application consist of 10 pages of 25x25 ImageActors, this can be modified using the following command line arguments:
187 // -r NumberOfRows (Modifies the number of rows per page)
188 // -c NumberOfColumns (Modifies the number of columns per page)
189 // -p NumberOfPages (Modifies the nimber of pages )
190 // --use-imageview ( Use ImageView instead of ImageActor )
191 // --use-mesh ( Use new renderer API (as ImageView) but shares renderers between actors when possible )
194 class Benchmark : public ConnectionTracker
198 Benchmark( Application& application )
199 : mApplication( application ),
200 mRowsPerPage( gRowsPerPage ),
201 mColumnsPerPage( gColumnsPerPage ),
202 mPageCount( gPageCount )
204 // Connect to the Application's Init signal
205 mApplication.InitSignal().Connect( this, &Benchmark::Create );
210 // Nothing to do here;
213 // The Init signal is received once (only) during the Application lifetime
214 void Create( Application& application )
216 // Get a handle to the stage
217 Stage stage = Stage::GetCurrent();
218 stage.SetBackgroundColor( Color::WHITE );
219 Vector2 stageSize = stage.GetSize();
221 stage.GetRootLayer().SetDepthTestDisabled(true);
223 mSize = Vector3( stageSize.x / mColumnsPerPage, stageSize.y / mRowsPerPage, 0.0f );
225 // Respond to a click anywhere on the stage
226 stage.GetRootLayer().TouchedSignal().Connect( this, &Benchmark::OnTouch );
232 else if( gUseImageView )
244 bool OnTouch( Actor actor, const TouchEvent& touch )
246 // quit the application
251 void CreateImageActors()
253 Stage stage = Stage::GetCurrent();
254 unsigned int actorCount(mRowsPerPage*mColumnsPerPage * mPageCount);
255 mActor.resize(actorCount);
257 for( size_t i(0); i<actorCount; ++i )
259 Image image = ResourceImage::New(IMAGE_PATH[i % NUM_IMAGES]);
260 mActor[i] = ImageActor::New(image);
261 mActor[i].SetSize(Vector3(0.0f,0.0f,0.0f));
262 mActor[i].SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
263 stage.Add(mActor[i]);
267 void CreateImageViews()
269 Stage stage = Stage::GetCurrent();
270 unsigned int actorCount(mRowsPerPage*mColumnsPerPage * mPageCount);
271 mImageView.resize(actorCount);
273 for( size_t i(0); i<actorCount; ++i )
275 Image image = ResourceImage::New(IMAGE_PATH[i % NUM_IMAGES]);
276 mImageView[i] = ImageView::New(image);
277 mImageView[i].SetSize(Vector3(0.0f,0.0f,0.0f));
278 mImageView[i].SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
279 stage.Add(mImageView[i]);
283 void CreateMeshActors()
285 Stage stage = Stage::GetCurrent();
286 unsigned int actorCount(mRowsPerPage*mColumnsPerPage * mPageCount);
287 mActor.resize(actorCount);
288 for( size_t i(0); i<actorCount; ++i )
290 mActor[i] = CreateMeshActor(i % NUM_IMAGES);
291 mActor[i].SetSize(0.0f,0.0f,0.0f);
293 stage.Add(mActor[i]);
297 void OnAnimationEnd( Animation& source )
299 if( source == mShow )
303 else if( source == mScroll )
315 Stage stage = Stage::GetCurrent();
316 Vector3 initialPosition( stage.GetSize().x * 0.5f, stage.GetSize().y*0.5f, 1000.0f );
318 unsigned int totalColumns = mColumnsPerPage * mPageCount;
322 mShow = Animation::New(0.0f);
324 float totalDuration( 10.0f );
325 float durationPerActor( 0.5f );
326 float delayBetweenActors = ( totalDuration - durationPerActor) / (mRowsPerPage*mColumnsPerPage);
327 for( size_t i(0); i<totalColumns; ++i )
331 for( size_t j(0);j<mRowsPerPage;++j)
337 float duration = 0.0f;
338 if( count < mRowsPerPage*mColumnsPerPage )
340 duration = durationPerActor;
341 delay = delayBetweenActors * count;
345 mImageView[count].SetPosition( initialPosition );
346 mImageView[count].SetSize( Vector3(0.0f,0.0f,0.0f) );
347 mImageView[count].SetOrientation( Quaternion( Radian(0.0f),Vector3::XAXIS));
348 mShow.AnimateTo( Property( mImageView[count], Actor::Property::POSITION), Vector3(xpos+mSize.x*0.5f, ypos+mSize.y*0.5f, 0.0f), AlphaFunction::EASE_OUT_BACK, TimePeriod( delay, duration ));
349 mShow.AnimateTo( Property( mImageView[count], Actor::Property::SIZE), mSize, AlphaFunction::EASE_OUT_BACK, TimePeriod( delay, duration ));
353 mActor[count].SetPosition( initialPosition );
354 mActor[count].SetSize( Vector3(0.0f,0.0f,0.0f) );
355 mActor[count].SetOrientation( Quaternion( Radian(0.0f),Vector3::XAXIS));
356 mShow.AnimateTo( Property( mActor[count], Actor::Property::POSITION), Vector3(xpos+mSize.x*0.5f, ypos+mSize.y*0.5f, 0.0f), AlphaFunction::EASE_OUT_BACK, TimePeriod( delay, duration ));
357 mShow.AnimateTo( Property( mActor[count], Actor::Property::SIZE), mSize, AlphaFunction::EASE_OUT_BACK, TimePeriod( delay, duration ));
363 mShow.FinishedSignal().Connect( this, &Benchmark::OnAnimationEnd );
366 void ScrollAnimation()
368 Stage stage = Stage::GetCurrent();
369 Vector3 stageSize( stage.GetSize() );
371 mScroll = Animation::New(10.0f);
372 size_t actorCount( mRowsPerPage*mColumnsPerPage*mPageCount);
373 for( size_t i(0); i<actorCount; ++i )
377 mScroll.AnimateBy( Property( mImageView[i], Actor::Property::POSITION), Vector3(-4.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(0.0f,3.0f));
378 mScroll.AnimateBy( Property( mImageView[i], Actor::Property::POSITION), Vector3(-4.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(3.0f,3.0f));
379 mScroll.AnimateBy( Property( mImageView[i], Actor::Property::POSITION), Vector3(-4.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(6.0f,2.0f));
380 mScroll.AnimateBy( Property( mImageView[i], Actor::Property::POSITION), Vector3( 12.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(8.0f,2.0f));
384 mScroll.AnimateBy( Property( mActor[i], Actor::Property::POSITION), Vector3(-4.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(0.0f,3.0f));
385 mScroll.AnimateBy( Property( mActor[i], Actor::Property::POSITION), Vector3(-4.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(3.0f,3.0f));
386 mScroll.AnimateBy( Property( mActor[i], Actor::Property::POSITION), Vector3(-4.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(6.0f,2.0f));
387 mScroll.AnimateBy( Property( mActor[i], Actor::Property::POSITION), Vector3( 12.0f*stageSize.x,0.0f, 0.0f), AlphaFunction::EASE_OUT, TimePeriod(8.0f,2.0f));
391 mScroll.FinishedSignal().Connect( this, &Benchmark::OnAnimationEnd );
397 unsigned int actorsPerPage( mRowsPerPage*mColumnsPerPage );
398 mHide = Animation::New(0.0f);
400 unsigned int totalColumns = mColumnsPerPage * mPageCount;
402 float totalDuration( 5.0f);
403 float durationPerActor( 0.5f );
404 float delayBetweenActors = ( totalDuration - durationPerActor) / (mRowsPerPage*mColumnsPerPage);
405 for( size_t i(0); i<mRowsPerPage; ++i )
407 for( size_t j(0);j<totalColumns;++j)
410 float duration = 0.0f;
411 if( count < actorsPerPage )
413 duration = durationPerActor;
414 delay = delayBetweenActors * count;
419 mHide.AnimateTo( Property( mImageView[count], Actor::Property::ORIENTATION), Quaternion( Radian( Degree( 70.0f ) ), Vector3::XAXIS ), AlphaFunction::EASE_OUT, TimePeriod( delay, duration ));
420 mHide.AnimateBy( Property( mImageView[count], Actor::Property::POSITION_Z), 1000.0f, AlphaFunction::EASE_OUT_BACK, TimePeriod( delay +delayBetweenActors*actorsPerPage + duration, duration ));
424 mHide.AnimateTo( Property( mActor[count], Actor::Property::ORIENTATION), Quaternion( Radian( Degree( 70.0f ) ), Vector3::XAXIS ), AlphaFunction::EASE_OUT, TimePeriod( delay, duration ));
425 mHide.AnimateBy( Property( mActor[count], Actor::Property::POSITION_Z), 1000.0f, AlphaFunction::EASE_OUT_BACK, TimePeriod( delay +delayBetweenActors*actorsPerPage + duration, duration ));
432 mHide.FinishedSignal().Connect( this, &Benchmark::OnAnimationEnd );
436 Application& mApplication;
438 std::vector<Actor> mActor;
439 std::vector<ImageView> mImageView;
442 unsigned int mRowsPerPage;
443 unsigned int mColumnsPerPage;
444 unsigned int mPageCount;
451 void RunTest( Application& application )
453 Benchmark test( application );
455 application.MainLoop();
458 // Entry point for Linux & Tizen applications
460 int main( int argc, char **argv )
462 Application application = Application::New( &argc, &argv );
464 for( int i(1) ; i < argc; ++i )
466 std::string arg( argv[i] );
467 if( arg.compare("--use-mesh") == 0)
471 else if( arg.compare("--use-imageview") == 0)
473 gUseImageView = true;
475 else if( arg.compare(0, 2, "-r" ) == 0)
477 gRowsPerPage = atoi( arg.substr( 2, arg.size()).c_str());
479 else if( arg.compare(0, 2, "-c" ) == 0)
481 gColumnsPerPage = atoi( arg.substr( 2, arg.size()).c_str());
483 else if( arg.compare(0, 2, "-p" ) == 0)
485 gPageCount = atoi( arg.substr( 2, arg.size()).c_str());
491 RunTest( application );