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"
43 #include <sys/types.h>
47 tuple4 getSurfaceScreenCoordinates(ilmSurfaceProperties targetSurfaceProperties, ilmLayerProperties targetLayerProperties)
49 t_ilm_float horizontalScale = targetLayerProperties.sourceWidth ?
50 1.0 * targetLayerProperties.destWidth / targetLayerProperties.sourceWidth : 0;
52 t_ilm_float targetX1 = targetLayerProperties.destX + horizontalScale
53 * (targetSurfaceProperties.destX- targetLayerProperties.sourceX);
54 t_ilm_float targetX2 = targetX1 + horizontalScale * targetSurfaceProperties.destWidth;
56 t_ilm_float verticalScale = targetLayerProperties.sourceHeight ?
57 1.0 * targetLayerProperties.destHeight/ targetLayerProperties.sourceHeight : 0;
59 t_ilm_float targetY1 = targetLayerProperties.destY + verticalScale
60 * (targetSurfaceProperties.destY - targetLayerProperties.sourceY);
61 t_ilm_float targetY2 = targetY1 + verticalScale * targetSurfaceProperties.destHeight;
63 tuple4 targetSurfaceCoordinates(static_cast<t_ilm_int>(targetX1),
64 static_cast<t_ilm_int>(targetY1),
65 max(0, static_cast<t_ilm_int>(targetX2) - 1),
66 max(0, static_cast<t_ilm_int>(targetY2) - 1));
68 return targetSurfaceCoordinates;
71 tuple4 getSurfaceScreenCoordinates(t_scene_data* pScene, t_ilm_surface surface)
73 tuple4 surfaceCoordinates;
75 //if surface belongs to a layer make it appear exacrly as it would appear on its current layer
76 if (pScene->surfaceLayer.find(surface) != pScene->surfaceLayer.end())
78 //set dimensions of the surface to map to the extra layer according to its current placement in the
79 t_ilm_layer layer = pScene->surfaceLayer[surface];
80 ilmLayerProperties layerProperties = pScene->layerProperties[layer];
81 ilmSurfaceProperties surfaceProperties = pScene->surfaceProperties[surface];
83 surfaceCoordinates = getSurfaceScreenCoordinates(surfaceProperties, layerProperties);
85 //if surface does not belong to a layer just assume it belongs to a layer that fills the screen
88 ilmSurfaceProperties surfaceProperties = pScene->surfaceProperties[surface];
90 surfaceCoordinates.x = surfaceProperties.destX;
91 surfaceCoordinates.y = surfaceProperties.destY;
92 surfaceCoordinates.z = surfaceProperties.destX + surfaceProperties.destWidth;
93 surfaceCoordinates.w = surfaceProperties.destX + surfaceProperties.destHeight;
96 return surfaceCoordinates;
99 t_ilm_bool surfaceRenderedOnScreen(t_scene_data& scene, t_ilm_surface surface)
101 //if scene belongs to a layer and that layer belongs to a screen
102 if (scene.surfaceLayer.find(surface) != scene.surfaceLayer.end())
104 t_ilm_layer layer = scene.surfaceLayer[surface];
105 if (scene.layerScreen.find(layer) != scene.layerScreen.end())
114 vector<t_ilm_surface> getSceneRenderOrder(t_scene_data* pScene)
116 t_scene_data& scene = *pScene;
117 vector<t_ilm_surface> renderOrder;
119 //iterate over screens
120 for (vector<t_ilm_display>::iterator it = scene.screens.begin(); it != scene.screens.end(); ++it)
122 t_ilm_display screen = *it;
123 vector<t_ilm_layer> layers = scene.screenLayers[screen];
125 //iterate over layers
126 for (vector<t_ilm_layer>::iterator layerIterator = layers.begin();
127 layerIterator != layers.end(); ++layerIterator)
129 t_ilm_layer layer = (*layerIterator);
130 vector<t_ilm_surface> surfaces = scene.layerSurfaces[layer];
132 //iterate over surfaces
133 for (vector<t_ilm_surface>::iterator it = surfaces.begin(); it != surfaces.end(); ++it)
135 t_ilm_surface surface = *it;
137 renderOrder.push_back(surface);
145 void captureSceneData(t_scene_data* pScene)
147 t_scene_data& scene = *pScene;
149 //get screen information
150 t_ilm_uint screenWidth = 0, screenHeight = 0;
152 ilmErrorTypes callResult = ilm_getScreenResolution(0, &screenWidth, &screenHeight);
153 if (ILM_SUCCESS != callResult)
155 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
156 cout << "Failed to get screen resolution for screen with ID " << 0 << "\n";
160 scene.screenWidth = screenWidth;
161 scene.screenHeight = screenHeight;
163 //extra layer for debugging
164 scene.extraLayer = 0xFFFFFFFF;
167 unsigned int screenCount = 0;
168 t_ilm_display* screenArray = NULL;
170 callResult = ilm_getScreenIDs(&screenCount, &screenArray);
171 if (ILM_SUCCESS != callResult)
173 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
174 cout << "Failed to get available screen IDs\n";
178 scene.screens = vector<t_ilm_display>(screenArray, screenArray + screenCount);
180 //layers on each screen
181 for (unsigned int i = 0; i < screenCount; ++i)
183 t_ilm_display screenId = screenArray[i];
185 t_ilm_int layerCount = 0;
186 t_ilm_layer* layerArray = NULL;
188 callResult = ilm_getLayerIDsOnScreen(screenId, &layerCount, &layerArray);
189 if (ILM_SUCCESS != callResult)
191 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
192 cout << "Failed to get layers on screen with ID "<< screenId <<"\n";
196 scene.screenLayers[screenId] = vector<t_ilm_layer>(layerArray, layerArray + layerCount);
198 //preserve rendering order for layers on each screen
199 for (int j = 0; j < layerCount; ++j)
201 t_ilm_layer layerId = layerArray[j];
203 scene.layerScreen[layerId] = screenId;
207 //get all layers (rendered and not rendered)
208 t_ilm_int layerCount = 0;
209 t_ilm_layer* layerArray = NULL;
210 ilm_getLayerIDs(&layerCount, &layerArray);
211 scene.layers = vector<t_ilm_layer>(layerArray, layerArray + layerCount);
213 for (int j = 0; j < layerCount; ++j)
215 t_ilm_layer layerId = layerArray[j];
218 ilmLayerProperties lp;
220 callResult = ilm_getPropertiesOfLayer(layerId, &lp);
221 if (ILM_SUCCESS != callResult)
223 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
224 cout << "Failed to get properties of layer with ID "<< layerId <<"\n";
228 scene.layerProperties[layerId] = lp;
231 //surfaces on each layer
232 for (int j = 0; j < layerCount; ++j)
234 t_ilm_layer layerId = layerArray[j];
236 //surfaces on layer (in rendering order)
237 int surfaceCount = 0;
238 t_ilm_surface* surfaceArray = NULL;
240 callResult = ilm_getSurfaceIDsOnLayer(layerId, &surfaceCount, &surfaceArray);
241 if (ILM_SUCCESS != callResult)
243 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
244 cout << "Failed to get surfaces on layer with ID "<< layerId <<"\n";
248 //rendering order on layer
249 scene.layerSurfaces[layerId] = vector<t_ilm_surface>(surfaceArray, surfaceArray + surfaceCount);
251 //make each surface aware of its layer
252 for (int k = 0; k < surfaceCount; ++k)
254 t_ilm_surface surfaceId = surfaceArray[k];
255 scene.surfaceLayer[surfaceId] = layerId;
259 //get all surfaces (on layers and without layers)
260 t_ilm_int surfaceCount = 0;
261 t_ilm_surface* surfaceArray = NULL;
263 callResult = ilm_getSurfaceIDs(&surfaceCount, &surfaceArray);
264 if (ILM_SUCCESS != callResult)
266 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
267 cout << "Failed to get available surfaces\n";
271 scene.surfaces = vector<t_ilm_surface>(surfaceArray, surfaceArray + surfaceCount);
273 for (int k = 0; k < surfaceCount; ++k)
275 t_ilm_surface surfaceId = surfaceArray[k];
278 ilmSurfaceProperties sp;
280 callResult = ilm_getPropertiesOfSurface(surfaceId, &sp);
281 if (ILM_SUCCESS != callResult)
283 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
284 cout << "Failed to get properties of surface with ID " << surfaceId << "\n";
288 scene.surfaceProperties[surfaceId] = sp;
292 void setScene(t_scene_data* pScene, bool clean)
294 t_scene_data initialScene;
295 captureSceneData(&initialScene);
297 //dismantel current scene
298 for (map<t_ilm_surface, t_ilm_layer>::iterator it = initialScene.surfaceLayer.begin();
299 it != initialScene.surfaceLayer.end(); ++it)
301 t_ilm_surface surface = it->first;
302 t_ilm_layer layer = it->second;
304 ilmErrorTypes callResult = ilm_layerRemoveSurface(layer, surface);
305 if (ILM_SUCCESS != callResult)
307 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
308 cout << "Failed to remove surface " << surface << " from layer " << layer << "\n";
315 //cleaning scene if needed
318 //remove unneeded surfaces and layers!
319 for (vector<t_ilm_surface>::iterator it = initialScene.surfaces.begin();
320 it != initialScene.surfaces.end(); ++it)
322 t_ilm_surface surface = *it;
323 //if surface does not exist (in final scene)
324 if (find(pScene->surfaces.begin(), pScene->surfaces.end(), surface) == pScene->surfaces.end())
327 ilmErrorTypes callResult = ilm_surfaceRemove(surface);
328 if (ILM_SUCCESS != callResult)
330 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
331 cout << "Failed to remove surface " << surface << "\n";
339 for (vector<t_ilm_layer>::iterator it = initialScene.layers.begin();
340 it != initialScene.layers.end(); ++it)
342 t_ilm_layer layer = *it;
343 //if layer does not exist (in final scene)
344 if (find(pScene->layers.begin(), pScene->layers.end(), layer) == pScene->layers.end())
347 ilmErrorTypes callResult = ilm_layerRemove(layer);
348 if (ILM_SUCCESS != callResult)
350 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
351 cout << "Failed to remove layer " << layer << "\n";
360 //make sure all layers and surfaces of the new scene are created
361 for (vector<t_ilm_layer>::iterator it = pScene->layers.begin();
362 it != pScene->layers.end(); ++it)
364 t_ilm_layer layer = *it;
365 //if layer does not exist (in initial scene)
366 if (find(initialScene.layers.begin(), initialScene.layers.end(), layer) == initialScene.layers.end())
368 ilmLayerProperties& props = pScene->layerProperties[layer];
370 ilmErrorTypes callResult = ilm_layerCreateWithDimension(&layer, props.origSourceWidth, props.origSourceHeight);
371 if (ILM_SUCCESS != callResult)
373 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
374 cout << "Failed to create layer with ID " << layer << " and dimensions (" << props.origSourceWidth << " ," << props.origSourceHeight << ")\n";
382 for (vector<t_ilm_surface>::iterator it = pScene->surfaces.begin();
383 it != pScene->surfaces.end(); ++it)
385 t_ilm_surface surface = *it;
386 //if surface does not exist (in initial scene)
387 if (find(initialScene.surfaces.begin(), initialScene.surfaces.end(), surface)
388 == initialScene.surfaces.end())
390 ilmSurfaceProperties& props = pScene->surfaceProperties[surface];
392 ilm_surfaceCreate(props.nativeSurface,
393 props.origSourceWidth,
394 props.origSourceHeight,
395 (e_ilmPixelFormat) props.pixelformat,
399 //if surface exists but mapped to different native: remove then recreate it
400 if (initialScene.surfaceProperties[surface].nativeSurface
401 != pScene->surfaceProperties[surface].nativeSurface)
403 ilm_surfaceRemove(surface);
404 ilmSurfaceProperties& props = pScene->surfaceProperties[surface];
405 ilm_surfaceCreate(props.nativeSurface,
406 props.origSourceWidth,
407 props.origSourceHeight,
408 (e_ilmPixelFormat) props.pixelformat,
415 //set render order of layers on each screen
416 for (vector<t_ilm_display>::iterator it = pScene->screens.begin();
417 it != pScene->screens.end(); ++it)
419 t_ilm_display screen = *it;
420 vector<t_ilm_layer>& layers = pScene->screenLayers[screen];
422 //if vector data is NULL (no data in vector)
423 if (layers.data() == NULL)
428 ilm_displaySetRenderOrder(screen, layers.data(), layers.size());
433 //set render order of surfaces on each layer
434 for (map<t_ilm_layer, vector<t_ilm_surface> >::iterator it = pScene->layerSurfaces.begin();
435 it != pScene->layerSurfaces.end(); ++it)
437 t_ilm_layer layer = it->first;
438 vector<t_ilm_surface>& surfaces = it->second;
439 if(surfaces.data() == NULL)
444 ilm_layerSetRenderOrder(layer, surfaces.data(), surfaces.size());
449 //set properties of layers
450 for (map<t_ilm_layer, ilmLayerProperties>::iterator it = pScene->layerProperties.begin();
451 it != pScene->layerProperties.end(); ++it)
453 t_ilm_layer layer = it->first;
454 ilmLayerProperties& props = it->second;
456 //set layer properties
457 ilm_layerSetDestinationRectangle(layer, props.destX, props.destY, props.destWidth, props.destHeight);
460 ilm_layerSetOpacity(layer, props.opacity);
463 ilm_layerSetOrientation(layer, props.orientation);
466 ilm_layerSetSourceRectangle(layer, props.sourceX, props.sourceY, props.sourceWidth, props.sourceHeight);
469 ilm_layerSetVisibility(layer, props.visibility);
473 //set properties of surfaces
474 for (map<t_ilm_surface, ilmSurfaceProperties>::iterator it = pScene->surfaceProperties.begin();
475 it != pScene->surfaceProperties.end(); ++it)
477 t_ilm_surface surface = it->first;
478 ilmSurfaceProperties& props = it->second;
480 ilm_surfaceSetNativeContent(props.nativeSurface,
481 props.origSourceWidth,
482 props.origSourceHeight,
483 (e_ilmPixelFormat) props.pixelformat,
487 ilm_surfaceSetOpacity(surface, props.opacity);
490 ilm_surfaceSetOrientation(surface, props.orientation);
493 ilm_surfaceSetSourceRectangle(surface, props.sourceX, props.sourceY, props.sourceWidth, props.sourceHeight);
496 ilm_surfaceSetDestinationRectangle(surface, props.destX, props.destY, props.destWidth, props.destHeight);
499 ilm_surfaceSetVisibility(surface, props.visibility);
506 void emptyScene(t_scene_data* pScene)
508 pScene->extraLayer = -1;
509 pScene->layerProperties.clear();
510 pScene->layerScreen.clear();
511 pScene->layerSurfaces.clear();
512 pScene->layers.clear();
513 pScene->screenLayers.clear();
514 pScene->screens.clear();
515 pScene->surfaceLayer.clear();
516 pScene->surfaceProperties.clear();
517 pScene->surfaces.clear();
520 t_ilm_display* screenArray;
521 ilm_getScreenIDs(&count, &screenArray);
522 for(t_ilm_uint i = 0 ; i < count ; ++i)
524 pScene->screens.push_back(screenArray[i]);
526 ilmErrorTypes callResult = ilm_getScreenResolution(screenArray[0], & pScene->screenWidth, & pScene->screenHeight);
527 if (ILM_SUCCESS != callResult)
529 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
530 cout << "Failed to get screen resolution for screen with ID " << screenArray[0] << "\n";
536 t_scene_data cloneToUniLayerScene(t_scene_data* pScene)
538 //prepare values needed for dummy (animation) scene
539 t_ilm_layer extraLayer = -1;
540 //if the scene is already uni layer just reuse same layer
541 if(pScene->layers.size() == 1)
543 extraLayer = pScene->layers[0];
546 ilmErrorTypes callResult = ilm_layerCreate(&extraLayer);
547 if (ILM_SUCCESS != callResult)
549 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
550 cout << "Failed to create layer\n";
553 ilmLayerProperties extraLayerProperties;
554 extraLayerProperties.destHeight = pScene->screenHeight;
555 extraLayerProperties.destWidth = pScene->screenWidth;
556 extraLayerProperties.destX = 0;
557 extraLayerProperties.destY = 0;
558 extraLayerProperties.opacity = 1;
559 extraLayerProperties.orientation = (e_ilmOrientation) 0;
560 extraLayerProperties.origSourceHeight = pScene->screenHeight;
561 extraLayerProperties.origSourceWidth = pScene->screenWidth;
562 extraLayerProperties.sourceHeight = pScene->screenHeight;
563 extraLayerProperties.sourceWidth = pScene->screenWidth;
564 extraLayerProperties.sourceX = 0;
565 extraLayerProperties.sourceY = 0;
566 extraLayerProperties.type = 2;
567 extraLayerProperties.visibility = 1;
569 t_ilm_display screen = pScene->screens[0];
571 vector<t_ilm_surface> finalRenderOrder = getSceneRenderOrder(pScene);
573 //build dummy scene to be used for animation
574 t_scene_data dummyScene;
575 //to avoid destroying and recreating surfaces and layers
576 dummyScene.surfaces = pScene->surfaces;
579 dummyScene.screens.push_back(screen);
580 dummyScene.screenLayers[screen] = vector<t_ilm_layer>(&extraLayer, &extraLayer + 1);
581 dummyScene.layerScreen[extraLayer] = screen;
582 dummyScene.layerSurfaces[extraLayer] = finalRenderOrder;
584 for (vector<t_ilm_surface>::iterator it = finalRenderOrder.begin();
585 it != finalRenderOrder.end(); ++it)
587 dummyScene.surfaceProperties[*it] = pScene->surfaceProperties[*it];
589 tuple4 coords = getSurfaceScreenCoordinates(pScene, *it);
591 dummyScene.surfaceProperties[*it].destX = coords.x;
592 dummyScene.surfaceProperties[*it].destY = coords.y;
593 dummyScene.surfaceProperties[*it].destWidth = coords.z - coords.x;
594 dummyScene.surfaceProperties[*it].destHeight = coords.w - coords.y;
597 dummyScene.layerProperties[extraLayer] = extraLayerProperties;
599 dummyScene.layerScreen[extraLayer] = screen;
601 for (vector<t_ilm_surface>::iterator it = finalRenderOrder.begin();
602 it != finalRenderOrder.end(); ++it)
604 dummyScene.surfaceLayer[*it] = extraLayer;
607 dummyScene.surfaces = finalRenderOrder;
608 dummyScene.layers = vector<t_ilm_layer>(&extraLayer, &extraLayer + 1);
610 dummyScene.extraLayer = -1;
611 dummyScene.screenWidth = pScene->screenWidth;
612 dummyScene.screenHeight = pScene->screenHeight;
617 tuple4 interpolateCoordinatesHelper(tuple4& start, tuple4& end, float t)
619 t = static_cast<float>(1 - pow((t - 1), 4));
620 return tuple4(static_cast<int>(start.x * (1 - t) + end.x * t),
621 static_cast<int>(start.y * (1 - t) + end.y * t),
622 static_cast<int>(start.z * (1 - t) + end.z * t),
623 static_cast<int>(start.w * (1 - t) + end.w * t));
626 void transformScene(t_scene_data* pInitialScene, t_scene_data* pFinalScene, t_ilm_long durationMillis, t_ilm_int frameCount)
628 t_scene_data dummyScene = cloneToUniLayerScene(pFinalScene);
630 setScene(&dummyScene);
632 //animate dummy scene !
634 if (durationMillis > 0 && frameCount > 0)
637 long sleepMillis = durationMillis / frameCount;
638 struct timespec sleepTime;
639 sleepTime.tv_nsec = (sleepMillis% 1000) * 1000000;
640 sleepTime.tv_sec = sleepMillis / 1000;
642 struct timespec remTime;
644 //start and end coordinates of surfaces
645 map<t_ilm_surface, tuple4> start;
646 map<t_ilm_surface, tuple4> end;
647 for(vector<t_ilm_surface>::iterator it = dummyScene.surfaces.begin();
648 it != dummyScene.surfaces.end(); ++it)
650 t_ilm_surface surface = *it;
651 start[surface] = getSurfaceScreenCoordinates(pInitialScene, surface);
653 end[surface] = getSurfaceScreenCoordinates(pFinalScene, surface);
656 for (int i = 0; i < frameCount; ++i)
658 float t = 1.0 * i / frameCount;
660 //interpolate properties of each surface
661 for(vector<t_ilm_surface>::iterator it = dummyScene.surfaces.begin();
662 it != dummyScene.surfaces.end(); ++it)
664 t_ilm_surface surface = *it;
665 tuple4 coords = interpolateCoordinatesHelper(start[surface], end[surface], t);
667 ilmErrorTypes callResult = ilm_surfaceSetDestinationRectangle(surface, coords.x, coords.y, coords.z - coords.x, coords.w - coords.y);
668 if (ILM_SUCCESS != callResult)
670 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
671 cout << "Failed to set destination rectangle (" << coords.x << "," << coords.y << ", "<< coords.z - coords.x << ", " << coords.w - coords.y
672 <<") for surface with ID " << surface << "\n";
676 float opacity = t * pFinalScene->surfaceProperties[surface].opacity
677 + (1-t) * pInitialScene->surfaceProperties[surface].opacity;
678 ilm_surfaceSetOpacity(surface, opacity);
684 nanosleep(&sleepTime, &remTime);
689 setScene(pFinalScene);
692 static t_scene_data* global_pOriginalScene = NULL;
694 void interruptSignalRestoreScene(int s)
698 cout<<"LayerManagerControl :Interrupt signal...\n";
699 if (global_pOriginalScene != NULL)
701 setScene(global_pOriginalScene, true);
707 void setSceneToRestore(t_scene_data* pScene)
709 if (global_pOriginalScene == NULL)
711 global_pOriginalScene = pScene;
712 struct sigaction signalAction;
714 signalAction.sa_handler = &interruptSignalRestoreScene;
715 sigemptyset(&signalAction.sa_mask);
716 signalAction.sa_flags = 0;
718 sigaction(SIGINT, &signalAction, NULL);