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;
357 if(wdata->last_indicator_showtime + 3000< SDL_GetTicks())
359 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();
367 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && wdata->indicator_show)
369 GLES2_Context Mainctx;
370 LoadContext(&Mainctx);
371 Mainctx.glUseProgram(programObject);
373 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
374 Mainctx.glVertexAttribPointer(vIndex, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
375 Mainctx.glVertexAttribPointer(cIndex, 2, GL_FLOAT, GL_FALSE, 0, vCoord);
376 Mainctx.glUniformMatrix4fv(Mainctx.glGetUniformLocation(programObject, "modelMatrix"), 1, GL_FALSE, mMatrix.m);
378 Mainctx.glEnableVertexAttribArray(vIndex);
379 Mainctx.glEnableVertexAttribArray(cIndex);
381 GLboolean isDepthTest = Mainctx.glIsEnabled(GL_DEPTH_TEST);
382 if(isDepthTest) Mainctx.glDisable(GL_DEPTH_TEST);
383 Mainctx.glDrawArrays(GL_TRIANGLES, 0, 6);
385 if(isDepthTest) Mainctx.glEnable(GL_DEPTH_TEST);
386 Mainctx.glDisableVertexAttribArray(vIndex);
387 Mainctx.glDisableVertexAttribArray(cIndex);
391 SDL_bool Tizen_remote_surface_init(void)
393 Eina_Inlist *globals;
394 Ecore_Wl_Global *global;
395 struct wl_registry *registry;
396 if (!shared_info.tizen_rsm)
398 registry = ecore_wl_registry_get();
399 globals = ecore_wl_globals_get();
401 if (!registry || !globals)
403 SDL_Log( "Could not get registry(%p) or global list(%p)\n", registry, globals);
407 EINA_INLIST_FOREACH(globals, global)
409 if (!strcmp(global->interface, "tizen_remote_surface_manager"))
411 shared_info.tizen_rsm = wl_registry_bind(registry, global->id,
412 &tizen_remote_surface_manager_interface, 1);
413 SDL_Log("[SDL] Create tizen_rsm : %p",shared_info.tizen_rsm);
416 shared_info.tizen_rs = NULL;
418 if (!shared_info.tizen_rsm)
420 SDL_Log("Could not bind tizen_remote_surface_manager");
424 if(!shared_info.tbm_client)
426 shared_info.tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get());
427 shared_info.wl_tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(shared_info.tbm_client);
428 if (!shared_info.wl_tbm)
430 SDL_Log("[SDL]wl_tbm is NULL");
435 eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglCreateImageKHR");
436 eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglDestroyImageKHR");
437 glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("glEGLImageTargetTexture2DOES");
442 int Tizen_FiniIndicator()
445 for (n=0; n < SHARED_FILE_NUMBER; n++)
446 Tizen_Indicator_SharedFile_Free(&shared_info, n);
448 if(shared_info.eglImage_Indicator != NULL)
449 eglDestroyImageKHR(SDL_GetVideoDevice()->egl_data->egl_display, shared_info.eglImage_Indicator);
451 if (shared_info.tizen_rs)
452 tizen_remote_surface_destroy(shared_info.tizen_rs);
453 if (shared_info.tbm_client)
454 wayland_tbm_client_deinit(shared_info.tbm_client);
455 if (shared_info.tizen_rsm)
456 tizen_remote_surface_manager_destroy(shared_info.tizen_rsm);
458 GLES2_Context Mainctx;
459 LoadContext(&Mainctx);
460 Mainctx.glDeleteProgram(programObject);
464 int Indicator_GLES_Init(SDL_Window* window)
466 SDL_WindowData *wind = window->driverdata;
467 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
468 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
469 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
471 Ecore_Ipc_Server* IpcServer = serverConnection("elm_indicator", &shared_info);
474 SDL_Log("Fail to connect elm_indicator!\n");
478 GLchar vShaderStr[] =
479 "attribute vec4 vVertices;\n"
480 "attribute vec2 vCoord;\n"
481 "uniform mat4 modelMatrix;\n"
482 "varying vec2 Coord;\n"
485 " gl_Position = modelMatrix * vVertices;\n"
489 GLchar fShaderStr[] =
490 "precision mediump float;\n"
491 "varying vec2 Coord;\n"
492 "uniform sampler2D s_texture;\n"
495 " gl_FragColor = texture2D(s_texture,Coord);\n"
499 GLuint fragmentShader;
503 GLES2_Context Mainctx;
504 LoadContext(&Mainctx);
506 vertexShader = LoadShader(&Mainctx, vShaderStr, GL_VERTEX_SHADER);
507 fragmentShader = LoadShader(&Mainctx, fShaderStr, GL_FRAGMENT_SHADER);
508 SDL_Log("The vertex shader is %d", vertexShader);
509 SDL_Log("The fragment shader is %d", fragmentShader);
511 programObject = Mainctx.glCreateProgram();
512 if(programObject == 0)
515 Mainctx.glAttachShader(programObject, vertexShader);
516 Mainctx.glAttachShader(programObject, fragmentShader);
518 Mainctx.glLinkProgram(programObject);
519 Mainctx.glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
524 Mainctx.glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
527 char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
528 Mainctx.glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
529 SDL_Log("Error linking program: %s", infoLog);
532 Mainctx.glDeleteProgram(programObject);
536 Mainctx.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
537 Mainctx.glEnable(GL_DEPTH_TEST);
539 vIndex = Mainctx.glGetAttribLocation(programObject, "vVertices");
540 cIndex = Mainctx.glGetAttribLocation(programObject, "vCoord");
542 Mainctx.glBindAttribLocation(programObject, vIndex, "vVertices");
543 Mainctx.glBindAttribLocation(programObject, cIndex, "vCoord");
545 ModelMatrixLoadIdentity(&mMatrix);
548 Mainctx.glGenTextures(1, &textureID);
549 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
551 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
552 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
553 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
554 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
556 wind->indicator_show = SDL_TRUE;
557 wind->last_indicator_showtime = SDL_GetTicks();
559 ecore_main_loop_iterate();
560 SDL_IndicatorProcessEvent(window, wind->rotation);
561 _tizen_indicator_event_filter();
567 Tizen_GLES_CreateContext(_THIS, SDL_Window *window)
569 SDL_GLContext context;
571 context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
573 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS))
575 if(!Indicator_GLES_Init(window))
577 SDL_Log("Indicator GLES init error!");
585 Tizen_GLES_SwapWindow(_THIS, SDL_Window *window)
587 if(!((SDL_WindowData*)window->driverdata)->indicator_show) {
588 Tizen_DrawIndicator(window);
589 SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
594 Tizen_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
598 if (window && context) {
599 ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
601 ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
608 Tizen_GLES_DeleteContext(_THIS, SDL_GLContext context)
610 SDL_EGL_DeleteContext(_this, context);
614 SDL_IndicatorProcessEvent(SDL_Window *window, int rot)
616 GLES2_Context Mainctx;
617 LoadContext(&Mainctx);
619 SDL_WindowData *wind = window->driverdata;
621 double ratio = 0.92f;
622 if( rot == 90 || rot ==270)
625 vVertices[4] = vVertices[7] = vVertices[16] = ratio;
627 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_vbo);
628 Mainctx.glBufferData(GL_ARRAY_BUFFER, 18 * 4, vVertices, GL_STATIC_DRAW);
629 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_ibo);
630 Mainctx.glBufferData(GL_ARRAY_BUFFER, 12 * 4, vCoord, GL_STATIC_DRAW);
632 ModelMatrixLoadIdentity(&mMatrix);
634 if (!wind->support_pre_rotation)
635 rotate_indicator(&mMatrix, 0, 0, rot);
637 wind->indicator_show = SDL_TRUE;
638 wind->last_indicator_showtime = SDL_GetTicks();
641 _tizen_indicator_event_filter();
645 #endif /* SDL_VIDEO_DRIVER_TIZEN && SDL_VIDEO_OPENGL_EGL */
647 /* vi: set ts=4 sw=4 expandtab: */