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