1 /***************************************************************************
2 *
3 * Copyright 2012 BMW Car IT GmbH
4 *
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ****************************************************************************/
19
20 #include "LMControl.h"
21
22 #include <algorithm>
23 using std::find;
24
25 #include <cstdio>
26
27 #include <iterator>
28 using std::iterator;
29
30 #include <iostream>
31 using std::cout;
32 using std::cin;
33 using std::endl;
34
35 #include <iomanip>
36 using std::dec;
37 using std::hex;
38 using std::left;
39 using std::right;
40 using std::setw;
41
42 #include <cmath>
43 using std::max;
44 using std::min;
45
46 #include <string>
47 using std::string;
48
49 #include <vector>
50 using std::vector;
51
52 namespace
53 {
analyzePrintHelper(string tag,string flag,string description)54 void analyzePrintHelper(string tag, string flag, string description)
55 {
56 cout << left << setw(25) << tag << " | " << setw(7) << flag << " | " << description << endl;
57 }
58
analyzeVisibilityAndOpacity(t_ilm_surface targetSurfaceId,t_scene_data & scene)59 void analyzeVisibilityAndOpacity(t_ilm_surface targetSurfaceId, t_scene_data& scene)
60 {
61 t_ilm_layer targetSurfaceLayer = scene.surfaceLayer[targetSurfaceId];
62 ilmSurfaceProperties& targetSurfaceProperties = scene.surfaceProperties[targetSurfaceId];
63 ilmLayerProperties& targetLayerProperties = scene.layerProperties[targetSurfaceLayer];
64 string tag;
65 string flag;
66 char description[300] = "";
67
68 //check visibility
69 tag = "Surface Visibility";
70 if (targetSurfaceProperties.visibility == ILM_FALSE)
71 {
72 flag = "PROBLEM";
73 sprintf(description, "Surface %i visibility set to false", targetSurfaceId);
74 }
75 else
76 {
77 flag = "OK";
78 sprintf(description, "%s", "");
79 }
80
81 analyzePrintHelper(tag, flag, description);
82
83 tag = "Layer Visibility";
84 if (targetLayerProperties.visibility == ILM_FALSE)
85 {
86 flag = "PROBLEM";
87 sprintf(description, "Layer %i visibility set to false.", targetSurfaceLayer);
88 }
89 else
90 {
91 flag = "OK";
92 sprintf(description, "%s", "");
93 }
94
95 analyzePrintHelper(tag, flag, description);
96
97 //check opacity
98 tag = "Surface Opacity";
99 if (targetSurfaceProperties.opacity <= 0.2)
100 {
101 flag = "PROBLEM";
102 sprintf(description, "Surface %i opacity set to %f, it is (almost) invisible", targetSurfaceId, targetSurfaceProperties.opacity);
103 }
104 else if (targetSurfaceProperties.opacity < 1.0)
105 {
106 flag = "WARNING";
107 sprintf(description, "Surface %i opacity set to %f, it might not be easy to see", targetSurfaceId, targetSurfaceProperties.opacity);
108 }
109 else
110 {
111 flag = "OK";
112 sprintf(description, "%s", "");
113 }
114
115 analyzePrintHelper(tag, flag, description);
116
117 tag = "Layer Opacity";
118 if (targetLayerProperties.opacity <= 0.2)
119 {
120 flag = "PROBLEM";
121 sprintf(description, "Layer %i opacity set to %f, it is (almost) invisible", targetSurfaceLayer, targetLayerProperties.opacity);
122 }
123 else if (targetLayerProperties.opacity < 1.0)
124 {
125 flag = "WARNING";
126 sprintf(description, "Layer %i opacity set to %f, it might not be easy to see", targetSurfaceLayer, targetLayerProperties.opacity);
127 }
128 else
129 {
130 flag = "OK";
131 sprintf(description, "%s", "");
132 }
133
134 analyzePrintHelper(tag, flag, description);
135 }
136
analyzeSurfaceDimensions(t_ilm_surface targetSurfaceId,t_scene_data & scene)137 void analyzeSurfaceDimensions(t_ilm_surface targetSurfaceId, t_scene_data& scene)
138 {
139 ilmSurfaceProperties& targetSurfaceProperties = scene.surfaceProperties[targetSurfaceId];
140 string tag;
141 string flag;
142 char description[300] = "";
143
144 t_ilm_uint minDimension = 32;
145
146 tag = "Surface dest width";
147 if (targetSurfaceProperties.destWidth <= minDimension)
148 {
149 flag = "PROBLEM";
150 sprintf(description, "Surface %i has [destWidth=%i]", targetSurfaceId, targetSurfaceProperties.destWidth);
151 }
152 else
153 {
154 flag = "OK";
155 sprintf(description, "%s", "");
156 }
157
158 analyzePrintHelper(tag, flag, description);
159
160 tag = "Surface source width";
161 if (targetSurfaceProperties.sourceWidth <= minDimension)
162 {
163 flag = "PROBLEM";
164 sprintf(description, "Surface %i has [sourceWidth=%i]", targetSurfaceId, targetSurfaceProperties.sourceWidth);
165 }
166 else
167 {
168 flag = "OK";
169 sprintf(description, "%s", "");
170 }
171
172 analyzePrintHelper(tag, flag, description);
173
174 tag = "Surface original width";
175 if (targetSurfaceProperties.origSourceWidth <= minDimension)
176 {
177 flag = "PROBLEM";
178 sprintf(description, "Surface %i has [origSourceWidth=%i]", targetSurfaceId, targetSurfaceProperties.origSourceWidth);
179 }
180 else
181 {
182 flag = "OK";
183 sprintf(description, "%s", "");
184 }
185
186 analyzePrintHelper(tag, flag, description);
187
188 tag = "Surface dest height";
189 if (targetSurfaceProperties.destHeight <= minDimension)
190 {
191 flag = "PROBLEM";
192 sprintf(description, "Surface %i has [destHeight=%i]", targetSurfaceId, targetSurfaceProperties.destHeight);
193 }
194 else
195 {
196 flag = "OK";
197 sprintf(description, "%s", "");
198 }
199
200 analyzePrintHelper(tag, flag, description);
201
202 tag = "Surface source height";
203 if (targetSurfaceProperties.sourceHeight <= minDimension)
204 {
205 flag = "PROBLEM";
206 sprintf(description, "Surface %i has [sourceHeight=%i]", targetSurfaceId, targetSurfaceProperties.sourceHeight);
207 }
208 else
209 {
210 flag = "OK";
211 sprintf(description, "%s", "");
212 }
213
214 analyzePrintHelper(tag, flag, description);
215
216 tag = "Surface original height";
217 if (targetSurfaceProperties.origSourceHeight <= minDimension)
218 {
219 flag = "PROBLEM";
220 sprintf(description, "Surface %i has [origSourceHeight=%i]", targetSurfaceId, targetSurfaceProperties.origSourceHeight);
221 }
222 else
223 {
224 flag = "OK";
225 sprintf(description, "%s", "");
226 }
227
228 analyzePrintHelper(tag, flag, description);
229 }
230
analyzeLayerDimensions(t_ilm_surface targetSurfaceId,t_scene_data & scene)231 void analyzeLayerDimensions(t_ilm_surface targetSurfaceId, t_scene_data& scene)
232 {
233 t_ilm_layer targetSurfaceLayer = scene.surfaceLayer[targetSurfaceId];
234 ilmLayerProperties& targetLayerProperties = scene.layerProperties[targetSurfaceLayer];
235 t_ilm_uint minDimension = 32;
236
237 string tag;
238 string flag;
239 char description[300] = "";
240 tag = "Layer dest width";
241 if (targetLayerProperties.destWidth <= minDimension)
242 {
243 flag = "PROBLEM";
244 sprintf(description, "Layer %i has [destWidth=%i]", targetSurfaceLayer, targetLayerProperties.destWidth);
245 }
246 else
247 {
248 flag = "OK";
249 sprintf(description, "%s", "");
250 }
251
252 analyzePrintHelper(tag, flag, description);
253
254 tag = "Layer source width";
255 if (targetLayerProperties.sourceWidth <= minDimension)
256 {
257 flag = "PROBLEM";
258 sprintf(description, "Layer %i has [sourceWidth=%i]", targetSurfaceLayer, targetLayerProperties.sourceWidth);
259 }
260 else
261 {
262 flag = "OK";
263 sprintf(description, "%s", "");
264 }
265
266 analyzePrintHelper(tag, flag, description);
267
268 tag = "Layer dest height";
269 if (targetLayerProperties.destHeight <= minDimension)
270 {
271 flag = "PROBLEM";
272 sprintf(description, "Layer %i has [destHeight=%i]", targetSurfaceLayer, targetLayerProperties.destHeight);
273 }
274 else
275 {
276 flag = "OK";
277 sprintf(description, "%s", "");
278 }
279
280 analyzePrintHelper(tag, flag, description);
281
282 tag = "Layer source height";
283 if (targetLayerProperties.sourceHeight <= minDimension)
284 {
285 flag = "PROBLEM";
286 sprintf(description, "Layer %i has [sourceHeight=%i]", targetSurfaceLayer, targetLayerProperties.sourceHeight);
287 }
288 else
289 {
290 flag = "OK";
291 sprintf(description, "%s", "");
292 }
293
294 analyzePrintHelper(tag, flag, description);
295 }
296
analyzeDimensions(t_ilm_surface targetSurfaceId,t_scene_data & scene)297 void analyzeDimensions(t_ilm_surface targetSurfaceId, t_scene_data& scene)
298 {
299 analyzeSurfaceDimensions(targetSurfaceId, scene);
300 analyzeLayerDimensions(targetSurfaceId, scene);
301 }
302
analyzeSurfaceCheckInsideLayer(t_ilm_surface targetSurfaceId,t_scene_data & scene)303 void analyzeSurfaceCheckInsideLayer(t_ilm_surface targetSurfaceId, t_scene_data& scene)
304 {
305 t_ilm_layer targetSurfaceLayer = scene.surfaceLayer[targetSurfaceId];
306 tuple4 targetSurfaceCoordinates = getSurfaceScreenCoordinates(&scene, targetSurfaceId);
307 ilmLayerProperties& targetLayerProperties = scene.layerProperties[targetSurfaceLayer];
308 string tag;
309 string flag;
310 char description[300] = "";
311
312 tuple4 layerCoordinates(targetLayerProperties.destX,
313 targetLayerProperties.destY,
314 targetLayerProperties.destX + targetLayerProperties.destWidth,
315 targetLayerProperties.destY + targetLayerProperties.destHeight);
316
317 tag = "Surface inside Layer";
318 if (!inside(targetSurfaceCoordinates, layerCoordinates))
319 {
320 flag = "PROBLEM";
321 sprintf(description, "Surface %i is not viewed completely insde the destination region of layer %i",
322 targetSurfaceId, targetSurfaceLayer);
323 }
324 else
325 {
326 flag = "OK";
327 sprintf(description, "%s", "");
328 }
329
330 analyzePrintHelper(tag, flag, description);
331 }
332
analyzeOcclusion(t_ilm_surface targetSurfaceId,t_scene_data & scene)333 void analyzeOcclusion(t_ilm_surface targetSurfaceId, t_scene_data& scene)
334 {
335 string tag;
336 string flag;
337 char description[300] = "";
338
339 vector<t_ilm_surface> renderedSurfaces = getSceneRenderOrder(&scene);
340 vector<t_ilm_surface> occludingSurfaces;
341
342 vector<t_ilm_surface>::iterator it = find(renderedSurfaces.begin(), renderedSurfaces.end(), targetSurfaceId);
343
344 tuple4 targetSurfaceCoordinates = getSurfaceScreenCoordinates(&scene, targetSurfaceId);
345
346 t_ilm_bool occluded = ILM_FALSE;
347 tag = "Occlusion";
348 ++it;
349 for (; it != renderedSurfaces.end(); ++it)
350 {
351 t_ilm_surface surfaceId = *it;
352 t_ilm_layer surfaceLayer = scene.surfaceLayer[surfaceId];
353
354 //if surface or layer invisible: neglect
355 if (scene.layerProperties[surfaceLayer].visibility == ILM_FALSE || scene.surfaceProperties[surfaceId].visibility == ILM_FALSE)
356 continue;
357
358 //if multiplication of their opacity is zero: neglect
359 if (scene.layerProperties[surfaceLayer].opacity * scene.surfaceProperties[surfaceId].opacity == 0)
360 continue;
361
362 //coordinates of the surface on screen
363 tuple4 surfaceCoordinates = getSurfaceScreenCoordinates(&scene, surfaceId);
364
365 //if the surface is completely occluded
366 if (inside(targetSurfaceCoordinates, surfaceCoordinates))
367 {
368 flag = "PROBLEM";
369 sprintf(description, "Surface %i is completely occluded by surface %i", targetSurfaceId, surfaceId);
370 analyzePrintHelper(tag, flag, description);
371
372 occluded = ILM_TRUE;
373 }
374 //if the surface is partially occluded
375 else if (intersect(targetSurfaceCoordinates, surfaceCoordinates))
376 {
377 flag = "PROBLEM";
378 sprintf(description, "Surface %i is partially occluded by surface %i", targetSurfaceId, surfaceId);
379 analyzePrintHelper(tag, flag, description);
380 occluded = ILM_TRUE;
381 }
382 }
383
384 if (!occluded)
385 {
386 flag = "OK";
387 sprintf(description, "%s", "");
388 analyzePrintHelper(tag, flag, description);
389 }
390 }
391
analyzeCheckSurfaceExists(t_ilm_surface targetSurfaceId,t_scene_data & scene)392 t_ilm_bool analyzeCheckSurfaceExists(t_ilm_surface targetSurfaceId, t_scene_data& scene)
393 {
394 t_ilm_bool exists = ILM_FALSE;
395
396 string tag;
397 string flag;
398 char description[300] = "";
399
400 tag = "Surface existance";
401 //check if surface exists
402 if (find(scene.surfaces.begin(), scene.surfaces.end(), targetSurfaceId)
403 == scene.surfaces.end())
404 {
405 flag = "PROBLEM";
406 sprintf(description, "There is no surface with ID %i", targetSurfaceId);
407 }
408 else
409 {
410 exists = ILM_TRUE;
411 flag = "OK";
412 sprintf(description, "%s", "");
413 }
414
415 analyzePrintHelper(tag, flag, description);
416
417 return exists;
418 }
419
analyzeCheckRendered(t_ilm_surface targetSurfaceId,t_scene_data & scene)420 t_ilm_bool analyzeCheckRendered(t_ilm_surface targetSurfaceId, t_scene_data& scene)
421 {
422 t_ilm_bool onLayer = ILM_FALSE;
423 t_ilm_bool layerOnScreen = ILM_FALSE;
424 //is surface on layer?
425 map<t_ilm_surface, t_ilm_layer>::iterator surfaceLayerIt = scene.surfaceLayer.find(targetSurfaceId);
426
427 if (surfaceLayerIt != scene.surfaceLayer.end())
428 {
429 onLayer = ILM_TRUE;
430 t_ilm_layer layer = (*surfaceLayerIt).second;
431
432 //is layer on screen?
433 layerOnScreen = scene.layerScreen.find(layer) != scene.layerScreen.end();
434 }
435
436 //output
437 string tag;
438 string flag;
439 char description[300] = "";
440
441 tag = "Surface on layer";
442 if (!onLayer)
443 {
444 flag = "PROBLEM";
445 sprintf(description, "Surface %i is not on any layer", targetSurfaceId);
446 }
447 else
448 {
449 flag = "OK";
450 sprintf(description, "%s", "");
451 }
452
453 analyzePrintHelper(tag, flag, description);
454
455 if (onLayer)
456 {
457 tag = "Layer on screen";
458 if (!layerOnScreen)
459 {
460 flag = "PROBLEM";
461 sprintf(description, "Layer %i is not on any screen", scene.surfaceLayer[targetSurfaceId]);
462 }
463 else
464 {
465 flag = "OK";
466 sprintf(description, "%s", "");
467 }
468
469 analyzePrintHelper(tag, flag, description);
470 }
471
472 return onLayer && layerOnScreen;
473 }
474
analyzeFrameCounter(t_ilm_surface targetSurfaceId,t_scene_data & scene)475 t_ilm_bool analyzeFrameCounter(t_ilm_surface targetSurfaceId, t_scene_data& scene)
476 {
477 ilmSurfaceProperties& targetSurfaceProperties = scene.surfaceProperties[targetSurfaceId];
478
479 t_ilm_bool problem = targetSurfaceProperties.frameCounter == 0;
480 string tag;
481 string flag;
482 char description[300] = "";
483
484 tag = "Frame Counter";
485 //check if surface counter was updated since its creation
486 if (problem)
487 {
488 flag = "PROBLEM";
489 sprintf(description, "Surface %i frame counter is %i, no content was added to the surface since its creation",
490 targetSurfaceId, targetSurfaceProperties.frameCounter);
491 }
492 else
493 {
494 flag = "OK";
495 sprintf(description, "%s", "");
496 }
497
498 analyzePrintHelper(tag, flag, description);
499
500 return !problem;
501 }
502 } //end of anonymous namespace
503
504
analyzeSurface(t_ilm_surface targetSurfaceId)505 t_ilm_bool analyzeSurface(t_ilm_surface targetSurfaceId)
506 {
507 t_scene_data scene;
508 captureSceneData(&scene);
509
510 if (!analyzeCheckSurfaceExists(targetSurfaceId, scene))
511 return ILM_TRUE;
512
513 if (!analyzeCheckRendered(targetSurfaceId, scene))
514 return ILM_TRUE;
515
516 //check no visibility or low opacity
517 analyzeVisibilityAndOpacity(targetSurfaceId, scene);
518
519 //check small dimensions
520 analyzeDimensions(targetSurfaceId, scene);
521
522 //check if surface is completely inside the destination region of the layer
523 analyzeSurfaceCheckInsideLayer(targetSurfaceId, scene);
524
525 //get occluding visible surfaces
526 analyzeOcclusion(targetSurfaceId, scene);
527
528 //check if the surface has been updated (if it has any content)
529 analyzeFrameCounter(targetSurfaceId, scene);
530
531 return ILM_TRUE;
532 }
533