Dali 3D User Interface Engine
utc-image-loading-cancel-some-loads.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 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 // EXTERNAL INCLUDES
19 #include <set>
20 
21 // INTERNAL INCLUDES
23 
25 {
27 }
28 
30 {
32 }
33 
41 {
42  tet_printf( "Running load cancel load subset test.\n" );
43 
45 
46  // Start a bunch of loads that should work:
47 
49  unsigned loadsLaunched = 0;
50 
51  std::set<Integration::ResourceId> cancelledLoadSet;
53 
54  for( unsigned loadGroup = 0; loadGroup < NUM_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
55  {
56  const unsigned preIterationCompletions = resourceSink.mGrandTotalCompletions;
57 
58  // Issue load requests for a batch of images:
59  for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
60  {
61  const ImageParameters & loadParams = gCancelAttributes[ loadsLaunched % gCancelAttributes.size() ];
62  const BitmapResourceType bitmapResourceType( loadParams.first, loadParams.second.first, loadParams.second.second.first, loadParams.second.second.second );
63  const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
64  gAbstraction->LoadResource( ResourceRequest( resourceId, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
65  loadsLaunched += 1;
66  }
67 
68  // Let the first image in the batch start to load so we can try to cancel it in-flight:
69  usleep( 1 * 1000 ); //< 1 ms is enough to let an image start to load.
71 
72  // Cancel just two loads (hopefully one in-flight and one queued):
73 
74  // Cancel first load, hopefully while it is in-flight:
75  const ResourceId cancelledInFlight = loadGroup * NUM_VALID_IMAGES + 1;
76  gAbstraction->CancelLoad( cancelledInFlight, ResourceBitmap );
77  cancelledLoadSet.insert( cancelledInFlight );
78 
79  // Cancel second load, that is still queued:
80  const ResourceId cancelledFromQueue = loadGroup * NUM_VALID_IMAGES + NUM_VALID_IMAGES;
81  gAbstraction->CancelLoad( cancelledFromQueue, ResourceBitmap );
82  cancelledLoadSet.insert( cancelledFromQueue );
83 
84  // Drain a group worth of images so the cancellations hit in-flight loads on the next iteration:
85  for( unsigned i = 0; i < NUM_VALID_IMAGES * 1000 * 1000 * 10 / (5 * 1000) && resourceSink.mGrandTotalCompletions < preIterationCompletions + NUM_VALID_IMAGES - 2; ++i )
86  {
87  gAbstraction->GetResources( resourceSink );
88  usleep( 5 * 1000 );
89  }
90  }
91 
92  // Drain any spare completed loads until no new loads complete on an iteration:
93  unsigned lastNotifications = -1;
94  for( unsigned i = 0; i < MAX_NUM_RESOURCE_TRIES && resourceSink.mGrandTotalCompletions < loadsLaunched && resourceSink.mGrandTotalNotifications != lastNotifications; ++i )
95  {
96  lastNotifications = resourceSink.mGrandTotalNotifications;
97  gAbstraction->GetResources( resourceSink );
98  usleep( 70 * 1000 ); //< 70 ms should allow at least one medium image to load. You might to increase this to run on a slow device.
99  gAbstraction->GetResources( resourceSink );
100  usleep( 70 * 1000 );
101  gAbstraction->GetResources( resourceSink );
102  usleep( 70 * 1000 );
103  gAbstraction->GetResources( resourceSink );
104  }
105 
106  // Check the loads completed as expected:
107 
108  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
109  DALI_TEST_CHECK( loadsLaunched >= resourceSink.mGrandTotalCompletions );
110  DALI_TEST_CHECK( loadsLaunched >= resourceSink.mSuccessCounts.size() );
111  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
112 
113  // Check that if an image was not loaded, it is one of the ones that was cancelled:
114  // This is the main point of this test case.
115  std::vector<Integration::ResourceId> missingLoads;
116  for( unsigned resourceId = 1; resourceId <= NUM_LOAD_GROUPS_TO_ISSUE * NUM_VALID_IMAGES; ++resourceId )
117  {
118  // Was the load (not) completed?
119  if( resourceSink.mCompletionStatuses.find( resourceId ) == resourceSink.mCompletionStatuses.end() )
120  {
121  // Was the load (not) cancelled?
122  if( cancelledLoadSet.find( resourceId ) == cancelledLoadSet.end() )
123  {
124  // Whoa, the load was not completed and not cancelled either... so where did it go then?
125  missingLoads.push_back( resourceId );
126  tet_printf( "Missing load. ResourceId %u was not completed but was also not cancelled.\n", resourceId );
128  }
129  }
130  }
131  DALI_TEST_CHECK( missingLoads.size() == 0U );
132 
133  // Check that each success was reported exactly once:
134  for(ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
135  {
136  DALI_TEST_CHECK( it->second == 1u );
137  }
138 
139  END_TEST;
140 }
Dali Docs Home
Read more about Dali