1 /***************************************************************************
3 * Copyright 2010, 2011 BMW Car IT GmbH
4 * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ****************************************************************************/
20 #include "OpenGLES2App.h"
21 #include "LayerScene.h"
22 #include <ilm_client.h>
40 #include <sys/ioctl.h>
41 #include <sys/types.h>
48 #include "WaylandServerinfoClientProtocol.h"
52 void OpenGLES2App::serverinfoListener(void *data, struct serverinfo *pServerinfo, uint32_t client_handle)
54 pServerinfo = pServerinfo; // TODO:to avoid warning
55 WLContextStruct* p_wlCtx = (WLContextStruct*)data;
56 p_wlCtx->connect_id = client_handle;
59 struct serverinfo_listener serverinfo_listener_list = {
60 OpenGLES2App::serverinfoListener
63 void OpenGLES2App::display_handle_global(struct wl_display* display, uint32_t id, const char* interface, uint32_t version, void* data)
65 version = version; // TODO:to avoid warning
66 WLContextStruct* p_wlCtx = (WLContextStruct*)data;
71 ans_strcmp = strcmp(interface, "wl_compositor");
74 p_wlCtx->wlCompositor = (wl_compositor*)wl_display_bind(display, id, &wl_compositor_interface);
78 ans_strcmp = strcmp(interface, "tunneler");
81 p_wlCtx->wlExtServerinfo = (struct serverinfo*)wl_display_bind(display, id, &serverinfo_interface);
82 serverinfo_add_listener(p_wlCtx->wlExtServerinfo, &serverinfo_listener_list, data);
83 serverinfo_get_connection_id(p_wlCtx->wlExtServerinfo);
88 int OpenGLES2App::event_mask_update(uint32_t mask, void* data)
90 WLContextStruct* p_wlCtx = (WLContextStruct*)data;
96 #define RUNTIME_IN_MS() (GetTickCount() - startTimeInMS)
99 OpenGLES2App::OpenGLES2App(float fps, float animationSpeed, SurfaceConfiguration* config)
100 : m_framesPerSecond(fps)
101 , m_animationSpeed(animationSpeed)
102 , m_timerIntervalInMs(1000.0 / m_framesPerSecond)
105 createWLContext(config);
107 setupLayerMangement(config);
111 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
115 glClearColor(0.2f, 0.2f, 0.5f, 1.0f);
120 glDisable(GL_CULL_FACE);
121 glEnable(GL_DEPTH_TEST);
122 glDepthFunc(GL_LEQUAL);
125 OpenGLES2App::~OpenGLES2App()
132 void OpenGLES2App::mainloop()
134 unsigned int startTimeInMS = GetTickCount();
135 unsigned int frameStartTimeInMS = 0;
136 unsigned int renderTimeInMS = 0;
137 unsigned int frameEndTimeInMS = 0;
138 unsigned int frameTimeInMS = 0;
142 frameTimeInMS = frameEndTimeInMS - frameStartTimeInMS;
143 frameStartTimeInMS = RUNTIME_IN_MS();
145 update(m_animationSpeed * frameStartTimeInMS, m_animationSpeed * frameTimeInMS);
149 renderTimeInMS = RUNTIME_IN_MS() - frameStartTimeInMS;
151 if (renderTimeInMS < m_timerIntervalInMs)
153 usleep((m_timerIntervalInMs - renderTimeInMS) * 1000);
156 frameEndTimeInMS = RUNTIME_IN_MS();
160 bool OpenGLES2App::createWLContext(SurfaceConfiguration* config)
162 t_ilm_bool result = ILM_TRUE;
163 int width = config->surfaceWidth;
164 int height = config->surfaceHeight;
166 memset(&m_wlContextStruct, 0, sizeof(m_wlContextStruct));
168 m_wlContextStruct.width = width;
169 m_wlContextStruct.height = height;
170 m_wlContextStruct.wlDisplay = wl_display_connect(NULL);
171 if (NULL == m_wlContextStruct.wlDisplay)
173 cout<<"Error: wl_display_connect() failed.\n";
176 wl_display_add_global_listener(m_wlContextStruct.wlDisplay, display_handle_global, &m_wlContextStruct);
177 wl_display_get_fd(m_wlContextStruct.wlDisplay, event_mask_update, &m_wlContextStruct);
178 wl_display_iterate(m_wlContextStruct.wlDisplay, WL_DISPLAY_READABLE);
179 wl_display_roundtrip(m_wlContextStruct.wlDisplay);
181 m_wlContextStruct.wlSurface = wl_compositor_create_surface(m_wlContextStruct.wlCompositor);
182 if (NULL == m_wlContextStruct.wlSurface)
184 cout<<"Error: wl_compositor_create_surface() failed.\n";
188 m_wlContextStruct.wlNativeWindow = wl_egl_window_create(m_wlContextStruct.wlSurface, width, height);
189 if (NULL == m_wlContextStruct.wlNativeWindow)
191 cout<<"Error: wl_egl_window_create() failed"<<endl;
198 bool OpenGLES2App::createEGLContext()
200 t_ilm_bool result = ILM_TRUE;
201 EGLint eglstatus = EGL_SUCCESS;
202 m_eglContextStruct.eglDisplay = NULL;
203 m_eglContextStruct.eglSurface = NULL;
204 m_eglContextStruct.eglContext = NULL;
206 m_eglContextStruct.eglDisplay = eglGetDisplay(m_wlContextStruct.wlDisplay);
207 eglstatus = eglGetError();
208 if (!m_eglContextStruct.eglDisplay)
210 cout << "Error: eglGetDisplay() failed.\n";
213 EGLint iMajorVersion, iMinorVersion;
214 if (!eglInitialize(m_eglContextStruct.eglDisplay, &iMajorVersion,
217 cout << "Error: eglInitialize() failed.\n";
220 eglBindAPI(EGL_OPENGL_ES_API);
221 eglstatus = eglGetError();
222 if (eglstatus != EGL_SUCCESS)
224 cout << "Error: eglBindAPI() failed.\n";
226 EGLint pi32ConfigAttribs[] = {
227 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
228 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
239 if (!eglChooseConfig(m_eglContextStruct.eglDisplay, pi32ConfigAttribs, &m_eglContextStruct.eglConfig, 1, &iConfigs) || (iConfigs != 1))
241 cout << "Error: eglChooseConfig() failed.\n";
244 m_eglContextStruct.eglSurface = eglCreateWindowSurface(
245 m_eglContextStruct.eglDisplay, m_eglContextStruct.eglConfig,
246 m_wlContextStruct.wlNativeWindow, NULL);
247 eglstatus = eglGetError();
249 if (eglstatus != EGL_SUCCESS)
251 cout << "Error: eglCreateWindowSurface() failed.\n";
254 EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
256 m_eglContextStruct.eglContext = eglCreateContext(
257 m_eglContextStruct.eglDisplay, m_eglContextStruct.eglConfig, NULL,
260 eglstatus = eglGetError();
261 if (eglstatus != EGL_SUCCESS)
263 cout << "Error: eglCreateContext() failed.\n";
266 eglMakeCurrent(m_eglContextStruct.eglDisplay,
267 m_eglContextStruct.eglSurface, m_eglContextStruct.eglSurface,
268 m_eglContextStruct.eglContext);
269 eglSwapInterval(m_eglContextStruct.eglDisplay, 1);
270 eglstatus = eglGetError();
271 if (eglstatus != EGL_SUCCESS)
273 cout << "Error: eglMakeCurrent() failed.\n";
279 bool OpenGLES2App::setupLayerMangement(SurfaceConfiguration* config)
281 ilmErrorTypes error = ILM_FAILED;
283 // register surfaces to layermanager
284 t_ilm_layer layerid = (t_ilm_layer)config->layerId;//LAYER_EXAMPLE_GLES_APPLICATIONS;
285 t_ilm_surface surfaceid = (t_ilm_surface)config->surfaceId;//SURFACE_EXAMPLE_EGLX11_APPLICATION;
286 int width = config->surfaceWidth;
287 int height = config->surfaceHeight;
288 int posX = config->surfacePosX;
289 int posY = config->surfacePosY;
290 float opacity = config->opacity;
294 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
298 glClearColor(0.2f, 0.2f, 0.5f, 1.0f);
300 // TODO: auto generate surface id
301 cout << "creating surface " << surfaceid << "\n";
302 struct wl_object* p_obj = (struct wl_object*)m_wlContextStruct.wlSurface;
303 uint32_t native_ilm_handle = 0;
304 native_ilm_handle = (m_wlContextStruct.connect_id << 16) | (uint32_t)p_obj->id;
305 cout<<"create a surface 0x"<<(t_ilm_nativehandle) native_ilm_handle<<"\n";
306 error = ilm_surfaceCreate( (t_ilm_nativehandle) native_ilm_handle, width, height,
307 ILM_PIXELFORMAT_RGBA_8888, &surfaceid);
309 cout << "set surface " << surfaceid << " dest region " << posX << ", " << posY << ", " << width << ", " << height << "\n";
310 ilm_surfaceSetDestinationRectangle(surfaceid, posX, posY, width, height);
312 cout << "set surface " << surfaceid << " src region " << 0 << ", " << 0 << ", " << width << ", " << height << "\n";
313 error = ilm_surfaceSetSourceRectangle(surfaceid, 0, 0, width, height);
315 cout << "Set surface " << surfaceid << " visible\n";
316 error = ilm_surfaceSetVisibility(surfaceid, ILM_TRUE);
318 cout << "Set surface " << surfaceid << " opacity " << opacity << "\n";
319 ilm_surfaceSetOpacity(surfaceid, opacity);
321 cout << "add surface " << surfaceid << " to layer " << layerid << "\n";
322 error = ilm_layerAddSurface(layerid, surfaceid);
325 error = ilm_commitChanges();
330 void OpenGLES2App::destroyEglContext()
332 if (m_eglContextStruct.eglDisplay != NULL)
334 eglMakeCurrent(m_eglContextStruct.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
335 eglTerminate(m_eglContextStruct.eglDisplay);
339 void OpenGLES2App::destroyWLContext()
341 if (m_wlContextStruct.wlNativeWindow)
343 wl_egl_window_destroy(m_wlContextStruct.wlNativeWindow);
345 if (m_wlContextStruct.wlSurface)
347 wl_surface_destroy(m_wlContextStruct.wlSurface);
349 if (m_wlContextStruct.wlCompositor)
351 wl_compositor_destroy(m_wlContextStruct.wlCompositor);
355 unsigned int OpenGLES2App::GetTickCount()
358 gettimeofday(&ts, 0);
359 return (t_ilm_uint) (ts.tv_sec * 1000 + (ts.tv_usec / 1000));
363 OpenGLES2App::frame_listener_func(void *data, struct wl_callback *callback, uint32_t time)
365 data = data; // TODO:to avoid warning
366 time = time; // TODO:to avoid warning
369 wl_callback_destroy(callback);
373 static const struct wl_callback_listener frame_listener = {
374 OpenGLES2App::frame_listener_func
377 void OpenGLES2App::swapBuffers()
379 eglSwapBuffers(m_eglContextStruct.eglDisplay, m_eglContextStruct.eglSurface);
381 struct wl_callback* callback = wl_surface_frame(m_wlContextStruct.wlSurface);
382 wl_callback_add_listener(callback, &frame_listener, NULL);
383 wl_display_flush(m_wlContextStruct.wlDisplay);