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 Tizen_remote_indicator(int res_id)
268 if(!shared_info.tizen_rs) {
269 //create tizen_remote_surface
270 shared_info.tizen_rs = tizen_remote_surface_manager_create_surface(shared_info.tizen_rsm, res_id, shared_info.wl_tbm);
271 if(!shared_info.tizen_rs)
273 SDL_Log("tizen_rs is NULL");
276 tizen_remote_surface_add_listener(shared_info.tizen_rs, &_extn_gl_plug_listener, NULL);
277 tizen_remote_surface_redirect(shared_info.tizen_rs);
281 void Tizen_glTexImage2D(int idx)
283 GLES2_Context Mainctx;
284 LoadContext(&Mainctx);
286 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
287 Mainctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shared_info.fileInfo[idx].ImageWidth, shared_info.fileInfo[idx].ImageHeight,
288 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)(shared_info.fileInfo[idx].sharedFile->address));
291 void Tizen_DrawIndicator(SDL_Window *window)
293 SDL_WindowData* wdata = (SDL_WindowData*)window->driverdata;
294 if (wdata->received_rotation == 1) {
295 ecore_wl_window_rotation_change_done_send(wdata->window);
296 wdata->received_rotation = 0;
299 if(wdata->last_indicator_showtime + 3000< SDL_GetTicks())
301 switch(wdata->rotation)
304 ModelMatrixTranslate(&mMatrix, 0.0f, 0.02f, 0.0f);
307 ModelMatrixTranslate(&mMatrix, -0.02f, 0.0f, 0.0f);
310 ModelMatrixTranslate(&mMatrix, 0.0f, -0.02f, 0.0f);
313 ModelMatrixTranslate(&mMatrix, 0.02f, 0.0f, 0.0f);
318 if(wdata->last_indicator_showtime + 3500 <SDL_GetTicks()) {
319 wdata->indicator_show = SDL_FALSE;
320 _tizen_indicator_event_filter();
323 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && wdata->indicator_show)
325 GLES2_Context Mainctx;
326 LoadContext(&Mainctx);
327 Mainctx.glUseProgram(programObject);
329 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
330 Mainctx.glVertexAttribPointer(vIndex, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
331 Mainctx.glVertexAttribPointer(cIndex, 2, GL_FLOAT, GL_FALSE, 0, vCoord);
332 Mainctx.glUniformMatrix4fv(Mainctx.glGetUniformLocation(programObject, "modelMatrix"), 1, GL_FALSE, mMatrix.m);
334 Mainctx.glEnableVertexAttribArray(vIndex);
335 Mainctx.glEnableVertexAttribArray(cIndex);
337 GLboolean isDepthTest = Mainctx.glIsEnabled(GL_DEPTH_TEST);
338 if(isDepthTest) Mainctx.glDisable(GL_DEPTH_TEST);
339 Mainctx.glDrawArrays(GL_TRIANGLES, 0, 6);
341 if(isDepthTest) Mainctx.glEnable(GL_DEPTH_TEST);
342 Mainctx.glDisableVertexAttribArray(vIndex);
343 Mainctx.glDisableVertexAttribArray(cIndex);
347 SDL_bool Tizen_remote_surface_init(void)
349 Eina_Inlist *globals;
350 Ecore_Wl_Global *global;
351 struct wl_registry *registry;
352 if (!shared_info.tizen_rsm)
354 registry = ecore_wl_registry_get();
355 globals = ecore_wl_globals_get();
357 if (!registry || !globals)
359 SDL_Log( "Could not get registry(%p) or global list(%p)\n", registry, globals);
363 EINA_INLIST_FOREACH(globals, global)
365 if (!strcmp(global->interface, "tizen_remote_surface_manager"))
367 shared_info.tizen_rsm = wl_registry_bind(registry, global->id,
368 &tizen_remote_surface_manager_interface, 1);
369 SDL_Log("[SDL] Create tizen_rsm : %p",shared_info.tizen_rsm);
372 shared_info.tizen_rs = NULL;
374 if (!shared_info.tizen_rsm)
376 SDL_Log("Could not bind tizen_remote_surface_manager");
380 if(!shared_info.tbm_client)
382 shared_info.tbm_client = (struct wayland_tbm_client *)wayland_tbm_client_init(ecore_wl_display_get());
383 shared_info.wl_tbm = (struct wl_tbm *)wayland_tbm_client_get_wl_tbm(shared_info.tbm_client);
384 if (!shared_info.wl_tbm)
386 SDL_Log("[SDL]wl_tbm is NULL");
391 eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglCreateImageKHR");
392 eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("eglDestroyImageKHR");
393 glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)SDL_GetVideoDevice()->egl_data->eglGetProcAddress("glEGLImageTargetTexture2DOES");
398 int Tizen_FiniIndicator()
401 for (n=0; n < SHARED_FILE_NUMBER; n++)
402 Tizen_Indicator_SharedFile_Free(&shared_info, n);
404 if(shared_info.eglImage_Indicator != NULL)
405 eglDestroyImageKHR(SDL_GetVideoDevice()->egl_data->egl_display, shared_info.eglImage_Indicator);
407 if (shared_info.tizen_rs)
408 tizen_remote_surface_destroy(shared_info.tizen_rs);
409 if (shared_info.tbm_client)
410 wayland_tbm_client_deinit(shared_info.tbm_client);
411 if (shared_info.tizen_rsm)
412 tizen_remote_surface_manager_destroy(shared_info.tizen_rsm);
414 GLES2_Context Mainctx;
415 LoadContext(&Mainctx);
416 Mainctx.glDeleteProgram(programObject);
420 int Indicator_GLES_Init(SDL_Window* window)
422 SDL_WindowData *wind = window->driverdata;
423 ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
424 ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
425 ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
427 Ecore_Ipc_Server* IpcServer = serverConnection("elm_indicator", &shared_info);
430 SDL_Log("Fail to connect elm_indicator!\n");
434 GLchar vShaderStr[] =
435 "attribute vec4 vVertices;\n"
436 "attribute vec2 vCoord;\n"
437 "uniform mat4 modelMatrix;\n"
438 "varying vec2 Coord;\n"
441 " gl_Position = modelMatrix * vVertices;\n"
445 GLchar fShaderStr[] =
446 "precision mediump float;\n"
447 "varying vec2 Coord;\n"
448 "uniform sampler2D s_texture;\n"
451 " gl_FragColor = texture2D(s_texture,Coord);\n"
455 GLuint fragmentShader;
459 GLES2_Context Mainctx;
460 LoadContext(&Mainctx);
462 vertexShader = LoadShader(&Mainctx, vShaderStr, GL_VERTEX_SHADER);
463 fragmentShader = LoadShader(&Mainctx, fShaderStr, GL_FRAGMENT_SHADER);
464 SDL_Log("The vertex shader is %d", vertexShader);
465 SDL_Log("The fragment shader is %d", fragmentShader);
467 programObject = Mainctx.glCreateProgram();
468 if(programObject == 0)
471 Mainctx.glAttachShader(programObject, vertexShader);
472 Mainctx.glAttachShader(programObject, fragmentShader);
474 Mainctx.glLinkProgram(programObject);
475 Mainctx.glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
480 Mainctx.glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
483 char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
484 Mainctx.glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
485 SDL_Log("Error linking program: %s", infoLog);
488 Mainctx.glDeleteProgram(programObject);
492 Mainctx.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
493 Mainctx.glEnable(GL_DEPTH_TEST);
495 vIndex = Mainctx.glGetAttribLocation(programObject, "vVertices");
496 cIndex = Mainctx.glGetAttribLocation(programObject, "vCoord");
498 Mainctx.glBindAttribLocation(programObject, vIndex, "vVertices");
499 Mainctx.glBindAttribLocation(programObject, cIndex, "vCoord");
501 ModelMatrixLoadIdentity(&mMatrix);
504 Mainctx.glGenTextures(1, &textureID);
505 Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
507 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
508 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
509 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
510 Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
512 wind->indicator_show = SDL_TRUE;
513 wind->last_indicator_showtime = SDL_GetTicks();
515 ecore_main_loop_iterate();
516 if (!wind->support_pre_rotation)
517 SDL_IndicatorProcessEvent(window, wind->rotation);
519 SDL_IndicatorProcessEvent(window, 0);
521 _tizen_indicator_event_filter();
527 Tizen_GLES_CreateContext(_THIS, SDL_Window *window)
529 SDL_GLContext context;
531 context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
533 if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS))
535 if(!Indicator_GLES_Init(window))
537 SDL_Log("Indicator GLES init error!");
545 Tizen_GLES_SwapWindow(_THIS, SDL_Window *window)
547 if(!((SDL_WindowData*)window->driverdata)->indicator_show) {
548 Tizen_DrawIndicator(window);
549 SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
554 Tizen_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
558 if (window && context) {
559 ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
561 ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
568 Tizen_GLES_DeleteContext(_THIS, SDL_GLContext context)
570 SDL_EGL_DeleteContext(_this, context);
574 SDL_IndicatorProcessEvent(SDL_Window *window, int rot)
576 GLES2_Context Mainctx;
577 LoadContext(&Mainctx);
579 SDL_WindowData *wind = window->driverdata;
582 SDL_Log("===rotate 0 degree!\n");
585 vVertices[3] = -1.0f;
586 vVertices[4] = 0.92f;
588 vVertices[7] = 0.92f;
590 vVertices[10] = 1.0f;
591 vVertices[12] = -1.0f;
592 vVertices[13] = 1.0f;
593 vVertices[15] = -1.0f;
594 vVertices[16] = 0.92f;
611 SDL_Log("===rotate 90 degree!\n");
612 vVertices[0] = -0.86f;
614 vVertices[3] = -0.86f;
615 vVertices[4] = -1.0f;
616 vVertices[6] = -1.0f;
618 vVertices[9] = -1.0f;
619 vVertices[10] = -1.0f;
620 vVertices[12] = -0.86f;
621 vVertices[13] = -1.0f;
622 vVertices[15] = -1.0f;
623 vVertices[16] = 1.0f;
640 SDL_Log("===rotate 180 degree!\n");
641 vVertices[0] = -1.0f;
642 vVertices[1] = -1.0f;
643 vVertices[3] = -1.0f;
644 vVertices[4] = -0.92f;
646 vVertices[7] = -1.0f;
648 vVertices[10] = -0.92f;
649 vVertices[12] = -1.0f;
650 vVertices[13] = -0.92f;
651 vVertices[15] = 1.0f;
652 vVertices[16] = -1.0f;
669 SDL_Log("===rotate 270 degree!\n");
672 vVertices[3] = 0.86f;
675 vVertices[7] = -1.0f;
676 vVertices[9] = 0.86f;
677 vVertices[10] = -1.0f;
678 vVertices[12] = 0.86f;
679 vVertices[13] = 1.0f;
680 vVertices[15] = 1.0f;
681 vVertices[16] = -1.0f;
696 //Invisible Indicator
697 wind->indicator_show = SDL_FALSE;
698 _tizen_indicator_event_filter();
701 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_vbo[wind->rotation/90]);
702 Mainctx.glBufferData(GL_ARRAY_BUFFER, 18 * 4, vVertices, GL_STATIC_DRAW);
703 Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_ibo[wind->rotation/90]);
704 Mainctx.glBufferData(GL_ARRAY_BUFFER, 12 * 4, vCoord, GL_STATIC_DRAW);
706 ModelMatrixLoadIdentity(&mMatrix);
707 wind->indicator_show = SDL_TRUE;
708 wind->last_indicator_showtime = SDL_GetTicks();
710 _tizen_indicator_event_filter();
714 #endif /* SDL_VIDEO_DRIVER_TIZEN && SDL_VIDEO_OPENGL_EGL */
716 /* vi: set ts=4 sw=4 expandtab: */