1 /***************************************************************************
3 * Copyright 2012 BMW Car IT GmbH
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 ****************************************************************************/
20 #include "ilm_client.h"
21 #include "LMControl.h"
55 void analyzePrintHelper(string tag, string flag, string description)
57 cout << left << setw(25) << tag << " | " << setw(7) << flag << " | " << description << endl;
60 void analyzeVisibilityAndOpacity(t_ilm_surface targetSurfaceId, t_scene_data& scene)
62 t_ilm_layer targetSurfaceLayer = scene.surfaceLayer[targetSurfaceId];
63 ilmSurfaceProperties& targetSurfaceProperties = scene.surfaceProperties[targetSurfaceId];
64 ilmLayerProperties& targetLayerProperties = scene.layerProperties[targetSurfaceLayer];
67 char description[300] = "";
70 tag = "Surface Visibility";
71 if (targetSurfaceProperties.visibility == ILM_FALSE)
74 sprintf(description, "Surface %i visibility set to false", targetSurfaceId);
79 sprintf(description, "%s", "");
82 analyzePrintHelper(tag, flag, description);
84 tag = "Layer Visibility";
85 if (targetLayerProperties.visibility == ILM_FALSE)
88 sprintf(description, "Layer %i visibility set to false.", targetSurfaceLayer);
93 sprintf(description, "%s", "");
96 analyzePrintHelper(tag, flag, description);
99 tag = "Surface Opacity";
100 if (targetSurfaceProperties.opacity <= 0.2)
103 sprintf(description, "Surface %i opacity set to %f, it is (almost) invisible", targetSurfaceId, targetSurfaceProperties.opacity);
105 else if (targetSurfaceProperties.opacity < 1.0)
108 sprintf(description, "Surface %i opacity set to %f, it might not be easy to see", targetSurfaceId, targetSurfaceProperties.opacity);
113 sprintf(description, "%s", "");
116 analyzePrintHelper(tag, flag, description);
118 tag = "Layer Opacity";
119 if (targetLayerProperties.opacity <= 0.2)
122 sprintf(description, "Layer %i opacity set to %f, it is (almost) invisible", targetSurfaceLayer, targetLayerProperties.opacity);
124 else if (targetLayerProperties.opacity < 1.0)
127 sprintf(description, "Layer %i opacity set to %f, it might not be easy to see", targetSurfaceLayer, targetLayerProperties.opacity);
132 sprintf(description, "%s", "");
135 analyzePrintHelper(tag, flag, description);
138 void analyzeSurfaceDimensions(t_ilm_surface targetSurfaceId, t_scene_data& scene)
140 ilmSurfaceProperties& targetSurfaceProperties = scene.surfaceProperties[targetSurfaceId];
143 char description[300] = "";
145 t_ilm_uint minDimension = 32;
147 tag = "Surface dest width";
148 if (targetSurfaceProperties.destWidth <= minDimension)
151 sprintf(description, "Surface %i has [destWidth=%i]", targetSurfaceId, targetSurfaceProperties.destWidth);
156 sprintf(description, "%s", "");
159 analyzePrintHelper(tag, flag, description);
161 tag = "Surface source width";
162 if (targetSurfaceProperties.sourceWidth <= minDimension)
165 sprintf(description, "Surface %i has [sourceWidth=%i]", targetSurfaceId, targetSurfaceProperties.sourceWidth);
170 sprintf(description, "%s", "");
173 analyzePrintHelper(tag, flag, description);
175 tag = "Surface original width";
176 if (targetSurfaceProperties.origSourceWidth <= minDimension)
179 sprintf(description, "Surface %i has [origSourceWidth=%i]", targetSurfaceId, targetSurfaceProperties.origSourceWidth);
184 sprintf(description, "%s", "");
187 analyzePrintHelper(tag, flag, description);
189 tag = "Surface dest height";
190 if (targetSurfaceProperties.destHeight <= minDimension)
193 sprintf(description, "Surface %i has [destHeight=%i]", targetSurfaceId, targetSurfaceProperties.destHeight);
198 sprintf(description, "%s", "");
201 analyzePrintHelper(tag, flag, description);
203 tag = "Surface source height";
204 if (targetSurfaceProperties.sourceHeight <= minDimension)
207 sprintf(description, "Surface %i has [sourceHeight=%i]", targetSurfaceId, targetSurfaceProperties.sourceHeight);
212 sprintf(description, "%s", "");
215 analyzePrintHelper(tag, flag, description);
217 tag = "Surface original height";
218 if (targetSurfaceProperties.origSourceHeight <= minDimension)
221 sprintf(description, "Surface %i has [origSourceHeight=%i]", targetSurfaceId, targetSurfaceProperties.origSourceHeight);
226 sprintf(description, "%s", "");
229 analyzePrintHelper(tag, flag, description);
232 void analyzeLayerDimensions(t_ilm_surface targetSurfaceId, t_scene_data& scene)
234 t_ilm_layer targetSurfaceLayer = scene.surfaceLayer[targetSurfaceId];
235 ilmLayerProperties& targetLayerProperties = scene.layerProperties[targetSurfaceLayer];
236 t_ilm_uint minDimension = 32;
240 char description[300] = "";
241 tag = "Layer dest width";
242 if (targetLayerProperties.destWidth <= minDimension)
245 sprintf(description, "Layer %i has [destWidth=%i]", targetSurfaceLayer, targetLayerProperties.destWidth);
250 sprintf(description, "%s", "");
253 analyzePrintHelper(tag, flag, description);
255 tag = "Layer source width";
256 if (targetLayerProperties.sourceWidth <= minDimension)
259 sprintf(description, "Layer %i has [sourceWidth=%i]", targetSurfaceLayer, targetLayerProperties.sourceWidth);
264 sprintf(description, "%s", "");
267 analyzePrintHelper(tag, flag, description);
269 tag = "Layer original width";
270 if (targetLayerProperties.origSourceWidth <= minDimension)
273 sprintf(description, "Layer %i has [origSourceWidth=%i]", targetSurfaceLayer, targetLayerProperties.origSourceWidth);
278 sprintf(description, "%s", "");
281 analyzePrintHelper(tag, flag, description);
283 tag = "Layer dest height";
284 if (targetLayerProperties.destHeight <= minDimension)
287 sprintf(description, "Layer %i has [destHeight=%i]", targetSurfaceLayer, targetLayerProperties.destHeight);
292 sprintf(description, "%s", "");
295 analyzePrintHelper(tag, flag, description);
297 tag = "Layer source height";
298 if (targetLayerProperties.sourceHeight <= minDimension)
301 sprintf(description, "Layer %i has [sourceHeight=%i]", targetSurfaceLayer, targetLayerProperties.sourceHeight);
306 sprintf(description, "%s", "");
309 analyzePrintHelper(tag, flag, description);
311 tag = "Layer original source";
312 if (targetLayerProperties.origSourceHeight <= minDimension)
315 sprintf(description, "Layer %i has [origSourceHeight=%i]", targetSurfaceLayer, targetLayerProperties.origSourceHeight);
320 sprintf(description, "%s", "");
323 analyzePrintHelper(tag, flag, description);
326 void analyzeDimensions(t_ilm_surface targetSurfaceId, t_scene_data& scene)
328 analyzeSurfaceDimensions(targetSurfaceId, scene);
329 analyzeLayerDimensions(targetSurfaceId, scene);
332 void analyzeSurfaceCheckInsideLayer(t_ilm_surface targetSurfaceId, t_scene_data& scene)
334 t_ilm_layer targetSurfaceLayer = scene.surfaceLayer[targetSurfaceId];
335 tuple4 targetSurfaceCoordinates = getSurfaceScreenCoordinates(&scene, targetSurfaceId);
336 ilmLayerProperties& targetLayerProperties = scene.layerProperties[targetSurfaceLayer];
339 char description[300] = "";
341 tuple4 layerCoordinates(targetLayerProperties.destX,
342 targetLayerProperties.destY,
343 targetLayerProperties.destX + targetLayerProperties.destWidth,
344 targetLayerProperties.destY + targetLayerProperties.destHeight);
346 tag = "Surface inside Layer";
347 if (!inside(targetSurfaceCoordinates, layerCoordinates))
350 sprintf(description, "Surface %i is not viewed completely insde the destination region of layer %i",
351 targetSurfaceId, targetSurfaceLayer);
356 sprintf(description, "%s", "");
359 analyzePrintHelper(tag, flag, description);
362 void analyzeOcclusion(t_ilm_surface targetSurfaceId,
363 map<t_ilm_surface, t_ilm_layer>& surfaceLayers,
364 map<t_ilm_surface, ilmSurfaceProperties>& surfaceProperties,
365 map<t_ilm_layer, ilmLayerProperties>& layerProperties,
366 vector<t_ilm_surface>& allSurfaces, tuple4 targetSurfaceCoordinates)
370 char description[300] = "";
372 vector<t_ilm_surface> occludingSurfaces;
374 vector<t_ilm_surface>::iterator it = find(allSurfaces.begin(), allSurfaces.end(), targetSurfaceId);
376 t_ilm_bool occluded = ILM_FALSE;
379 for (; it != allSurfaces.end(); ++it)
381 t_ilm_surface surfaceId = *it;
382 t_ilm_layer surfaceLayer = surfaceLayers[surfaceId];
384 //if surface or layer invisible: neglect
385 if (layerProperties[surfaceLayer].visibility == ILM_FALSE || surfaceProperties[surfaceId].visibility == ILM_FALSE)
388 //if multiplication of their opacity is zero: neglect
389 if (layerProperties[surfaceLayer].opacity * surfaceProperties[surfaceId].opacity == 0)
392 //coordinates of the surface on screen
393 t_ilm_int horizontalScale = layerProperties[surfaceLayer].destWidth / layerProperties[surfaceLayer].sourceWidth;
394 t_ilm_int surfaceX1 = layerProperties[surfaceLayer].destX + horizontalScale
395 * (surfaceProperties[surfaceId].destX - layerProperties[surfaceLayer].sourceX);
396 t_ilm_int surfaceX2 = surfaceX1 + horizontalScale * surfaceProperties[surfaceId].destWidth;
398 t_ilm_int verticalScale = layerProperties[surfaceLayer].destHeight / layerProperties[surfaceLayer].sourceHeight;
399 t_ilm_int surfaceY1 = layerProperties[surfaceLayer].destY + verticalScale
400 * (surfaceProperties[surfaceId].destY - layerProperties[surfaceLayer].sourceY);
401 t_ilm_int surfaceY2 = surfaceY1 + verticalScale * surfaceProperties[surfaceId].destHeight;
403 tuple4 surfaceCoordinates(surfaceX1, surfaceY1, surfaceX2, surfaceY2);
405 //if the surface is completely occluded
406 if (inside(targetSurfaceCoordinates, surfaceCoordinates))
409 sprintf(description, "Surface %i is completely occluded by surface %i", targetSurfaceId, surfaceId);
410 analyzePrintHelper(tag, flag, description);
414 //if the surface is partially occluded
415 else if (intersect(targetSurfaceCoordinates, surfaceCoordinates))
418 sprintf(description, "Surface %i is partially occluded by surface %i", targetSurfaceId, surfaceId);
419 analyzePrintHelper(tag, flag, description);
427 sprintf(description, "%s", "");
428 analyzePrintHelper(tag, flag, description);
432 void analyzeOcclusion(t_ilm_surface targetSurfaceId, t_scene_data& scene)
436 char description[300] = "";
438 vector<t_ilm_surface> renderedSurfaces = getSceneRenderOrder(&scene);
439 vector<t_ilm_surface> occludingSurfaces;
441 vector<t_ilm_surface>::iterator it = find(renderedSurfaces.begin(), renderedSurfaces.end(), targetSurfaceId);
443 tuple4 targetSurfaceCoordinates = getSurfaceScreenCoordinates(&scene, targetSurfaceId);
445 t_ilm_bool occluded = ILM_FALSE;
448 for (; it != renderedSurfaces.end(); ++it)
450 t_ilm_surface surfaceId = *it;
451 t_ilm_layer surfaceLayer = scene.surfaceLayer[surfaceId];
453 //if surface or layer invisible: neglect
454 if (scene.layerProperties[surfaceLayer].visibility == ILM_FALSE || scene.surfaceProperties[surfaceId].visibility == ILM_FALSE)
457 //if multiplication of their opacity is zero: neglect
458 if (scene.layerProperties[surfaceLayer].opacity * scene.surfaceProperties[surfaceId].opacity == 0)
461 //coordinates of the surface on screen
462 tuple4 surfaceCoordinates = getSurfaceScreenCoordinates(&scene, surfaceId);
464 //if the surface is completely occluded
465 if (inside(targetSurfaceCoordinates, surfaceCoordinates))
468 sprintf(description, "Surface %i is completely occluded by surface %i", targetSurfaceId, surfaceId);
469 analyzePrintHelper(tag, flag, description);
473 //if the surface is partially occluded
474 else if (intersect(targetSurfaceCoordinates, surfaceCoordinates))
477 sprintf(description, "Surface %i is partially occluded by surface %i", targetSurfaceId, surfaceId);
478 analyzePrintHelper(tag, flag, description);
486 sprintf(description, "%s", "");
487 analyzePrintHelper(tag, flag, description);
491 t_ilm_bool analyzeCheckSurfaceExists(t_ilm_surface targetSurfaceId, t_scene_data& scene)
493 t_ilm_bool exists = ILM_FALSE;
497 char description[300] = "";
499 tag = "Surface existance";
500 //check if surface exists
501 if (find(scene.surfaces.begin(), scene.surfaces.end(), targetSurfaceId)
502 == scene.surfaces.end())
505 sprintf(description, "There is no surface with ID %i", targetSurfaceId);
511 sprintf(description, "%s", "");
514 analyzePrintHelper(tag, flag, description);
519 t_ilm_bool analyzeCheckRendered(t_ilm_surface targetSurfaceId, t_scene_data& scene)
521 t_ilm_bool onLayer = ILM_FALSE;
522 t_ilm_bool layerOnScreen = ILM_FALSE;
523 //is surface on layer?
524 map<t_ilm_surface, t_ilm_layer>::iterator surfaceLayerIt = scene.surfaceLayer.find(targetSurfaceId);
526 if (surfaceLayerIt != scene.surfaceLayer.end())
529 t_ilm_layer layer = (*surfaceLayerIt).second;
531 //is layer on screen?
532 layerOnScreen = scene.layerScreen.find(layer) != scene.layerScreen.end();
538 char description[300] = "";
540 tag = "Surface on layer";
544 sprintf(description, "Surface %i is not on any layer", targetSurfaceId);
549 sprintf(description, "%s", "");
552 analyzePrintHelper(tag, flag, description);
556 tag = "Layer on screen";
560 sprintf(description, "Layer %i is not on any screen", scene.surfaceLayer[targetSurfaceId]);
565 sprintf(description, "%s", "");
568 analyzePrintHelper(tag, flag, description);
571 return onLayer && layerOnScreen;
574 t_ilm_bool analyzeSharedNative(t_ilm_surface targetSurfaceId, t_scene_data& scene)
578 char description[300] = "";
580 tag = "Shared native";
582 t_ilm_bool shared = ILM_FALSE;
584 //native of the target surface
585 t_ilm_uint targetNative = scene.surfaceProperties[targetSurfaceId].nativeSurface;
587 //iterate all surface properties
588 for (map<t_ilm_surface, ilmSurfaceProperties>::iterator it = scene.surfaceProperties.begin();
589 it != scene.surfaceProperties.end(); ++it)
591 t_ilm_surface surface = (*it).first;
592 ilmSurfaceProperties& properties = (*it).second;
593 //if there is a surface that has the same surface as the target surface
594 if (surface != targetSurfaceId && properties.nativeSurface == targetNative)
599 sprintf(description, "Surface %i shares native that has ID %i with surface %i",
600 targetSurfaceId, targetNative, surface);
601 analyzePrintHelper(tag, flag, description);
608 sprintf(description, "%s", "");
609 analyzePrintHelper(tag, flag, description);
615 t_ilm_bool analyzeUpdateCounter(t_ilm_surface targetSurfaceId, t_scene_data& scene)
617 ilmSurfaceProperties& targetSurfaceProperties = scene.surfaceProperties[targetSurfaceId];
619 t_ilm_bool problem = targetSurfaceProperties.updateCounter == 0;
622 char description[300] = "";
624 tag = "Update Counter";
625 //check if surface counter was updated since its creation
629 sprintf(description, "Surface %i update counter is %i, no content was added to the surface since its creation",
630 targetSurfaceId, targetSurfaceProperties.updateCounter);
635 sprintf(description, "%s", "");
638 analyzePrintHelper(tag, flag, description);
642 } //end of anonymous namespace
645 t_ilm_bool analyzeSurface(t_ilm_surface targetSurfaceId)
648 captureSceneData(&scene);
650 if (!analyzeCheckSurfaceExists(targetSurfaceId, scene))
653 if (!analyzeCheckRendered(targetSurfaceId, scene))
656 //check no visibility or low opacity
657 analyzeVisibilityAndOpacity(targetSurfaceId, scene);
659 //check small dimensions
660 analyzeDimensions(targetSurfaceId, scene);
662 //check if surface is completely inside the destination region of the layer
663 analyzeSurfaceCheckInsideLayer(targetSurfaceId, scene);
665 //get occluding visible surfaces
666 analyzeOcclusion(targetSurfaceId, scene);
668 //check if the surface has been updated (if it has any content)
669 analyzeUpdateCounter(targetSurfaceId, scene);
671 //check if the surface shares the native with another surface
672 analyzeSharedNative(targetSurfaceId, scene);