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 "ilm_control.h"
21 #include "LMControl.h"
22
23 #include <algorithm>
24 using std::find;
25
26 #include <cmath>
27 using std::max;
28 using std::min;
29
30 #include <iterator>
31 using std::iterator;
32
33 #include <iostream>
34 using std::cout;
35 using std::cin;
36 using std::endl;
37
38 #include <vector>
39 using std::vector;
40
41 #include <pthread.h>
42 #include <signal.h>
43 #include <sys/types.h>
44 #include <unistd.h>
45
46
getSurfaceScreenCoordinates(ilmSurfaceProperties targetSurfaceProperties,ilmLayerProperties targetLayerProperties)47 tuple4 getSurfaceScreenCoordinates(ilmSurfaceProperties targetSurfaceProperties, ilmLayerProperties targetLayerProperties)
48 {
49 t_ilm_float horizontalScale = targetLayerProperties.sourceWidth ?
50 1.0 * targetLayerProperties.destWidth / targetLayerProperties.sourceWidth : 0;
51
52 t_ilm_float targetX1 = targetLayerProperties.destX + horizontalScale
53 * (targetSurfaceProperties.destX - targetLayerProperties.sourceX);
54 t_ilm_float targetX2 = targetX1 + horizontalScale * targetSurfaceProperties.destWidth;
55
56 t_ilm_float verticalScale = targetLayerProperties.sourceHeight ?
57 1.0 * targetLayerProperties.destHeight / targetLayerProperties.sourceHeight : 0;
58
59 t_ilm_float targetY1 = targetLayerProperties.destY + verticalScale
60 * (targetSurfaceProperties.destY - targetLayerProperties.sourceY);
61 t_ilm_float targetY2 = targetY1 + verticalScale * targetSurfaceProperties.destHeight;
62
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));
67
68 return targetSurfaceCoordinates;
69 }
70
getSurfaceScreenCoordinates(t_scene_data * pScene,t_ilm_surface surface)71 tuple4 getSurfaceScreenCoordinates(t_scene_data* pScene, t_ilm_surface surface)
72 {
73 tuple4 surfaceCoordinates;
74
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())
77 {
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];
82
83 surfaceCoordinates = getSurfaceScreenCoordinates(surfaceProperties, layerProperties);
84 }
85 //if surface does not belong to a layer just assume it belongs to a layer that fills the screen
86 else
87 {
88 ilmSurfaceProperties surfaceProperties = pScene->surfaceProperties[surface];
89
90 surfaceCoordinates.x = surfaceProperties.destX;
91 surfaceCoordinates.y = surfaceProperties.destY;
92 surfaceCoordinates.z = surfaceProperties.destX + surfaceProperties.destWidth;
93 surfaceCoordinates.w = surfaceProperties.destX + surfaceProperties.destHeight;
94 }
95
96 return surfaceCoordinates;
97 }
98
getSceneRenderOrder(t_scene_data * pScene)99 vector<t_ilm_surface> getSceneRenderOrder(t_scene_data* pScene)
100 {
101 t_scene_data& scene = *pScene;
102 vector<t_ilm_surface> renderOrder;
103
104 //iterate over screens
105 for (vector<t_ilm_display>::iterator it = scene.screens.begin(); it != scene.screens.end(); ++it)
106 {
107 t_ilm_display screen = *it;
108 vector<t_ilm_layer> layers = scene.screenLayers[screen];
109
110 //iterate over layers
111 for (vector<t_ilm_layer>::iterator layerIterator = layers.begin();
112 layerIterator != layers.end(); ++layerIterator)
113 {
114 t_ilm_layer layer = (*layerIterator);
115 vector<t_ilm_surface> surfaces = scene.layerSurfaces[layer];
116
117 //iterate over surfaces
118 for (vector<t_ilm_surface>::iterator it = surfaces.begin(); it != surfaces.end(); ++it)
119 {
120 t_ilm_surface surface = *it;
121
122 renderOrder.push_back(surface);
123 }
124 }
125 }
126
127 return renderOrder;
128 }
129
captureSceneData(t_scene_data * pScene)130 void captureSceneData(t_scene_data* pScene)
131 {
132 t_scene_data& scene = *pScene;
133
134 //get screen information
135 t_ilm_uint screenWidth = 0;
136 t_ilm_uint screenHeight = 0;
137
138 ilmErrorTypes callResult = ilm_getScreenResolution(0, &screenWidth, &screenHeight);
139 if (ILM_SUCCESS != callResult)
140 {
141 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
142 cout << "Failed to get screen resolution for screen with ID " << 0 << "\n";
143 return;
144 }
145
146 scene.screenWidth = screenWidth;
147 scene.screenHeight = screenHeight;
148
149 //extra layer for debugging
150 scene.extraLayer = 0xFFFFFFFF;
151
152 //get screens
153 unsigned int screenCount = 0;
154 t_ilm_display* screenArray = NULL;
155
156 callResult = ilm_getScreenIDs(&screenCount, &screenArray);
157 if (ILM_SUCCESS != callResult)
158 {
159 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
160 cout << "Failed to get available screen IDs\n";
161 return;
162 }
163
164 scene.screens = vector<t_ilm_display>(screenArray, screenArray + screenCount);
165
166 //layers on each screen
167 for (unsigned int i = 0; i < screenCount; ++i)
168 {
169 t_ilm_display screenId = screenArray[i];
170
171 t_ilm_int layerCount = 0;
172 t_ilm_layer* layerArray = NULL;
173
174 callResult = ilm_getLayerIDsOnScreen(screenId, &layerCount, &layerArray);
175 if (ILM_SUCCESS != callResult)
176 {
177 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
178 cout << "Failed to get layers on screen with ID " << screenId << "\n";
179 return;
180 }
181
182 scene.screenLayers[screenId] = vector<t_ilm_layer>(layerArray, layerArray + layerCount);
183
184 //preserve rendering order for layers on each screen
185 for (int j = 0; j < layerCount; ++j)
186 {
187 t_ilm_layer layerId = layerArray[j];
188
189 scene.layerScreen[layerId] = screenId;
190 }
191 }
192
193 //get all layers (rendered and not rendered)
194 t_ilm_int layerCount = 0;
195 t_ilm_layer* layerArray = NULL;
196 ilm_getLayerIDs(&layerCount, &layerArray);
197 scene.layers = vector<t_ilm_layer>(layerArray, layerArray + layerCount);
198
199 for (int j = 0; j < layerCount; ++j)
200 {
201 t_ilm_layer layerId = layerArray[j];
202
203 //layer properties
204 ilmLayerProperties lp;
205
206 callResult = ilm_getPropertiesOfLayer(layerId, &lp);
207 if (ILM_SUCCESS != callResult)
208 {
209 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
210 cout << "Failed to get properties of layer with ID " << layerId << "\n";
211 return;
212 }
213
214 scene.layerProperties[layerId] = lp;
215 }
216
217 //surfaces on each layer
218 for (int j = 0; j < layerCount; ++j)
219 {
220 t_ilm_layer layerId = layerArray[j];
221
222 //surfaces on layer (in rendering order)
223 int surfaceCount = 0;
224 t_ilm_surface* surfaceArray = NULL;
225
226 callResult = ilm_getSurfaceIDsOnLayer(layerId, &surfaceCount, &surfaceArray);
227 if (ILM_SUCCESS != callResult)
228 {
229 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
230 cout << "Failed to get surfaces on layer with ID " << layerId << "\n";
231 return;
232 }
233
234 //rendering order on layer
235 scene.layerSurfaces[layerId] = vector<t_ilm_surface>(surfaceArray, surfaceArray + surfaceCount);
236
237 //make each surface aware of its layer
238 for (int k = 0; k < surfaceCount; ++k)
239 {
240 t_ilm_surface surfaceId = surfaceArray[k];
241 scene.surfaceLayer[surfaceId] = layerId;
242 }
243 }
244
245 //get all surfaces (on layers and without layers)
246 t_ilm_int surfaceCount = 0;
247 t_ilm_surface* surfaceArray = NULL;
248
249 callResult = ilm_getSurfaceIDs(&surfaceCount, &surfaceArray);
250 if (ILM_SUCCESS != callResult)
251 {
252 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
253 cout << "Failed to get available surfaces\n";
254 return;
255 }
256
257 scene.surfaces = vector<t_ilm_surface>(surfaceArray, surfaceArray + surfaceCount);
258
259 for (int k = 0; k < surfaceCount; ++k)
260 {
261 t_ilm_surface surfaceId = surfaceArray[k];
262
263 //surface properties
264 ilmSurfaceProperties sp;
265
266 callResult = ilm_getPropertiesOfSurface(surfaceId, &sp);
267 if (ILM_SUCCESS != callResult)
268 {
269 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
270 cout << "Failed to get properties of surface with ID " << surfaceId << "\n";
271 return;
272 }
273
274 scene.surfaceProperties[surfaceId] = sp;
275 }
276 }
277