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.glViewport(0, 0, window->w, window->h);
372 Mainctx.glUseProgram(programObject);
374 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
375 Mainctx.glVertexAttribPointer(vIndex, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
376 Mainctx.glVertexAttribPointer(cIndex, 2, GL_FLOAT, GL_FALSE, 0, vCoord);
377 Mainctx.glUniformMatrix4fv(Mainctx.glGetUniformLocation(programObject, "modelMatrix"), 1, GL_FALSE, mMatrix.m);
379 Mainctx.glEnableVertexAttribArray(vIndex);
380 Mainctx.glEnableVertexAttribArray(cIndex);
382 GLboolean isDepthTest = Mainctx.glIsEnabled(GL_DEPTH_TEST);
383 if(isDepthTest) Mainctx.glDisable(GL_DEPTH_TEST);
384 Mainctx.glDrawArrays(GL_TRIANGLES, 0, 6);
386 if(isDepthTest) Mainctx.glEnable(GL_DEPTH_TEST);
387 Mainctx.glDisableVertexAttribArray(vIndex);
388 Mainctx.glDisableVertexAttribArray(cIndex);
392 SDL_bool Tizen_remote_surface_init(void)
394 Eina_Inlist *globals;
395 Ecore_Wl_Global *global;
396 struct wl_registry *registry;
397 if (!shared_info.tizen_rsm)
399 registry = ecore_wl_registry_get();
400 globals = ecore_wl_globals_get();
402 if (!registry || !globals)
404 SDL_Log( "Could not get registry(%p) or global list(%p)\n", registry, globals);
408 EINA_INLIST_FOREACH(globals, global)
410 if (!strcmp(global->interface, "tizen_remote_surface_manager"))
412 shared_info.tizen_rsm = wl_registry_bind(registry, global->id,
413 &tizen_remote_surface_manager_interface, 1);
414 SDL_Log("[SDL] Create tizen_rsm : %p",shared_info.tizen_rsm);
417 shared_info.tizen_rs = NULL;
419 if (!shared_info.tizen_rsm)
421 SDL_Log("Could not bind tizen_remote_surface_manager");
425 if(!shared_info.tbm_client)
427 shared_info.tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get());
428 shared_info.wl_tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(shared_info.tbm_client);
429 if (!shared_info.wl_tbm)
431 SDL_Log("[SDL]wl_tbm is NULL");
436 eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglCreateImageKHR");
437 eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglDestroyImageKHR");
438 glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("glEGLImageTargetTexture2DOES");
443 int Tizen_FiniIndicator()
446 for (n=0; n < SHARED_FILE_NUMBER; n++)
447 Tizen_Indicator_SharedFile_Free(&shared_info, n);
449 if(shared_info.eglImage_Indicator != NULL)
450 eglDestroyImageKHR(SDL_GetVideoDevice()->egl_data->egl_display, shared_info.eglImage_Indicator);
452 if (shared_info.tizen_rs)
453 tizen_remote_surface_destroy(shared_info.tizen_rs);
454 if (shared_info.tbm_client)
455 wayland_tbm_client_deinit(shared_info.tbm_client);
456 if (shared_info.tizen_rsm)
457 tizen_remote_surface_manager_destroy(shared_info.tizen_rsm);
459 GLES2_Context Mainctx;
460 LoadContext(&Mainctx);
461 Mainctx.glDeleteProgram(programObject);
465 int Indicator_GLES_Init(SDL_Window* window)
467 SDL_WindowData *wind = window->driverdata;
468 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
469 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
470 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
472 Ecore_Ipc_Server* IpcServer = serverConnection("elm_indicator", &shared_info);
475 SDL_Log("Fail to connect elm_indicator!\n");
479 GLchar vShaderStr[] =
480 "attribute vec4 vVertices;\n"
481 "attribute vec2 vCoord;\n"
482 "uniform mat4 modelMatrix;\n"
483 "varying vec2 Coord;\n"
486 " gl_Position = modelMatrix * vVertices;\n"
490 GLchar fShaderStr[] =
491 "precision mediump float;\n"
492 "varying vec2 Coord;\n"
493 "uniform sampler2D s_texture;\n"
496 " gl_FragColor = texture2D(s_texture,Coord);\n"
500 GLuint fragmentShader;
504 GLES2_Context Mainctx;
505 LoadContext(&Mainctx);
507 vertexShader = LoadShader(&Mainctx, vShaderStr, GL_VERTEX_SHADER);
508 fragmentShader = LoadShader(&Mainctx, fShaderStr, GL_FRAGMENT_SHADER);
509 SDL_Log("The vertex shader is %d", vertexShader);
510 SDL_Log("The fragment shader is %d", fragmentShader);
512 programObject = Mainctx.glCreateProgram();
513 if(programObject == 0)
516 Mainctx.glAttachShader(programObject, vertexShader);
517 Mainctx.glAttachShader(programObject, fragmentShader);
519 Mainctx.glLinkProgram(programObject);
520 Mainctx.glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
525 Mainctx.glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
528 char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
529 Mainctx.glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
530 SDL_Log("Error linking program: %s", infoLog);
533 Mainctx.glDeleteProgram(programObject);
537 Mainctx.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
538 Mainctx.glEnable(GL_DEPTH_TEST);
540 vIndex = Mainctx.glGetAttribLocation(programObject, "vVertices");
541 cIndex = Mainctx.glGetAttribLocation(programObject, "vCoord");
543 Mainctx.glBindAttribLocation(programObject, vIndex, "vVertices");
544 Mainctx.glBindAttribLocation(programObject, cIndex, "vCoord");
546 ModelMatrixLoadIdentity(&mMatrix);
549 Mainctx.glGenTextures(1, &textureID);
550 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
552 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
553 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
554 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
555 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
557 wind->indicator_show = SDL_TRUE;
558 wind->last_indicator_showtime = SDL_GetTicks();
560 ecore_main_loop_iterate();
561 SDL_IndicatorProcessEvent(window, wind->rotation);
562 _tizen_indicator_event_filter();
568 Tizen_GLES_CreateContext(_THIS, SDL_Window *window)
570 SDL_GLContext context;
572 context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
574 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS))
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 GLES2_Context Mainctx;
618 LoadContext(&Mainctx);
620 SDL_WindowData *wind = window->driverdata;
622 double ratio = 0.92f;
623 if( rot == 90 || rot ==270)
626 vVertices[4] = vVertices[7] = vVertices[16] = ratio;
628 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_vbo);
629 Mainctx.glBufferData(GL_ARRAY_BUFFER, 18 * 4, vVertices, GL_STATIC_DRAW);
630 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_ibo);
631 Mainctx.glBufferData(GL_ARRAY_BUFFER, 12 * 4, vCoord, GL_STATIC_DRAW);
633 ModelMatrixLoadIdentity(&mMatrix);
635 if (!wind->support_pre_rotation)
636 rotate_indicator(&mMatrix, 0, 0, rot);
638 wind->indicator_show = SDL_TRUE;
639 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: */