• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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