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::registry_handle_global(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
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_registry_bind(registry, name, &wl_compositor_interface, 1);
78 ans_strcmp = strcmp(interface, "serverinfo");
81 p_wlCtx->wlExtServerinfo = (struct serverinfo*)wl_registry_bind(registry, name, &serverinfo_interface, 1);
82 serverinfo_add_listener(p_wlCtx->wlExtServerinfo, &serverinfo_listener_list, data);
83 serverinfo_get_connection_id(p_wlCtx->wlExtServerinfo);
88 static const struct wl_registry_listener registry_listener = {
89 OpenGLES2App::registry_handle_global,
94 #define RUNTIME_IN_MS() (GetTickCount() - startTimeInMS)
97 OpenGLES2App::OpenGLES2App(float fps, float animationSpeed, SurfaceConfiguration* config)
98 : m_framesPerSecond(fps)
99 , m_animationSpeed(animationSpeed)
100 , m_timerIntervalInMs(1000.0 / m_framesPerSecond)
103 createWLContext(config);
105 setupLayerMangement(config);
109 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
113 glClearColor(0.2f, 0.2f, 0.5f, 1.0f);
118 glDisable(GL_CULL_FACE);
119 glEnable(GL_DEPTH_TEST);
120 glDepthFunc(GL_LEQUAL);
123 OpenGLES2App::~OpenGLES2App()
130 void OpenGLES2App::mainloop()
132 unsigned int startTimeInMS = GetTickCount();
133 unsigned int frameStartTimeInMS = 0;
134 unsigned int renderTimeInMS = 0;
135 unsigned int frameEndTimeInMS = 0;
136 unsigned int frameTimeInMS = 0;
140 frameTimeInMS = frameEndTimeInMS - frameStartTimeInMS;
141 frameStartTimeInMS = RUNTIME_IN_MS();
143 update(m_animationSpeed * frameStartTimeInMS, m_animationSpeed * frameTimeInMS);
147 renderTimeInMS = RUNTIME_IN_MS() - frameStartTimeInMS;
149 if (renderTimeInMS < m_timerIntervalInMs)
151 usleep((m_timerIntervalInMs - renderTimeInMS) * 1000);
154 frameEndTimeInMS = RUNTIME_IN_MS();
158 bool OpenGLES2App::createWLContext(SurfaceConfiguration* config)
160 t_ilm_bool result = ILM_TRUE;
161 int width = config->surfaceWidth;
162 int height = config->surfaceHeight;
164 memset(&m_wlContextStruct, 0, sizeof(m_wlContextStruct));
166 m_wlContextStruct.width = width;
167 m_wlContextStruct.height = height;
168 m_wlContextStruct.wlDisplay = wl_display_connect(NULL);
169 if (NULL == m_wlContextStruct.wlDisplay)
171 cout<<"Error: wl_display_connect() failed.\n";
174 m_wlContextStruct.wlRegistry = wl_display_get_registry(m_wlContextStruct.wlDisplay);
175 wl_registry_add_listener(m_wlContextStruct.wlRegistry, ®istry_listener, &m_wlContextStruct);
176 wl_display_dispatch(m_wlContextStruct.wlDisplay);
177 wl_display_roundtrip(m_wlContextStruct.wlDisplay);
179 m_wlContextStruct.wlSurface = wl_compositor_create_surface(m_wlContextStruct.wlCompositor);
180 if (NULL == m_wlContextStruct.wlSurface)
182 cout<<"Error: wl_compositor_create_surface() failed.\n";
186 m_wlContextStruct.wlNativeWindow = wl_egl_window_create(m_wlContextStruct.wlSurface, width, height);
187 if (NULL == m_wlContextStruct.wlNativeWindow)
189 cout<<"Error: wl_egl_window_create() failed"<<endl;
196 bool OpenGLES2App::createEGLContext()
198 t_ilm_bool result = ILM_TRUE;
199 EGLint eglstatus = EGL_SUCCESS;
200 m_eglContextStruct.eglDisplay = NULL;
201 m_eglContextStruct.eglSurface = NULL;
202 m_eglContextStruct.eglContext = NULL;
204 m_eglContextStruct.eglDisplay = eglGetDisplay(m_wlContextStruct.wlDisplay);
205 eglstatus = eglGetError();
206 if (!m_eglContextStruct.eglDisplay)
208 cout << "Error: eglGetDisplay() failed.\n";
211 EGLint iMajorVersion, iMinorVersion;
212 if (!eglInitialize(m_eglContextStruct.eglDisplay, &iMajorVersion,
215 cout << "Error: eglInitialize() failed.\n";
218 eglBindAPI(EGL_OPENGL_ES_API);
219 eglstatus = eglGetError();
220 if (eglstatus != EGL_SUCCESS)
222 cout << "Error: eglBindAPI() failed.\n";
224 EGLint pi32ConfigAttribs[] = {
225 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
226 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
237 if (!eglChooseConfig(m_eglContextStruct.eglDisplay, pi32ConfigAttribs, &m_eglContextStruct.eglConfig, 1, &iConfigs) || (iConfigs != 1))
239 cout << "Error: eglChooseConfig() failed.\n";
242 m_eglContextStruct.eglSurface = eglCreateWindowSurface(
243 m_eglContextStruct.eglDisplay, m_eglContextStruct.eglConfig,
244 m_wlContextStruct.wlNativeWindow, NULL);
245 eglstatus = eglGetError();
247 if (eglstatus != EGL_SUCCESS)
249 cout << "Error: eglCreateWindowSurface() failed.\n";
252 EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
254 m_eglContextStruct.eglContext = eglCreateContext(
255 m_eglContextStruct.eglDisplay, m_eglContextStruct.eglConfig, NULL,
258 eglstatus = eglGetError();
259 if (eglstatus != EGL_SUCCESS)
261 cout << "Error: eglCreateContext() failed.\n";
264 eglMakeCurrent(m_eglContextStruct.eglDisplay,
265 m_eglContextStruct.eglSurface, m_eglContextStruct.eglSurface,
266 m_eglContextStruct.eglContext);
267 eglSwapInterval(m_eglContextStruct.eglDisplay, 1);
268 eglstatus = eglGetError();
269 if (eglstatus != EGL_SUCCESS)
271 cout << "Error: eglMakeCurrent() failed.\n";
277 bool OpenGLES2App::setupLayerMangement(SurfaceConfiguration* config)
279 ilmErrorTypes error = ILM_FAILED;
281 // register surfaces to layermanager
282 t_ilm_layer layerid = (t_ilm_layer)config->layerId;//LAYER_EXAMPLE_GLES_APPLICATIONS;
283 t_ilm_surface surfaceid = (t_ilm_surface)config->surfaceId;//SURFACE_EXAMPLE_EGLX11_APPLICATION;
284 int width = config->surfaceWidth;
285 int height = config->surfaceHeight;
286 int posX = config->surfacePosX;
287 int posY = config->surfacePosY;
288 float opacity = config->opacity;
292 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
296 glClearColor(0.2f, 0.2f, 0.5f, 1.0f);
298 // TODO: auto generate surface id
299 cout << "creating surface " << surfaceid << "\n";
300 struct wl_object* p_obj = (struct wl_object*)m_wlContextStruct.wlSurface;
301 uint32_t native_ilm_handle = 0;
302 native_ilm_handle = (m_wlContextStruct.connect_id << 16) | (uint32_t)p_obj->id;
303 cout<<"create a surface 0x"<<(t_ilm_nativehandle) native_ilm_handle<<"\n";
304 error = ilm_surfaceCreate( (t_ilm_nativehandle) native_ilm_handle, width, height,
305 ILM_PIXELFORMAT_RGBA_8888, &surfaceid);
307 cout << "set surface " << surfaceid << " dest region " << posX << ", " << posY << ", " << width << ", " << height << "\n";
308 ilm_surfaceSetDestinationRectangle(surfaceid, posX, posY, width, height);
310 cout << "set surface " << surfaceid << " src region " << 0 << ", " << 0 << ", " << width << ", " << height << "\n";
311 error = ilm_surfaceSetSourceRectangle(surfaceid, 0, 0, width, height);
313 cout << "Set surface " << surfaceid << " visible\n";
314 error = ilm_surfaceSetVisibility(surfaceid, ILM_TRUE);
316 cout << "Set surface " << surfaceid << " opacity " << opacity << "\n";
317 ilm_surfaceSetOpacity(surfaceid, opacity);
319 cout << "add surface " << surfaceid << " to layer " << layerid << "\n";
320 error = ilm_layerAddSurface(layerid, surfaceid);
323 error = ilm_commitChanges();
328 void OpenGLES2App::destroyEglContext()
330 if (m_eglContextStruct.eglDisplay != NULL)
332 eglMakeCurrent(m_eglContextStruct.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
333 eglTerminate(m_eglContextStruct.eglDisplay);
337 void OpenGLES2App::destroyWLContext()
339 if (m_wlContextStruct.wlNativeWindow)
341 wl_egl_window_destroy(m_wlContextStruct.wlNativeWindow);
343 if (m_wlContextStruct.wlSurface)
345 wl_surface_destroy(m_wlContextStruct.wlSurface);
347 if (m_wlContextStruct.wlCompositor)
349 wl_compositor_destroy(m_wlContextStruct.wlCompositor);
353 unsigned int OpenGLES2App::GetTickCount()
356 gettimeofday(&ts, 0);
357 return (t_ilm_uint) (ts.tv_sec * 1000 + (ts.tv_usec / 1000));
361 OpenGLES2App::frame_listener_func(void *data, struct wl_callback *callback, uint32_t time)
363 data = data; // TODO:to avoid warning
364 time = time; // TODO:to avoid warning
367 wl_callback_destroy(callback);
371 static const struct wl_callback_listener frame_listener = {
372 OpenGLES2App::frame_listener_func
375 void OpenGLES2App::swapBuffers()
377 eglSwapBuffers(m_eglContextStruct.eglDisplay, m_eglContextStruct.eglSurface);
379 struct wl_callback* callback = wl_surface_frame(m_wlContextStruct.wlSurface);
380 wl_callback_add_listener(callback, &frame_listener, NULL);
381 wl_surface_commit(m_wlContextStruct.wlSurface);
382 wl_display_flush(m_wlContextStruct.wlDisplay);