Merge "fix SDL_Vulkan API" into tizen
[platform/upstream/SDL.git] / src / video / tizen / SDL_tizenopengles.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4   Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
5
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.
9
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:
13
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.
21 */
22 #include "../../SDL_internal.h"
23
24 #if SDL_VIDEO_OPENGL_EGL
25
26 #include "SDL_tizenvideo.h"
27 #include "SDL_tizenopengles.h"
28 #include "SDL_tizenwindow.h"
29 #include "SDL_tizenevents_c.h"
30
31 #include "SDL_ecore_ipc.h"
32
33 #include <Ecore.h>
34
35 #if SDL_VIDEO_OPENGL
36 #include "SDL_opengl.h"
37 #endif /* SDL_VIDEO_OPENGL */
38
39 #if SDL_VIDEO_OPENGL_ES
40 #include "SDL_opengles.h"
41 #endif /* SDL_VIDEO_OPENGL_ES */
42
43 /* GL and GLES2 headers conflict on Linux 32 bits */
44 #if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL
45 #include "SDL_opengles2.h"
46 #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
47
48
49 GLfloat vVertices[18]={
50      1.0f, 1.0f,  0.0f,
51     -1.0f, 0.92f, 0.0f,
52      1.0f, 0.92f, 0.0f,
53      1.0f, 1.0f,  0.0f,
54     -1.0f, 1.0f,  0.0f,
55     -1.0f, 0.92f, 0.0f
56     };
57
58 GLfloat vCoord[12] = {
59     1.0f, 0.0f,
60     0.0f, 1.0f,
61     1.0f, 1.0f,
62     1.0f, 0.0f,
63     0.0f, 0.0f,
64     0.0f, 1.0f};
65
66
67 /* EGL implementation of SDL OpenGL ES support */
68 typedef struct GLES2_Context
69 {
70     #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
71     #include "../../render/opengles2/SDL_gles2funcs.h"
72     #undef SDL_PROC
73 } GLES2_Context;
74
75 GLuint programObject;
76 GLuint vIndex;
77 GLuint cIndex;
78
79 Uint32 _tizen_timer_callback_indicator(void *data)
80 {
81     SDL_VideoDevice *_this = SDL_GetVideoDevice();
82
83     drawIndicator(_this->windows);
84     SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) _this->windows->driverdata)->egl_surface);
85
86     return  ECORE_CALLBACK_RENEW;
87 }
88
89 int
90 _tizen_indicator_event_filter()
91 {
92     SDL_Window *window = SDL_GetVideoDevice()->windows;
93     SDL_WindowData *wind = window->driverdata;
94
95     if(wind->indicator_show && wind->indicator_timer == NULL)
96     {
97         wind->indicator_timer = ecore_timer_add(0.02, _tizen_timer_callback_indicator, NULL);
98     }
99     else if(!wind->indicator_show && wind->indicator_timer != NULL)
100     {
101         ecore_timer_del(wind ->indicator_timer);
102         wind->indicator_timer = NULL;
103     }
104
105     return 1;
106 }
107
108 int
109 Tizen_GLES_LoadLibrary(_THIS, const char *path)
110 {
111     int ret;
112
113     ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)ecore_wl_display_get());
114     return ret;
115 }
116
117 static int LoadContext(GLES2_Context * data)
118 {
119     #define SDL_PROC(ret,func,params) \
120     do { \
121         data->func = SDL_GL_GetProcAddress(#func); \
122         if ( ! data->func ) { \
123             return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \
124         } \
125     } while ( 0 );
126
127     #include "../../render/opengles2/SDL_gles2funcs.h"
128     #undef SDL_PROC
129
130     return 0;
131 }
132
133 static GLuint LoadShader(GLES2_Context* Mainctx, const char *shaderSrc, GLenum type)
134 {
135     GLuint shader;
136     GLint compiled;
137
138     shader = Mainctx->glCreateShader(type);
139     SDL_Log("shader == %d", shader);
140     if(shader == 0)
141         return 0;
142     Mainctx->glShaderSource(shader, 1, &shaderSrc, NULL);
143     Mainctx->glCompileShader(shader);
144     Mainctx->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
145     if(!compiled)
146     {
147         GLint infoLen = 0;
148         Mainctx->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
149         if(infoLen > 1)
150         {
151             char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
152             Mainctx->glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
153             SDL_Log("Error compiling shader: %s", infoLog );
154             free(infoLog);
155         }
156         Mainctx->glDeleteShader(shader);
157         return 0;
158     }
159     return shader;
160
161 }
162
163 SharedIndicatorInfo shared_info;
164 unsigned int textureID;
165 unsigned int indicator_vbo[4], indicator_ibo[4];
166 unsigned short indicator_index;
167 ModelMatrix mMatrix;
168
169 extern void ModelMatrixLoadIdentity(ModelMatrix* matrix)
170 {
171     matrix->m[0][0] = 1.0f;
172     matrix->m[0][1] = 0.0f;
173     matrix->m[0][2] = 0.0f;
174     matrix->m[0][3] = 0.0f;
175
176     matrix->m[1][0] = 0.0f;
177     matrix->m[1][1] = 1.0f;
178     matrix->m[1][2] = 0.0f;
179     matrix->m[1][3] = 0.0f;
180
181     matrix->m[2][0] = 0.0f;
182     matrix->m[2][1] = 0.0f;
183     matrix->m[2][2] = 1.0f;
184     matrix->m[2][3] = 0.0f;
185
186     matrix->m[3][0] = 0.0f;
187     matrix->m[3][1] = 0.0f;
188     matrix->m[3][2] = 0.0f;
189     matrix->m[3][3] = 1.0f;
190 }
191
192 static void ModelMatrixTranslate(ModelMatrix* matrix, GLfloat x, GLfloat y, GLfloat z)
193 {
194     matrix->m[3][0] += (matrix->m[0][0] * x + matrix->m[1][0] * y + matrix->m[2][0] * z);
195     matrix->m[3][1] += (matrix->m[0][1] * x + matrix->m[1][1] * y + matrix->m[2][1] * z);
196     matrix->m[3][2] += (matrix->m[0][2] * x + matrix->m[1][2] * y + matrix->m[2][2] * z);
197     matrix->m[3][3] += (matrix->m[0][3] * x + matrix->m[1][3] * y + matrix->m[2][3] * z);
198 }
199
200 void Tizen_glTexImage2d(int idx)
201 {
202     GLES2_Context Mainctx;
203     LoadContext(&Mainctx);
204
205     Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
206     Mainctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shared_info.fileInfo[idx].ImageWidth, shared_info.fileInfo[idx].ImageHeight,
207                       0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)(shared_info.fileInfo[idx].sharedFile->address));
208 }
209
210 void drawIndicator(SDL_Window *window)
211 {
212     SDL_WindowData* wdata = (SDL_WindowData*)window->driverdata;
213     if (wdata->received_rotation == 1) {
214         ecore_wl_window_rotation_change_done_send(wdata->window);
215         wdata->received_rotation = 0;
216     }
217
218     if(wdata->last_indicator_showtime + 3000< SDL_GetTicks())
219     {
220         switch(wdata->indicator_type)
221         {
222         case 0://0
223             ModelMatrixTranslate(&mMatrix, 0.0f, 0.02f, 0.0f);
224         break;
225         case 1://90
226             ModelMatrixTranslate(&mMatrix, -0.02f, 0.0f, 0.0f);
227         break;
228         case 2://180
229             ModelMatrixTranslate(&mMatrix, 0.0f, -0.02f, 0.0f);
230         break;
231         case 3://270
232             ModelMatrixTranslate(&mMatrix, 0.02f, 0.0f, 0.0f);
233         break;
234         }
235     }
236
237     if(wdata->last_indicator_showtime + 3500 <SDL_GetTicks()) {
238         wdata->indicator_show = SDL_FALSE;
239         _tizen_indicator_event_filter();
240     }
241
242     if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS) && wdata->indicator_show)
243     {
244         GLES2_Context Mainctx;
245         LoadContext(&Mainctx);
246         Mainctx.glUseProgram(programObject);
247
248         Mainctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
249         Mainctx.glVertexAttribPointer(vIndex, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
250         Mainctx.glVertexAttribPointer(cIndex, 2, GL_FLOAT, GL_FALSE, 0, vCoord);
251         Mainctx.glUniformMatrix4fv(Mainctx.glGetUniformLocation(programObject,  "modelMatrix"), 1, GL_FALSE, mMatrix.m);
252
253         Mainctx.glEnableVertexAttribArray(vIndex);
254         Mainctx.glEnableVertexAttribArray(cIndex);
255
256         GLboolean isDepthTest = Mainctx.glIsEnabled(GL_DEPTH_TEST);
257         if(isDepthTest) Mainctx.glDisable(GL_DEPTH_TEST);
258         Mainctx.glDrawArrays(GL_TRIANGLES, 0, 6);
259
260         if(isDepthTest) Mainctx.glEnable(GL_DEPTH_TEST);
261         Mainctx.glDisableVertexAttribArray(vIndex);
262         Mainctx.glDisableVertexAttribArray(cIndex);
263     }
264 }
265
266 static int Indicator_GLES_Init(SDL_Window* window)
267 {
268     SDL_WindowData *wind = window->driverdata;
269     ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
270     ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
271     ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
272
273     Ecore_Ipc_Server* IpcServer = serverConnection("elm_indicator", &shared_info);
274     if(!IpcServer)
275     {
276         SDL_Log("Fail to connect elm_indicator!\n");
277         return 0;
278     }
279
280     GLchar vShaderStr[] =
281         "attribute vec4 vVertices;\n"
282         "attribute vec2 vCoord;\n"
283         "uniform mat4 modelMatrix;\n"
284         "varying vec2 Coord;\n"
285         "void main()\n"
286         "{\n"
287         "    gl_Position = modelMatrix * vVertices;\n"
288         "    Coord = vCoord;\n"
289         "}\n";
290
291     GLchar fShaderStr[] =
292         "precision mediump float;\n"
293         "varying vec2 Coord;\n"
294         "uniform sampler2D s_texture;\n"
295         "void main()\n"
296         "{\n"
297         " gl_FragColor = texture2D(s_texture,Coord);\n"
298         "}\n";
299
300     GLuint vertexShader;
301     GLuint fragmentShader;
302
303     GLint linked;
304
305     GLES2_Context Mainctx;
306     LoadContext(&Mainctx);
307
308     vertexShader = LoadShader(&Mainctx, vShaderStr, GL_VERTEX_SHADER);
309     fragmentShader = LoadShader(&Mainctx, fShaderStr, GL_FRAGMENT_SHADER);
310     SDL_Log("The vertex shader is %d", vertexShader);
311     SDL_Log("The fragment shader is %d", fragmentShader);
312
313     programObject = Mainctx.glCreateProgram();
314     if(programObject == 0)
315         return 0;
316
317     Mainctx.glAttachShader(programObject, vertexShader);
318     Mainctx.glAttachShader(programObject, fragmentShader);
319
320     Mainctx.glLinkProgram(programObject);
321     Mainctx.glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
322
323     if(!linked)
324     {
325         GLint infoLen = 0;
326         Mainctx.glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
327         if(infoLen > 1)
328         {
329             char* infoLog = (char*)(malloc(sizeof(char) * infoLen));
330             Mainctx.glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
331             SDL_Log("Error linking program: %s", infoLog);
332             free(infoLog);
333         }
334         Mainctx.glDeleteProgram(programObject);
335         return 0;
336     }
337
338     Mainctx.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
339     Mainctx.glEnable(GL_DEPTH_TEST);
340
341     vIndex = Mainctx.glGetAttribLocation(programObject, "vVertices");
342     cIndex = Mainctx.glGetAttribLocation(programObject, "vCoord");
343
344     Mainctx.glBindAttribLocation(programObject, vIndex, "vVertices");
345     Mainctx.glBindAttribLocation(programObject, cIndex, "vCoord");
346
347     ModelMatrixLoadIdentity(&mMatrix);
348
349
350     Mainctx.glGenTextures(1, &textureID);
351     Mainctx.glBindTexture(GL_TEXTURE_2D, textureID);
352
353     Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
354     Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
355     Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
356     Mainctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
357
358     wind->indicator_show = SDL_TRUE;
359     wind->last_indicator_showtime = SDL_GetTicks();
360
361     ecore_main_loop_iterate();
362
363     _tizen_indicator_event_filter();
364
365     return 1;
366 }
367
368 SDL_GLContext
369 Tizen_GLES_CreateContext(_THIS, SDL_Window *window)
370 {
371     SDL_GLContext context;
372
373     context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
374
375     if(!(window->flags & SDL_WINDOW_FULLSCREEN) && !(window->flags & SDL_WINDOW_BORDERLESS))
376     {
377         if(!Indicator_GLES_Init(window))
378         {
379             SDL_Log("Indicator GLES init error!");
380         }
381     }
382
383     return context;
384 }
385
386 void
387 Tizen_GLES_SwapWindow(_THIS, SDL_Window *window)
388 {
389     if(!((SDL_WindowData*)window->driverdata)->indicator_show) {
390         drawIndicator(window);
391         SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
392     }
393 }
394
395 int
396 Tizen_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
397 {
398     int ret;
399
400     if (window && context) {
401         ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
402     } else {
403         ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
404     }
405
406     return ret;
407 }
408
409 void
410 Tizen_GLES_DeleteContext(_THIS, SDL_GLContext context)
411 {
412     SDL_EGL_DeleteContext(_this, context);
413 }
414
415 void
416 SDL_IndicatorProcessEvent(SDL_Event * event, SDL_Window *window)
417 {
418     GLES2_Context Mainctx;
419     LoadContext(&Mainctx);
420
421    SDL_WindowData *wind = window->driverdata;
422
423     if(event->type == SDL_ROTATEEVENT)
424     {
425         wind->indicator_type = ((int)event->user.data1) / 90;
426         if( wind->indicator_type == 0)
427         {
428             SDL_Log("===rotate 0 degree!\n");
429             vVertices[0] = 1.0f;
430             vVertices[1] = 1.0f;
431             vVertices[3] = -1.0f;
432             vVertices[4] = 0.92f;
433             vVertices[6] = 1.0f;
434             vVertices[7] = 0.92f;
435             vVertices[9] = 1.0f;
436             vVertices[10] = 1.0f;
437             vVertices[12] =  -1.0f;
438             vVertices[13] =  1.0f;
439             vVertices[15] = -1.0f;
440             vVertices[16] = 0.92f;
441
442             vCoord[0] = 1.0f;
443             vCoord[1] = 0.0f;
444             vCoord[2] = 0.0f;
445             vCoord[3] = 1.0f;
446             vCoord[4] = 1.0f;
447             vCoord[5] = 1.0f;
448             vCoord[6] = 1.0f;
449             vCoord[7] = 0.0f;
450             vCoord[8] = 0.0f;
451             vCoord[9] = 0.0f;
452             vCoord[10] = 0.0f;
453             vCoord[11] = 1.0f;
454
455         }
456         else if(wind->indicator_type == 1)
457         {
458             SDL_Log("===rotate 90 degree!\n");
459             vVertices[0] = -0.86f;
460             vVertices[1] = 1.0f;
461             vVertices[3] = -0.86f;
462             vVertices[4] = -1.0f;
463             vVertices[6] = -1.0f;
464             vVertices[7] = 1.0f;
465             vVertices[9] = -1.0f;
466             vVertices[10] = -1.0f;
467             vVertices[12] =  -0.86f;
468             vVertices[13] = -1.0f;
469             vVertices[15] = -1.0f;
470             vVertices[16] = 1.0f;
471
472             vCoord[0] = 1.0f;
473             vCoord[1] = 1.0f;
474             vCoord[2] = 0.0f;
475             vCoord[3] = 1.0f;
476             vCoord[4] = 1.0f;
477             vCoord[5] = 0.0f;
478             vCoord[6] = 0.0f;
479             vCoord[7] = 0.0f;
480             vCoord[8] = 0.0f;
481             vCoord[9] = 1.0f;
482             vCoord[10] = 1.0f;
483             vCoord[11] = 0.0f;
484         }
485         else if(wind->indicator_type == 2)
486         {
487             SDL_Log("===rotate 180 degree!\n");
488             vVertices[0] = -1.0f;
489             vVertices[1] = -1.0f;
490             vVertices[3] = -1.0f;
491             vVertices[4] = -0.92f;
492             vVertices[6] = 1.0f;
493             vVertices[7] = -1.0f;
494             vVertices[9] = 1.0f;
495             vVertices[10] = -0.92f;
496             vVertices[12] =  -1.0f;
497             vVertices[13] = -0.92f;
498             vVertices[15] = 1.0f;
499             vVertices[16] = -1.0f;
500
501             vCoord[0] = 1.0f;
502             vCoord[1] = 0.0f;
503             vCoord[2] = 1.0f;
504             vCoord[3] = 1.0f;
505             vCoord[4] = 0.0f;
506             vCoord[5] = 0.0f;
507             vCoord[6] = 0.0f;
508             vCoord[7] = 1.0f;
509             vCoord[8] = 1.0f;
510             vCoord[9] = 1.0f;
511             vCoord[10] = 0.0f;
512             vCoord[11] = 0.0f;
513         }
514         else if(wind->indicator_type == 3)
515         {
516             SDL_Log("===rotate 270 degree!\n");
517             vVertices[0] = 1.0f;
518             vVertices[1] = 1.0f;
519             vVertices[3] = 0.86f;
520             vVertices[4] = 1.0f;
521             vVertices[6] = 1.0f;
522             vVertices[7] = -1.0f;
523             vVertices[9] = 0.86f;
524             vVertices[10] = -1.0f;
525             vVertices[12] =  0.86f;
526             vVertices[13] = 1.0f;
527             vVertices[15] = 1.0f;
528             vVertices[16] = -1.0f;
529
530             vCoord[0] = 0.0f;
531             vCoord[1] = 0.0f;
532             vCoord[2] = 0.0f;
533             vCoord[3] = 1.0f;
534             vCoord[4] = 1.0f;
535             vCoord[5] = 0.0f;
536             vCoord[6] = 1.0f;
537             vCoord[7] = 1.0f;
538             vCoord[8] = 0.0f;
539             vCoord[9] = 1.0f;
540             vCoord[10] = 1.0f;
541             vCoord[11] = 0.0f;
542         }
543
544         Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_vbo[wind->indicator_type]);
545         Mainctx.glBufferData(GL_ARRAY_BUFFER, 18 * 4, vVertices, GL_STATIC_DRAW);
546         Mainctx.glBindBuffer(GL_ARRAY_BUFFER, indicator_ibo[wind->indicator_type]);
547         Mainctx.glBufferData(GL_ARRAY_BUFFER, 12 * 4, vCoord, GL_STATIC_DRAW);
548
549         ModelMatrixLoadIdentity(&mMatrix);
550         wind->indicator_show = SDL_TRUE;
551         wind->last_indicator_showtime = SDL_GetTicks();
552
553         _tizen_indicator_event_filter();
554
555     }
556 }
557
558 #endif /* SDL_VIDEO_DRIVER_TIZEN && SDL_VIDEO_OPENGL_EGL */
559
560 /* vi: set ts=4 sw=4 expandtab: */