Dali 3D User Interface Engine
utc-Dali-ImageAtlas.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <dali/dali.h>
26 
27 using namespace Dali;
28 using namespace Dali::Toolkit;
29 
30 namespace
31 {
32 // resolution: 34*34, pixel format: RGBA8888
33 static const char* gImage_34_RGBA = TEST_RESOURCE_DIR "/icon-edit.png";
34 // resolution: 50*50, pixel format: RGBA8888
35 static const char* gImage_50_RGBA = TEST_RESOURCE_DIR "/icon-delete.png";
36 // resolution: 128*128, pixel format: RGB888
37 static const char* gImage_128_RGB = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
38 
39 // this is image is not exist, for negative test
40 static const char* gImageNonExist = "non-exist.jpg";
41 
42 const int RENDER_FRAME_INTERVAL = 16;
43 
44 Rect<int> TextureCoordinateToPixelArea( const Vector4& textureCoordinate, float size )
45 {
46  Vector4 temp = textureCoordinate * size;
47  Rect<int> pixelArea;
48  pixelArea.x = static_cast<int>( temp.x );
49  pixelArea.y = static_cast<int>( temp.y );
50  pixelArea.width = static_cast<int>( temp.z-temp.x+1.f );
51  pixelArea.height = static_cast<int>( temp.w-temp.y+1.f );
52 
53  return pixelArea;
54 }
55 
56 bool IsOverlap( Rect<int> rect1, Rect<int> rect2 )
57 {
58  return rect1.x < rect2.x+rect2.width
59  && rect2.x < rect1.x+rect1.width
60  && rect1.y < rect2.y+rect2.height
61  && rect2.y < rect1.y+rect1.height;
62 }
63 
64 }
65 
67 {
69 }
70 
72 {
74 }
75 
77 {
78  ToolkitTestApplication application;
79 
80  // invoke default handle constructor
81  ImageAtlas atlas;
82 
83  DALI_TEST_CHECK( !atlas );
84 
85  // initialise handle
86  atlas = ImageAtlas::New( 32, 32 );
87 
88  DALI_TEST_CHECK( atlas );
89  END_TEST;
90 }
91 
93 {
94  ToolkitTestApplication application;
95 
96  ImageAtlas atlas = ImageAtlas::New( 32, 32);
97  ImageAtlas atlasCopy(atlas);
98 
99  DALI_TEST_EQUALS( (bool)atlasCopy, true, TEST_LOCATION );
100  END_TEST;
101 }
102 
104 {
105  ToolkitTestApplication application;
106 
107  ImageAtlas atlas = ImageAtlas::New( 32, 32 );
108 
109  ImageAtlas atlas2;
110  DALI_TEST_EQUALS( (bool)atlas2, false, TEST_LOCATION );
111 
112  atlas2 = atlas;
113  DALI_TEST_EQUALS( (bool)atlas2, true, TEST_LOCATION );
114 
115  END_TEST;
116 }
117 
119 {
120  ToolkitTestApplication application;
121 
122  ImageAtlas atlas = ImageAtlas::New( 32, 32 );
123  Image image = atlas.GetAtlas();
124 
125  // test the atlas created
126  DALI_TEST_EQUALS( (bool)image, true, TEST_LOCATION );
127  DALI_TEST_CHECK( image.GetHeight() == 32u );
128  DALI_TEST_CHECK( image.GetWidth() == 32u );
129 
130  Atlas coreAtlas = Atlas::DownCast( image );
131  DALI_TEST_EQUALS( (bool)coreAtlas, true, TEST_LOCATION );
132 
133  END_TEST;
134 }
135 
137 {
138  ToolkitTestApplication application;
139  unsigned int size = 200;
140  ImageAtlas atlas = ImageAtlas::New( size, size );
141 
142  Vector4 textureRect;
143  atlas.Upload( textureRect, gImageNonExist );
145 
146  // Set broken image
147  TestPlatformAbstraction& platform = application.GetPlatform();
148  platform.SetClosestImageSize(Vector2( 34, 34));
150 
151  // the non-exit image will be replaced with the broken image
152  platform.SetClosestImageSize(Vector2( 0, 0));
153  atlas.Upload( textureRect, gImageNonExist );
154 
155  Rect<int> pixelArea = TextureCoordinateToPixelArea(textureRect, size);
156  DALI_TEST_EQUALS( pixelArea.width, 34, TEST_LOCATION );
157  DALI_TEST_EQUALS( pixelArea.height, 34, TEST_LOCATION );
158 
159  END_TEST;
160 }
161 
163 {
164  ToolkitTestApplication application;
165  unsigned int size = 200;
166  ImageAtlas atlas = ImageAtlas::New( size, size );
167 
169  CallbackBase* callback = eventTrigger->GetCallback();
170 
171  TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
172  callStack.Reset();
173  callStack.Enable(true);
174 
175  Vector4 textureRect1;
176  atlas.Upload( textureRect1, gImage_34_RGBA, ImageDimensions(34, 34) );
177  Vector4 textureRect2;
178  atlas.Upload( textureRect2, gImage_50_RGBA, ImageDimensions(50, 50) );
179  Vector4 textureRect3;
180  atlas.Upload( textureRect3, gImage_128_RGB, ImageDimensions(128, 128) );
181 
182  eventTrigger->WaitingForTrigger( 3 );// waiting until all three images are loaded
183 
184  CallbackBase::Execute( *callback );
185 
186  application.SendNotification();
187  application.Render(RENDER_FRAME_INTERVAL);
188 
189  callStack.Enable(false);
190 
191  Rect<int> pixelArea1 = TextureCoordinateToPixelArea(textureRect1, size);
192  DALI_TEST_EQUALS( pixelArea1.width, 34, TEST_LOCATION );
193  DALI_TEST_EQUALS( pixelArea1.height, 34, TEST_LOCATION );
194  std::stringstream out;
195  out<<pixelArea1.x<<", "<<pixelArea1.y<<", "<<pixelArea1.width<<", "<<pixelArea1.height;
196  DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", out.str()) );
197 
198  Rect<int> pixelArea2 = TextureCoordinateToPixelArea(textureRect2, size);
199  DALI_TEST_EQUALS( pixelArea2.width, 50, TEST_LOCATION );
200  DALI_TEST_EQUALS( pixelArea2.height, 50, TEST_LOCATION );
201  out.str("");
202  out<<pixelArea2.x<<", "<<pixelArea2.y<<", "<<pixelArea2.width<<", "<<pixelArea2.height;
203  DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", out.str()) );
204 
205  Rect<int> pixelArea3 = TextureCoordinateToPixelArea(textureRect3, size);
206  DALI_TEST_EQUALS( pixelArea3.width, 128, TEST_LOCATION );
207  DALI_TEST_EQUALS( pixelArea3.height, 128, TEST_LOCATION );
208  out.str("");
209  out<<pixelArea3.x<<", "<<pixelArea3.y<<", "<<pixelArea3.width<<", "<<pixelArea3.height;
210  DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", out.str()) );
211 
212  DALI_TEST_CHECK( ! IsOverlap(pixelArea1, pixelArea2) );
213  DALI_TEST_CHECK( ! IsOverlap(pixelArea1, pixelArea3) );
214  DALI_TEST_CHECK( ! IsOverlap(pixelArea2, pixelArea3) );
215 
216  END_TEST;
217 }
218 
220 {
221  TestApplication application;
222  unsigned int size = 100;
223  ImageAtlas atlas = ImageAtlas::New( size, size );
224  Vector4 textureRect1;
225  atlas.Upload( textureRect1, gImage_34_RGBA, ImageDimensions(34, 34) );
226 
227  atlas.Remove( textureRect1 );
228 
229  Vector4 textureRect2;
230  atlas.Upload( textureRect2, gImage_50_RGBA, ImageDimensions(50, 50) );
231 
232  // one pixel gap
233  Rect<int> pixelArea = TextureCoordinateToPixelArea(textureRect2, size);
234  DALI_TEST_EQUALS( pixelArea.x, 0, TEST_LOCATION );
235  DALI_TEST_EQUALS( pixelArea.y, 0, TEST_LOCATION );
236 
237  END_TEST;
238 }
239 
241 {
242  ToolkitTestApplication application;
243 
244  TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
245  callStack.Reset();
246  callStack.Enable(true);
247 
248  ImageView imageView1 = ImageView::New( gImage_34_RGBA, ImageDimensions(34, 34) );
249  ImageView imageView2 = ImageView::New( gImage_50_RGBA, ImageDimensions(50, 50) );
250  Stage::GetCurrent().Add( imageView1 );
251  Stage::GetCurrent().Add( imageView2 );
252 
254  while( eventTrigger == NULL) // waiting uintil the ImageAtlas is created by ImageAtlasManager
255  {
256  usleep(10);
257  eventTrigger = EventThreadCallback::Get();
258  }
259  CallbackBase* callback = eventTrigger->GetCallback();
260 
261  eventTrigger->WaitingForTrigger( 2 );// waiting until both images are loaded
262 
263  CallbackBase::Execute( *callback );
264 
265  application.SendNotification();
266  application.Render(RENDER_FRAME_INTERVAL);
267 
268  callStack.Enable(false);
269 
270  DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 0, 34, 34" ) );
271  DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 34, 50, 50" ) );
272 
273  callStack.Reset();
274  callStack.Enable(true);
275 
276  // remove the imageView2 from stage, the second image will also be removed from atlas
277  // then the space on the atlas will be used by the third image added.
278  Stage::GetCurrent().Remove( imageView2 );
279  application.SendNotification();
280  application.Render(RENDER_FRAME_INTERVAL);
281  ImageView imageView3 = ImageView::New( gImage_128_RGB, ImageDimensions(100, 100) );
282  Stage::GetCurrent().Add( imageView3 );
283 
284  eventTrigger->WaitingForTrigger( 3 ); // waiting for the third image loaded
285  CallbackBase::Execute( *callback );
286 
287  application.SendNotification();
288  application.Render(RENDER_FRAME_INTERVAL);
289 
290  callStack.Enable(false);
291  DALI_TEST_CHECK( callStack.FindMethodAndParams("TexSubImage2D", "0, 34, 100, 100" ) );
292 
293  END_TEST;
294 }
Dali Docs Home
Read more about Dali