2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
22 #include "../../SDL_internal.h"
24 #if SDL_VIDEO_OPENGL_EGL
26 #include "SDL_tizenvideo.h"
27 #include "SDL_tizenopengles.h"
28 #include "SDL_tizenwindow.h"
29 #include "SDL_tizenevents_c.h"
31 #include "SDL_ecore_ipc.h"
32 #include "SDL_tizenvideo.h"
34 #include <wayland-extension/tizen-remote-surface-client-protocol.h>
35 #include <wayland-tbm-client.h>
36 #include <Ecore_Wayland.h>
40 #include "SDL_opengl.h"
41 #endif /* SDL_VIDEO_OPENGL */
43 #if SDL_VIDEO_OPENGL_ES
44 #include "SDL_opengles.h"
45 #endif /* SDL_VIDEO_OPENGL_ES */
47 /* GL and GLES2 headers conflict on Linux 32 bits */
48 #if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL
49 #include "SDL_opengles2.h"
50 #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
52 /* EGL implementation of SDL OpenGL ES support */
53 typedef struct GLES2_Context
55 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
56 #include "../../render/opengles2/SDL_gles2funcs.h"
60 GLfloat vVertices[18]={
69 GLfloat vCoord[12] = {
77 PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = NULL;
78 PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = NULL;
79 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = NULL;
81 SharedIndicatorInfo shared_info;
82 unsigned int textureID;
83 unsigned int indicator_vbo[4], indicator_ibo[4];
92 static int LoadContext(GLES2_Context * data)
94 #define SDL_PROC(ret,func,params) \
96 data->func = SDL_GL_GetProcAddress(#func); \
97 if ( ! data->func ) { \
98 return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \
102 #include "../../render/opengles2/SDL_gles2funcs.h"
109 _tizen_rs_cb_buffer_update(void *data, struct tizen_remote_surface *trs, struct wl_buffer *buffer, uint32_t time)
111 tizen_remote_surface_transfer_visibility(trs, TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE);
112 tbm_surface_h tbmSurface= wl_buffer_get_user_data(buffer);
114 if(eglCreateImageKHR != NULL && glEGLImageTargetTexture2DOES != NULL && eglDestroyImageKHR != NULL)
116 SDL_VideoDevice *_this = SDL_GetVideoDevice();
118 if(shared_info.eglImage_Indicator != NULL)
119 eglDestroyImageKHR(_this->egl_data->egl_display, shared_info.eglImage_Indicator);
121 shared_info.eglImage_Indicator = eglCreateImageKHR(_this->egl_data->egl_display,
122 EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN, tbmSurface, NULL);
124 if(shared_info.eglImage_Indicator == NULL)
126 SDL_Log("[SDL] eglImage is NULL");
129 SDL_Log("[SDL] eglImage : %p", shared_info.eglImage_Indicator);
130 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, shared_info.eglImage_Indicator);
134 tbm_surface_info_s info;
135 tbm_surface_map(tbmSurface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &info);
137 SDL_Log("[SDL] Buffer Update %p %p (%dx%d), format:%d", buffer, tbmSurface, info.width, info.height, info.format);
138 SDL_Log("[SDL] Info size:%d, offset:%d, stride:%d", info.planes[0].size, info.planes[0].offset, info.planes[0].stride);
140 GLES2_Context Mainctx;
141 LoadContext(&Mainctx);
143 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
144 Mainctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.planes[0].stride/4, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned int*)info.planes[0].ptr);
146 if (tbm_surface_unmap (tbmSurface) != TBM_SURFACE_ERROR_NONE)
147 SDL_Log("Failed to unmap tbm_surface\n");
150 if (tbm_surface_destroy (tbmSurface) != TBM_SURFACE_ERROR_NONE)
151 SDL_Log("Failed to destroy tbm_surface\n");
156 _tizen_rs_cb_missing(void *data, struct tizen_remote_surface *trs)
158 SDL_Log("Plug is missing...! ");
161 static const struct tizen_remote_surface_listener _extn_gl_plug_listener =
163 _tizen_rs_cb_buffer_update,
164 _tizen_rs_cb_missing,
167 Uint32 _tizen_timer_callback_indicator(void *data)
169 SDL_VideoDevice *_this = SDL_GetVideoDevice();
171 Tizen_DrawIndicator(_this->windows);
172 SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) _this->windows->driverdata)->egl_surface);
174 return ECORE_CALLBACK_RENEW;
178 _tizen_indicator_event_filter()
180 SDL_Window *window = SDL_GetVideoDevice()->windows;
181 SDL_WindowData *wind = window->driverdata;
183 if(wind->indicator_show && wind->indicator_timer == NULL)
185 wind->indicator_timer = ecore_timer_add(0.02, _tizen_timer_callback_indicator, NULL);
187 else if(!wind->indicator_show && wind->indicator_timer != NULL)
189 ecore_timer_del(wind ->indicator_timer);
190 wind->indicator_timer = NULL;
197 Tizen_GLES_LoadLibrary(_THIS, const char *path)
201 ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)ecore_wl_display_get());
205 static GLuint LoadShader(GLES2_Context* Mainctx, const char *shaderSrc, GLenum type)
210 shader = Mainctx->glCreateShader(type);
211 SDL_Log("shader == %d", shader);
214 Mainctx->glShaderSource(shader, 1, &shaderSrc, NULL);
215 Mainctx->glCompileShader(shader);
216 Mainctx->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
220 Mainctx->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
223 char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
224 Mainctx->glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
225 SDL_Log("Error compiling shader: %s", infoLog );
228 Mainctx->glDeleteShader(shader);
235 extern void ModelMatrixLoadIdentity(ModelMatrix* matrix)
237 matrix->m[0][0] = 1.0f;
238 matrix->m[0][1] = 0.0f;
239 matrix->m[0][2] = 0.0f;
240 matrix->m[0][3] = 0.0f;
242 matrix->m[1][0] = 0.0f;
243 matrix->m[1][1] = 1.0f;
244 matrix->m[1][2] = 0.0f;
245 matrix->m[1][3] = 0.0f;
247 matrix->m[2][0] = 0.0f;
248 matrix->m[2][1] = 0.0f;
249 matrix->m[2][2] = 1.0f;
250 matrix->m[2][3] = 0.0f;
252 matrix->m[3][0] = 0.0f;
253 matrix->m[3][1] = 0.0f;
254 matrix->m[3][2] = 0.0f;
255 matrix->m[3][3] = 1.0f;
258 static void ModelMatrixTranslate(ModelMatrix* matrix, GLfloat x, GLfloat y, GLfloat z)
260 matrix->m[3][0] += (matrix->m[0][0] * x + matrix->m[1][0] * y + matrix->m[2][0] * z);
261 matrix->m[3][1] += (matrix->m[0][1] * x + matrix->m[1][1] * y + matrix->m[2][1] * z);
262 matrix->m[3][2] += (matrix->m[0][2] * x + matrix->m[1][2] * y + matrix->m[2][2] * z);
263 matrix->m[3][3] += (matrix->m[0][3] * x + matrix->m[1][3] * y + matrix->m[2][3] * z);
266 void ModelMatrixTranslateInit(ModelMatrix* matrix)
268 matrix->m[3][0] = matrix->m[3][1] = matrix->m[3][2] =0;
272 void multiply_matrix(ModelMatrix *lhs, ModelMatrix *rhs, ModelMatrix *r)
277 for (i = 0; i < 4; i++) {
278 for (j = 0; j < 4; j++) {
281 for (k = 0; k < 4; k++) {
282 tmp[j][i] += lhs->m[k][i] * rhs->m[j][k];
286 for (i = 0; i < 4; i++) {
287 for (j=0; j<4; j++) {
288 r->m[i][j] = tmp[i][j];
293 void rotate_indicator(ModelMatrix* matrix, const float anglex, const float angley, const float anglez)
295 const float pi = 3.141592f;
296 ModelMatrix* temp = (ModelMatrix*)malloc(sizeof(ModelMatrix));
297 float rz = 2.0f * pi * anglez / 360.0f;
298 float rx = 2.0f * pi * anglex / 360.0f;
299 float ry = 2.0f * pi * angley / 360.0f;
300 float sy = SDL_sinf(ry);
301 float cy = SDL_cosf(ry);
302 float sx = SDL_sinf(rx);
303 float cx = SDL_cosf(rx);
304 float sz = SDL_sinf(rz);
305 float cz = SDL_cosf(rz);
307 ModelMatrixLoadIdentity(temp);
309 temp->m[0][0] = cy * cz - sx * sy * sz;
310 temp->m[0][1] = cz * sx * sy + cy * sz;
311 temp->m[0][2] = -cx * sy;
312 temp->m[1][0] = -cx * sz;
313 temp->m[1][1] = cx * cz;
316 temp->m[2][0] = cz * sy + cy * sx * sz;
317 temp->m[2][1] = -cy * cz * sx + sy * sz;
318 temp->m[2][2] = cx * cy;
320 multiply_matrix(matrix, temp, matrix);
324 void Tizen_remote_indicator(int res_id)
326 if(!shared_info.tizen_rs) {
327 //create tizen_remote_surface
328 shared_info.tizen_rs = tizen_remote_surface_manager_create_surface(shared_info.tizen_rsm, res_id, shared_info.wl_tbm);
329 if(!shared_info.tizen_rs)
331 SDL_Log("tizen_rs is NULL");
334 tizen_remote_surface_add_listener(shared_info.tizen_rs, &_extn_gl_plug_listener, NULL);
335 tizen_remote_surface_redirect(shared_info.tizen_rs);
339 void Tizen_glTexImage2D(int idx)
341 GLES2_Context Mainctx;
342 LoadContext(&Mainctx);
344 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
345 Mainctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shared_info.fileInfo[idx].ImageWidth, shared_info.fileInfo[idx].ImageHeight,
346 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)(shared_info.fileInfo[idx].sharedFile->address));
349 void Tizen_DrawIndicator(SDL_Window *window)
351 SDL_WindowData* wdata = (SDL_WindowData*)window->driverdata;
352 if (wdata->received_rotation == 1) {
353 ecore_wl_window_rotation_change_done_send(wdata->window);
354 wdata->received_rotation = 0;
356 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && wdata->indicator_show)
358 if(wdata->last_indicator_showtime + 3000< SDL_GetTicks())
360 ModelMatrixTranslate(&mMatrix, 0.0f, 0.02f, 0.0f);
362 if(wdata->last_indicator_showtime + 3500 <SDL_GetTicks()) {
363 wdata->indicator_show = SDL_FALSE;
364 _tizen_indicator_event_filter();
366 GLES2_Context Mainctx;
367 LoadContext(&Mainctx);
368 Mainctx.glViewport(0, 0, window->w, window->h);
369 Mainctx.glUseProgram(programObject);
371 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
372 Mainctx.glVertexAttribPointer(vIndex, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
373 Mainctx.glVertexAttribPointer(cIndex, 2, GL_FLOAT, GL_FALSE, 0, vCoord);
374 Mainctx.glUniformMatrix4fv(Mainctx.glGetUniformLocation(programObject, "modelMatrix"), 1, GL_FALSE, mMatrix.m);
376 Mainctx.glEnableVertexAttribArray(vIndex);
377 Mainctx.glEnableVertexAttribArray(cIndex);
379 GLboolean isDepthTest = Mainctx.glIsEnabled(GL_DEPTH_TEST);
380 if(isDepthTest) Mainctx.glDisable(GL_DEPTH_TEST);
381 Mainctx.glDrawArrays(GL_TRIANGLES, 0, 6);
383 if(isDepthTest) Mainctx.glEnable(GL_DEPTH_TEST);
384 Mainctx.glDisableVertexAttribArray(vIndex);
385 Mainctx.glDisableVertexAttribArray(cIndex);
389 SDL_bool Tizen_remote_surface_init(void)
391 Eina_Inlist *globals;
392 Ecore_Wl_Global *global;
393 struct wl_registry *registry;
394 if (!shared_info.tizen_rsm)
396 registry = ecore_wl_registry_get();
397 globals = ecore_wl_globals_get();
399 if (!registry || !globals)
401 SDL_Log( "Could not get registry(%p) or global list(%p)\n", registry, globals);
405 EINA_INLIST_FOREACH(globals, global)
407 if (!strcmp(global->interface, "tizen_remote_surface_manager"))
409 shared_info.tizen_rsm = wl_registry_bind(registry, global->id,
410 &tizen_remote_surface_manager_interface, 1);
411 SDL_Log("[SDL] Create tizen_rsm : %p",shared_info.tizen_rsm);
414 shared_info.tizen_rs = NULL;
416 if (!shared_info.tizen_rsm)
418 SDL_Log("Could not bind tizen_remote_surface_manager");
422 if(!shared_info.tbm_client)
424 shared_info.tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get());
425 shared_info.wl_tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(shared_info.tbm_client);
426 if (!shared_info.wl_tbm)
428 SDL_Log("[SDL]wl_tbm is NULL");
433 eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglCreateImageKHR");
434 eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglDestroyImageKHR");
435 glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("glEGLImageTargetTexture2DOES");
440 int Tizen_FiniIndicator()
443 for (n=0; n < SHARED_FILE_NUMBER; n++)
444 Tizen_Indicator_SharedFile_Free(&shared_info, n);
446 if(shared_info.eglImage_Indicator != NULL)
447 eglDestroyImageKHR(SDL_GetVideoDevice()->egl_data->egl_display, shared_info.eglImage_Indicator);
449 if (shared_info.tizen_rs)
450 tizen_remote_surface_destroy(shared_info.tizen_rs);
451 if (shared_info.tbm_client)
452 wayland_tbm_client_deinit(shared_info.tbm_client);
453 if (shared_info.tizen_rsm)
454 tizen_remote_surface_manager_destroy(shared_info.tizen_rsm);
456 GLES2_Context Mainctx;
457 LoadContext(&Mainctx);
458 Mainctx.glDeleteProgram(programObject);
462 int Indicator_GLES_Init(SDL_Window* window)
464 SDL_WindowData *wind = window->driverdata;
465 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
466 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
467 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
469 Ecore_Ipc_Server* IpcServer = serverConnection("elm_indicator", &shared_info);
472 SDL_Log("Fail to connect elm_indicator!\n");
476 GLchar vShaderStr[] =
477 "attribute vec4 vVertices;\n"
478 "attribute vec2 vCoord;\n"
479 "uniform mat4 modelMatrix;\n"
480 "varying vec2 Coord;\n"
483 " gl_Position = modelMatrix * vVertices;\n"
487 GLchar fShaderStr[] =
488 "precision mediump float;\n"
489 "varying vec2 Coord;\n"
490 "uniform sampler2D s_texture;\n"
493 " gl_FragColor = texture2D(s_texture,Coord);\n"
497 GLuint fragmentShader;
501 GLES2_Context Mainctx;
502 LoadContext(&Mainctx);
504 vertexShader = LoadShader(&Mainctx, vShaderStr, GL_VERTEX_SHADER);
505 fragmentShader = LoadShader(&Mainctx, fShaderStr, GL_FRAGMENT_SHADER);
506 SDL_Log("The vertex shader is %d", vertexShader);
507 SDL_Log("The fragment shader is %d", fragmentShader);
509 programObject = Mainctx.glCreateProgram();
510 if(programObject == 0)
513 Mainctx.glAttachShader(programObject, vertexShader);
514 Mainctx.glAttachShader(programObject, fragmentShader);
516 Mainctx.glLinkProgram(programObject);
517 Mainctx.glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
522 Mainctx.glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
525 char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
526 Mainctx.glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
527 SDL_Log("Error linking program: %s", infoLog);
530 Mainctx.glDeleteProgram(programObject);
534 Mainctx.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
535 Mainctx.glEnable(GL_DEPTH_TEST);
537 vIndex = Mainctx.glGetAttribLocation(programObject, "vVertices");
538 cIndex = Mainctx.glGetAttribLocation(programObject, "vCoord");
540 Mainctx.glBindAttribLocation(programObject, vIndex, "vVertices");
541 Mainctx.glBindAttribLocation(programObject, cIndex, "vCoord");
543 ModelMatrixLoadIdentity(&mMatrix);
546 Mainctx.glGenTextures(1, &textureID);
547 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
549 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
550 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
551 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
552 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
554 wind->indicator_show = SDL_TRUE;
555 wind->last_indicator_showtime = SDL_GetTicks();
557 ecore_main_loop_iterate();
558 SDL_IndicatorProcessEvent(window, wind->rotation);
559 _tizen_indicator_event_filter();
565 Tizen_GLES_CreateContext(_THIS, SDL_Window *window)
567 SDL_GLContext context;
569 context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
571 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS))
573 SDL_VideoData *data = (SDL_VideoData *) (SDL_GetVideoDevice()->driverdata);
574 if(data->current_thread != SDL_GetThreadID(0))
576 if(!Indicator_GLES_Init(window))
578 SDL_Log("Indicator GLES init error!");
586 Tizen_GLES_SwapWindow(_THIS, SDL_Window *window)
588 if(!((SDL_WindowData*)window->driverdata)->indicator_show) {
589 Tizen_DrawIndicator(window);
590 SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
595 Tizen_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
599 if (window && context) {
600 ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
602 ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
609 Tizen_GLES_DeleteContext(_THIS, SDL_GLContext context)
611 SDL_EGL_DeleteContext(_this, context);
615 SDL_IndicatorProcessEvent(SDL_Window *window, int rot)
617 SDL_WindowData *wind = window->driverdata;
618 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && wind->indicator_show)
620 GLES2_Context Mainctx;
621 LoadContext(&Mainctx);
623 double ratio = 0.92f;
624 if( rot == 90 || rot ==270)
627 vVertices[4] = vVertices[7] = vVertices[16] = ratio;
629 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_vbo);
630 Mainctx.glBufferData(GL_ARRAY_BUFFER, 18 * 4, vVertices, GL_STATIC_DRAW);
631 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_ibo);
632 Mainctx.glBufferData(GL_ARRAY_BUFFER, 12 * 4, vCoord, GL_STATIC_DRAW);
634 ModelMatrixLoadIdentity(&mMatrix);
636 if (!wind->support_pre_rotation)
637 rotate_indicator(&mMatrix, 0, 0, rot);
639 wind->indicator_show = SDL_TRUE;
640 wind->last_indicator_showtime = SDL_GetTicks();
642 _tizen_indicator_event_filter();
646 #endif /* SDL_VIDEO_DRIVER_TIZEN && SDL_VIDEO_OPENGL_EGL */
648 /* vi: set ts=4 sw=4 expandtab: */