Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / opengl / FGrpEgl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /*
19  * @file        FGrpEgl.cpp
20  * @brief       This is the implementation file for egl.
21  *
22  */
23
24 #include <X11/Xlib.h>
25 #include <X11/Xmd.h>
26 #include <EGL/egl.h>
27
28 #if defined(_OSP_EMUL_)
29 #define FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER
30 #else
31 #define FGRAPHICS_INTERNAL_USE_DRM
32 #endif
33
34 #define FGRAPHICS_INTERNAL_USE_DYNAMIC_LOADING
35 #if defined(FGRAPHICS_INTERNAL_USE_DYNAMIC_LOADING)
36 #include <dlfcn.h>
37 #endif
38
39 #include <Ecore_Evas.h>
40 #include <Ecore_X.h>
41 #include <Evas_Engine_GL_X11.h>
42
43 #include <FBaseSysLog.h>
44 #include <FGrpBitmap.h>
45 #include <FUiControl.h>
46 #include <FUiCtrlForm.h>
47 #include <FUiCtrlFrame.h>
48 #include <FUiWindow.h>
49
50 #include <FUi_EcoreEvasMgr.h>
51 #include <FUi_EcoreEvas.h>
52
53 #include <FGrp_BitmapTool.h>
54 #include <FGrp_BitmapImpl.h>
55 #include <FUi_ControlImpl.h>
56 #include <FUi_Control.h>
57 #include <FUi_WindowImpl.h>
58 #include <FUiAnim_VisualElementSurfaceImpl.h>
59 #include <FUiAnim_VisualElementImpl.h>
60
61
62 #ifdef __cplusplus
63 extern "C"
64 {
65 #endif
66
67 #include <elm_config.h>
68
69 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
70 #include <fcntl.h>
71 #include <unistd.h>
72 #include <dri2.h>
73 #include <libdrm/drm_slp_bufmgr.h>
74 #endif
75
76 typedef int _SglIndex;
77
78 EGLSurface
79 _SglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* pAttribList);
80 EGLSurface _SglGetCurrentSurface(EGLint readDraw);
81 EGLNativePixmapType _CreateNativePixmap(_SglIndex sglIndex, Tizen::Graphics::Bitmap* pixmap);
82 EGLNativePixmapType _CreateNativePixmapEx(Tizen::Graphics::Bitmap* pBitmap, Tizen::Graphics::BufferInfo bufferInfo);
83
84 #if defined(FGRAPHICS_INTERNAL_USE_DYNAMIC_LOADING)
85 void _GlesInterfaceTerminate_1();
86 void _GlesInterfaceTerminate_2();
87 #endif
88
89 using namespace Tizen::Ui::Controls;
90
91 #define FGRAPHICS_INTERNAL_USE_FBO
92 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
93
94 #include <GLES2/gl2.h>
95 bool _GlesFboInitialize_1(int& fboWidth, int& fboHeight, GLuint& frameBufferObject, GLuint& depthRenderBuffer, GLuint& stencilRenderBuffer
96                 , GLuint colorSize, GLuint depthSize, GLuint stencilSize, GLuint& textureId);
97 bool _GlesFboBinding_1(const GLuint frameBufferObject);
98 void _GlesFboSwapBuffers_1(const Frame* pFrame, int fboWidth, int fboHeight, const GLuint frameBufferObject, const GLuint textureId);
99 void _GlesFboTerminate_1(GLuint& frameBufferObject, GLuint& depthRenderBuffer, GLuint& stencilRenderBuffer, GLuint& textureId);
100
101 bool _GlesFboInitialize_2(const int fboWidth, const int fboHeight, GLuint& frameBufferObject, GLuint& depthRenderBuffer, GLuint& stencilRenderBuffer
102                 , GLuint colorSize, GLuint depthSize, GLuint stencilSize, GLuint& textureId, GLuint &program);
103 bool _GlesFboBinding_2(const GLuint frameBufferObject);
104 void _GlesFboSwapBuffers_2(const Frame* pFrame, const GLuint frameBufferObject, const GLuint textureId, const GLuint program);
105 void _GlesFboTerminate_2(GLuint& frameBufferObject, GLuint& depthRenderBuffer, GLuint& stencilRenderBuffer
106                 , GLuint& textureId, GLuint& program);
107 #endif
108
109 #ifdef __cplusplus
110 }
111 #endif
112
113 using namespace Tizen::Ui::Animations;
114 using namespace Tizen::Ui;
115 using namespace Tizen::Base;
116
117 namespace Tizen { namespace Graphics
118 {
119
120 namespace Opengl
121 {
122
123 namespace // unnamed
124 {
125
126 #define FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT
127 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
128 void _PostRenderCallback(Ecore_Evas* ee);
129 void _SaveCurrentContext(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
130 void _UnregisterRenderCallback(Evas_Object* pObject);
131 #endif
132
133 #if !defined(_OSP_EMUL_)
134 #define FGRAPHICS_INTERNAL_USE_EVAS_NATIVE_SURFACE
135 #endif
136 bool isEvasNativeSetEnabled = false;
137
138 void _OnBoundsChanged(void* pData);
139
140 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
141 void _OnBoundsChangedFbo(void* pData);
142 EGLContext _fboContext = EGL_NO_CONTEXT;
143 #endif
144
145 const int INVALID_SGL_INDEX = 0;
146 const int MAX_SGL_INDEX = 100;
147
148 class _SglInfo
149 {
150 public:
151         _SglInfo(void)
152         : sglIndex(INVALID_SGL_INDEX)
153         , display(EGL_NO_DISPLAY)
154         , surface(EGL_NO_SURFACE)
155         , context(EGL_NO_CONTEXT)
156         , config((EGLConfig)0)
157         , pBitmap(null)
158         , pObject(null)
159         , nativePixmap((EGLNativePixmapType)0)
160         , pVisualElementImpl(null)
161         , pControl(null)
162 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
163         , pEcoreImage(null)
164         , width(0)
165         , height(0)
166 #endif
167 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
168         , frameBufferObject(0)
169         , depthRenderBuffer(0)
170         , stencilRenderBuffer(0)
171         , colorSize(0)
172         , depthSize(0)
173         , stencilSize(0)
174         , isStencilEnabled(false)
175         , textureId(0)
176         , program(0)
177         , pFrame(null)
178         , glVersion(0)
179         , isFboAvailable(true)
180         , fboWidth(0)
181         , fboHeight(0)
182 #endif
183         {
184         }
185
186         virtual ~_SglInfo(void)
187         {
188 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
189                 if (this->pEcoreImage != null)
190                 {
191                         ecore_x_image_free(this->pEcoreImage);
192                 }
193 #endif
194                 if (pBitmap != null && pObject != null)
195                 {
196                         int objectWidth = 0;
197                         int objectHeight = 0;
198                         int objectBitsPerPixel = 0;
199                         Evas_Colorspace colorSpace = EVAS_COLORSPACE_ARGB8888;
200
201 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
202                         if (isEvasNativeSetEnabled)
203                         {
204                                 _UnregisterRenderCallback(pObject);
205                         }
206 #endif
207                         evas_object_image_size_get(pObject, &objectWidth, &objectHeight);
208                         colorSpace = evas_object_image_colorspace_get(pObject);
209                         if (colorSpace == EVAS_COLORSPACE_ARGB8888)
210                         {
211                                 objectBitsPerPixel = 32;
212                         }
213                         else if (colorSpace == EVAS_COLORSPACE_RGB565_A5P)
214                         {
215                                 objectBitsPerPixel = 24;
216                         }
217                         else if (colorSpace == EVAS_COLORSPACE_GRY8)
218                         {
219                                 objectBitsPerPixel = 8;
220                         }
221                         else
222                         {
223                                 SysLog(NID_GRP, "Incompatible color space for Evas Object.");
224                                 objectBitsPerPixel = 0;
225                         }
226
227                         int size = objectWidth * objectHeight * objectBitsPerPixel;
228
229                         if (size > 0)
230                         {
231                                 void* pPtr = new (std::nothrow) int[size];
232                                 if (pPtr == null)
233                                 {
234                                         SysLog(NID_GRP, "Fail to allocate memory for Evas Object.");
235                                 }
236
237                                 evas_object_image_data_set(pObject, pPtr);
238                         }
239                         else
240                         {
241                                 evas_object_image_data_set(pObject, NULL);
242                                 SysLog(NID_GRP, "Incompatible size for Evas object. w:%d h:%d bps:%d", objectWidth, objectHeight, objectBitsPerPixel);
243                         }
244
245                         delete pBitmap;
246                 }
247         }
248
249 public:
250         _SglIndex sglIndex;
251         EGLDisplay display;
252         EGLSurface surface;
253         EGLContext context;
254         EGLConfig config;
255         Bitmap* pBitmap;
256         Evas_Object* pObject;
257         EGLNativePixmapType nativePixmap;
258         _VisualElementImpl* pVisualElementImpl;
259         Control* pControl;
260 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
261         Ecore_X_Image* pEcoreImage;
262         int width;
263         int height;
264 #endif
265 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
266         GLuint frameBufferObject;
267         GLuint depthRenderBuffer;
268         GLuint stencilRenderBuffer;
269         EGLint colorSize;
270         EGLint depthSize;
271         EGLint stencilSize;
272         bool isStencilEnabled;
273         GLuint textureId;
274         GLuint program;
275         Frame* pFrame;
276         int glVersion;
277         bool isFboAvailable;
278         int fboWidth;
279         int fboHeight;
280 #endif
281
282 private:
283         _SglInfo(const _SglInfo& sglInfo);
284         _SglInfo& operator =(const _SglInfo& rhs);
285 };
286
287 class _PixmapInfo
288 {
289 public:
290         _PixmapInfo(void)
291         : nativePixmap((Pixmap)0)
292 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
293         , pDrmBufMgr(null)
294         , pDrmBufferObject(null)
295 #endif
296         {
297         }
298
299         virtual ~_PixmapInfo(void)
300         {
301                 Display* pDisplay = (Display*)ecore_x_display_get();
302 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
303                 drm_slp_bo_unmap(this->pDrmBufferObject, DRM_SLP_DEVICE_CPU);
304                 drm_slp_bo_unref(this->pDrmBufferObject);
305                 if (this->pDrmBufMgr)
306                 {
307                         close(this->pDrmBufMgr->drm_fd);
308                 }
309                 drm_slp_bufmgr_destroy(this->pDrmBufMgr);
310                 DRI2DestroyDrawable(pDisplay, this->nativePixmap);
311 #endif
312                 XFreePixmap(pDisplay, this->nativePixmap);
313         }
314
315 public:
316         Pixmap nativePixmap;
317 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
318         drm_slp_bufmgr pDrmBufMgr;
319         drm_slp_bo pDrmBufferObject;
320 #endif
321 };
322
323 void _EvasObjectImageChange(_SglInfo* pSglInfo);
324
325 void
326 _OnBoundsChanged(void* pData)
327 {
328         _SglInfo* pSglInfo = (_SglInfo*)pData;
329         _SglIndex readSurface = 0;
330         _SglIndex drawSurface = 0;
331         bool needMakeCurrent = false;
332         EGLBoolean ret = EGL_FALSE;
333         int width = 0;
334         int height = 0;
335         VisualElementSurface* pVisualElementSurface = null;
336         _VisualElementSurfaceImpl* pVisualElementSurfaceImpl = null;
337
338         result r = E_SUCCESS;
339         Tizen::Graphics::FloatRectangle rect;
340
341         if (pSglInfo == null || pSglInfo->sglIndex <= INVALID_SGL_INDEX)
342         {
343                 goto CATCH_01;
344         }
345
346         readSurface = (_SglIndex)_SglGetCurrentSurface(EGL_READ);
347         drawSurface = (_SglIndex)_SglGetCurrentSurface(EGL_DRAW);
348         if (readSurface == pSglInfo->sglIndex || drawSurface == pSglInfo->sglIndex)
349         {
350                 needMakeCurrent = true;
351         }
352
353         ret = eglMakeCurrent(pSglInfo->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
354         if (ret == EGL_FALSE)
355         {
356                 goto CATCH_01;
357         }
358
359         ret = eglDestroySurface(pSglInfo->display, pSglInfo->surface);
360         if (ret == EGL_FALSE)
361         {
362                 goto CATCH_02;
363         }
364
365         if (pSglInfo->pVisualElementImpl == null)
366         {
367                 goto CATCH_02;
368         }
369
370         rect = pSglInfo->pVisualElementImpl->GetBounds();
371         width = int(rect.width);
372         height = int(rect.height);
373         if (width <= 0 || height <=0)
374         {
375                 goto CATCH_02;
376         }
377
378         if (isEvasNativeSetEnabled)
379         {
380                 if (pSglInfo->pControl == null)
381                 {
382                         goto CATCH_02;
383                 }
384
385                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(*pSglInfo->pControl);
386                 if (pControlImpl == null)
387                 {
388                         goto CATCH_02;
389                 }
390
391                 VisualElement* pVE = pControlImpl->GetCore().GetVisualElement();
392                 if (pVE == null)
393                 {
394                         goto CATCH_02;
395                 }
396
397                 Control* pFrame = pSglInfo->pControl;
398                 Control* pTemp = pFrame->GetParent();
399                 while(pTemp != null)
400                 {
401                         pFrame = pTemp;
402                         pTemp = pTemp->GetParent();
403                 }
404
405                 Dimension size(width, height);
406                 Tizen::Ui::Window* pWindow = dynamic_cast<Tizen::Ui::Window*> (pFrame);
407                 if (pWindow == null)
408                 {
409                         goto CATCH_02;
410                 }
411
412                 pVisualElementSurface = new (std::nothrow) VisualElementSurface();
413                 if (pVisualElementSurface == null)
414                 {
415                         goto CATCH_02;
416                 }
417
418                 r = pVisualElementSurface->Construct(*pWindow->GetDisplayContext(), size);
419                 pVE->SetSurface(pVisualElementSurface);
420         }
421         else
422         {
423                 pVisualElementSurface = pSglInfo->pVisualElementImpl->GetSurfaceN();
424                 if (pVisualElementSurface == null)
425                 {
426                         goto CATCH_02;
427                 }
428         }
429
430         if (pSglInfo->pBitmap != null)
431         {
432                 delete pSglInfo->pBitmap;
433                 pSglInfo->pBitmap = null;
434         }
435
436         pSglInfo->pBitmap = new (std::nothrow) Tizen::Graphics::Bitmap;
437         if (pSglInfo->pBitmap == null)
438         {
439                 goto CATCH_03;
440         }
441
442         r = pSglInfo->pBitmap->Construct(Tizen::Graphics::Rectangle(0, 0, width, height));
443         if (r != E_SUCCESS)
444         {
445                 goto CATCH_04;
446         }
447
448         pSglInfo->nativePixmap = _CreateNativePixmap(pSglInfo->sglIndex, pSglInfo->pBitmap);
449         if (pSglInfo->nativePixmap == 0)
450         {
451                 goto CATCH_04;
452         }
453
454         pSglInfo->surface = eglCreatePixmapSurface(pSglInfo->display, pSglInfo->config, pSglInfo->nativePixmap, null);
455         if (pSglInfo->surface == EGL_NO_SURFACE)
456         {
457                 goto CATCH_04;
458         }
459
460         if (needMakeCurrent)
461         {
462                 eglMakeCurrent(pSglInfo->display, pSglInfo->surface, pSglInfo->surface, pSglInfo->context);
463                 eglWaitGL();
464 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
465                 _SaveCurrentContext(pSglInfo->display, pSglInfo->surface, pSglInfo->surface, pSglInfo->context);
466 #endif
467         }
468
469         pVisualElementSurfaceImpl = _VisualElementSurfaceImpl::GetInstance(*pVisualElementSurface);
470         if (pVisualElementSurfaceImpl == null)
471         {
472                 goto CATCH_04;
473         }
474
475         pSglInfo->pObject = (Evas_Object*)pVisualElementSurfaceImpl->GetNativeHandle();
476         if (pSglInfo->pObject == null)
477         {
478                 goto CATCH_04;
479         }
480
481         _EvasObjectImageChange(pSglInfo);
482
483         return;
484
485 CATCH_04:
486         delete pSglInfo->pBitmap;
487         pSglInfo->pBitmap = null;
488         //fall through
489
490 CATCH_03:
491         delete pVisualElementSurface;
492         //fall through
493
494 CATCH_02:
495         if (needMakeCurrent)
496         {
497                 eglMakeCurrent(pSglInfo->display, pSglInfo->surface, pSglInfo->surface, pSglInfo->context);
498                 eglWaitGL();
499 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
500                 _SaveCurrentContext(pSglInfo->display, pSglInfo->surface, pSglInfo->surface, pSglInfo->context);
501 #endif
502         }
503         //fall through
504
505 CATCH_01:
506         SysLog(NID_GRP, "_OnBoundsChanged failed!! pSglInfo:%#x", (unsigned int)pSglInfo);
507 }
508
509 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
510 void
511 _OnBoundsChangedFbo(void* pData)
512 {
513         _SglInfo* pSglInfo = (_SglInfo*)pData;
514
515         if (pSglInfo == null || pSglInfo->pVisualElementImpl == null)
516         {
517                 SysLog(NID_GRP, "FBO Invalid data");
518                 return;
519         }
520
521         FloatRectangle rect = pSglInfo->pVisualElementImpl->GetBounds();
522         pSglInfo->fboWidth = int(rect.width);
523         pSglInfo->fboHeight = int(rect.height);
524
525         if (pSglInfo->glVersion == 1)
526         {
527                 eglMakeCurrent(pSglInfo->display
528                                 , pSglInfo->surface
529                                 , pSglInfo->surface
530                                 , pSglInfo->context);
531
532                 _GlesFboTerminate_1(pSglInfo->frameBufferObject
533                                 , pSglInfo->depthRenderBuffer
534                                 , pSglInfo->stencilRenderBuffer
535                                 , pSglInfo->textureId
536                                 );
537
538                 _GlesFboInitialize_1(pSglInfo->fboWidth
539                                 , pSglInfo->fboHeight
540                                 , pSglInfo->frameBufferObject
541                                 , pSglInfo->depthRenderBuffer
542                                 , pSglInfo->stencilRenderBuffer
543                                 , pSglInfo->colorSize
544                                 , pSglInfo->depthSize
545                                 , pSglInfo->stencilSize
546                                 , pSglInfo->textureId
547                                 );
548         }
549         else if (pSglInfo->glVersion == 2)
550         {
551                 eglMakeCurrent(pSglInfo->display
552                                 , pSglInfo->surface
553                                 , pSglInfo->surface
554                                 , pSglInfo->context);
555
556                 _GlesFboTerminate_2(pSglInfo->frameBufferObject
557                                 , pSglInfo->depthRenderBuffer
558                                 , pSglInfo->stencilRenderBuffer
559                                 , pSglInfo->textureId
560                                 , pSglInfo->program
561                                 );
562
563                 _GlesFboInitialize_2(pSglInfo->fboWidth
564                                 , pSglInfo->fboHeight
565                                 , pSglInfo->frameBufferObject
566                                 , pSglInfo->depthRenderBuffer
567                                 , pSglInfo->stencilRenderBuffer
568                                 , pSglInfo->colorSize
569                                 , pSglInfo->depthSize
570                                 , pSglInfo->stencilSize
571                                 , pSglInfo->textureId
572                                 , pSglInfo->program
573                                 );
574         }
575         else
576         {
577                 SysLog(NID_GRP, "ambiguous gl Version %d", pSglInfo->glVersion);
578         }
579 }
580 #endif //#if defined(FGRAPHICS_INTERNAL_USE_FBO)
581
582 class _SglInfoTableManipulator
583 {
584 public:
585         _SglInfoTableManipulator()
586         {
587                 result r = __SglMutex.Create();
588                 SysTryLog(NID_GRP, r == E_SUCCESS, "Failed to create mutex. [%s]", GetErrorMessage(r));
589                 __SglIndexLastUsed = INVALID_SGL_INDEX;
590                 __SglInitialized = false;
591         }
592
593         ~_SglInfoTableManipulator()
594         {
595         }
596
597         _SglIndex
598         FindNextEmptySlotOfSglInfoTable()
599         {
600                 if (!__SglInitialized)
601                 {
602                         if (CreateSglInfoTable() == false)
603                         {
604                                 return INVALID_SGL_INDEX;
605                         }
606                 }
607
608                 _SglIndex sglIndex = INVALID_SGL_INDEX;
609                 _SglIndex index = __SglIndexLastUsed;
610                 {
611                         __SglMutex.Acquire();
612                         for (int i = 1; i < MAX_SGL_INDEX; i++)
613                         {
614                                 index++;
615
616                                 if (index >= MAX_SGL_INDEX)
617                                 {
618                                         index = 1;
619                                 }
620
621                                 if (__SglInfoTable[index] == null)
622                                 {
623                                         sglIndex = index;
624                                         __SglIndexLastUsed = index;
625                                         break;
626                                 }
627                         }
628                         __SglMutex.Release();
629                 }
630
631                 if (sglIndex <= INVALID_SGL_INDEX)
632                 {
633                         return INVALID_SGL_INDEX;
634                 }
635
636                 return sglIndex;
637         }
638
639         bool
640         CreateSglInfoTable()
641         {
642                 bool ret = false;
643
644                 __SglMutex.Acquire();
645
646                 for (int i = 0 ; i < MAX_SGL_INDEX; i++)
647                 {
648                         __SglInfoTable[i] = null;
649                 }
650
651                 __SglInfoTable[0] = new (std::nothrow) _SglInfo;
652                 if (__SglInfoTable[0] != null)
653                         {
654                         ret = true;
655                         __SglInitialized = true;
656                 }
657
658                 __SglMutex.Release();
659
660                 return ret;
661         }
662
663         void
664         DestroySglInfoTable()
665         {
666                 __SglMutex.Acquire();
667
668                 for (int i = 0 ; i < MAX_SGL_INDEX; i++)
669                 {
670                         if (__SglInfoTable[i] != null)
671                         {
672                                 delete __SglInfoTable[i];
673                                 __SglInfoTable[i] = null;
674                         }
675                 }
676                 __SglInitialized = false;
677
678                 __SglMutex.Release();
679         }
680
681         _SglInfo*
682         LockSglInfoTable(_SglIndex index)
683         {
684                 __SglMutex.Acquire();
685
686                 if (index < INVALID_SGL_INDEX || index >= MAX_SGL_INDEX)
687                 {
688                         return null;
689                 }
690
691                 return __SglInfoTable[index];
692         }
693
694         void
695         UnlockSglInfoTable()
696         {
697                 __SglMutex.Release();
698         }
699
700         _SglIndex
701         CreateSglIndex(void)
702         {
703                 _SglInfo* newSglInfo = new (std::nothrow) _SglInfo;
704                 if (newSglInfo == null)
705                 {
706                         SysLog(NID_GRP, "CreateSglIndex fail to allocate _SglInfo!!");
707                         return INVALID_SGL_INDEX;
708                 }
709
710                 int sglIndex = FindNextEmptySlotOfSglInfoTable();
711                 if (sglIndex == INVALID_SGL_INDEX)
712                 {
713                         delete newSglInfo;
714
715                         SysLog(NID_GRP, "CreateSglIndex failed!!");
716                         return INVALID_SGL_INDEX;
717                 }
718
719                 __SglMutex.Acquire();
720                 __SglInfoTable[sglIndex] = newSglInfo;
721                 __SglMutex.Release();
722
723                 return sglIndex;
724         }
725
726         bool
727         DestroySglIndex(_SglIndex sglIndex)
728         {
729                 if (sglIndex < 1 || sglIndex >= MAX_SGL_INDEX)
730                 {
731                         SysLog(NID_GRP, "sglIndex:%#x is out of range.", (unsigned int)sglIndex);
732                         return false;
733                 }
734
735                 __SglMutex.Acquire();
736
737                 if (sglIndex <= INVALID_SGL_INDEX || __SglInfoTable[sglIndex] == null)
738                 {
739                         __SglMutex.Release();
740
741                         SysLog(NID_GRP, "DestroySglIndex failed!! sglIndex:%#x", (unsigned int)sglIndex);
742                         return false;
743                 }
744
745                 delete __SglInfoTable[sglIndex];
746                 __SglInfoTable[sglIndex] = null;
747
748                 __SglMutex.Release();
749
750                 return true;
751         }
752
753         _SglIndex
754         GetSglIndexForSurface(EGLSurface surface)
755         {
756                 __SglMutex.Acquire();
757
758                 int sglIndex = 0;
759                 for (int i = 0; i < MAX_SGL_INDEX; i++)
760                 {
761                         if (__SglInfoTable[i] != null && __SglInfoTable[i]->surface == surface)
762                         {
763                                 sglIndex = i;
764                                 break;
765                         }
766                 }
767
768                 __SglMutex.Release();
769
770                 return sglIndex;
771         }
772
773         static _SglInfoTableManipulator* GetInstance(void)
774         {
775                 static pthread_once_t once_block = PTHREAD_ONCE_INIT;
776
777                 if (!__pTheInstance)
778                 {
779                         pthread_once(&once_block, __InitSglInfoTableManipulator);
780                 }
781
782                 return __pTheInstance;
783         }
784
785 private:
786         static void __InitSglInfoTableManipulator(void)
787         {
788                 static _SglInfoTableManipulator instance;
789                 __pTheInstance = &instance;
790         }
791
792 private:
793         Runtime::Mutex __SglMutex;
794         _SglInfo* __SglInfoTable[MAX_SGL_INDEX];
795         _SglIndex __SglIndexLastUsed;
796         bool __SglInitialized;
797
798         static _SglInfoTableManipulator* __pTheInstance;
799 };
800 _SglInfoTableManipulator* _SglInfoTableManipulator::__pTheInstance = null;
801
802 void
803 _PixmapSurfaceDestroyCallback(void* pCallbackParam)
804 {
805         delete (_PixmapInfo*)pCallbackParam;
806 }
807
808 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
809 void
810 _PixmapLockCallBack(void* pCallbackParam)
811 {
812         drm_slp_bo_map((drm_slp_bo)pCallbackParam, DRM_SLP_DEVICE_CPU, DRM_SLP_OPTION_READ | DRM_SLP_OPTION_WRITE);
813 }
814
815 void
816 _PixmapUnlockCallBack(void* pCallbackParam)
817 {
818         drm_slp_bo_unmap((drm_slp_bo)pCallbackParam, DRM_SLP_DEVICE_CPU);
819 }
820 #endif
821
822 bool
823 _IsEvasGlEnabled(void)
824 {
825         const char* pString = elm_config_preferred_engine_get();
826         String engineName(pString);
827
828         if (engineName.Contains(String("opengl_x11")))
829         {
830                 SysLog(NID_GRP, "gl backend : %s", pString);
831                 return true;
832         }
833         else if (engineName.Contains(String("software_x11")))
834         {
835                 SysLog(NID_GRP, "sw backend : %s", pString);
836                 return false;
837         }
838         else
839         {
840                 pString = elm_config_engine_get();
841                 String engineName(pString);
842                 if (engineName.Contains(String("opengl_x11")))
843                 {
844                         SysLog(NID_GRP, "system gl backend : %s", pString);
845                         return true;
846                 }
847         }
848
849         SysLog(NID_GRP, "system sw backend : %s", pString);
850         return false;
851 }
852
853 void
854 _EvasObjectImageChange(_SglInfo* pSglInfo)
855 {
856         if (isEvasNativeSetEnabled)
857         {
858                 Evas* pEvas = evas_object_evas_get(pSglInfo->pObject);
859                 if (pEvas == null)
860                 {
861                         return;
862                 }
863
864                 Evas_Engine_Info_GL_X11* pEvasInfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(pEvas);
865                 if (pEvasInfo == null)
866                 {
867                         return;
868                 }
869                 Evas_Native_Surface nativeSurface = {0, };
870                 nativeSurface.type = EVAS_NATIVE_SURFACE_X11;
871                 nativeSurface.version = EVAS_NATIVE_SURFACE_VERSION;
872                 nativeSurface.data.x11.pixmap = (unsigned long)pSglInfo->nativePixmap;
873                 nativeSurface.data.x11.visual = pEvasInfo->info.visual;
874                 evas_object_image_native_surface_set(pSglInfo->pObject, &nativeSurface);
875
876 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
877                 _PostRenderCallback(NULL);
878 #endif
879         }
880         else
881         {
882                 Tizen::Graphics::BufferInfo bufferInfo;
883                 pSglInfo->pBitmap->Lock(bufferInfo);
884                 evas_object_image_data_set(pSglInfo->pObject, bufferInfo.pPixels);
885                 pSglInfo->pBitmap->Unlock();
886         }
887 }
888
889 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
890 int __registerCallbackCount = 0;
891 EGLDisplay __previousDisplay = EGL_NO_DISPLAY;
892 EGLSurface __previousDrawSurface = EGL_NO_SURFACE;
893 EGLSurface __previousReadSurface = EGL_NO_SURFACE;
894 EGLContext __previousContext = EGL_NO_CONTEXT;
895
896 void
897 _PostRenderCallback(Ecore_Evas* ee)
898 {
899         EGLBoolean ret = eglMakeCurrent(__previousDisplay, __previousDrawSurface, __previousReadSurface, __previousContext);
900         SysTryLog(NID_GRP, ret == EGL_TRUE, "fail to restore previous surface and context. %#x %#x %#x %#x egl error:%#x"
901                         , (unsigned int)__previousDisplay
902                         , (unsigned int)__previousDrawSurface
903                         , (unsigned int)__previousReadSurface
904                         , (unsigned int)__previousContext
905                         , (unsigned int)eglGetError());
906 }
907
908 void
909 _SaveCurrentContext(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
910 {
911         __previousDisplay = dpy;
912         __previousDrawSurface = draw;
913         __previousReadSurface = read;
914         __previousContext = ctx;
915 }
916
917 void
918 _RegisterRenderCallback(Evas_Object* pObject)
919 {
920         if (__registerCallbackCount == 0)
921         {
922                 Evas* pEvas = evas_object_evas_get(pObject);
923                 if (pEvas == null)
924                 {
925                         return;
926                 }
927
928                 Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
929                 if (pEcoreEvas == null)
930                 {
931                         return;
932                 }
933
934                 ecore_evas_callback_post_render_set(pEcoreEvas, _PostRenderCallback);
935         }
936         __registerCallbackCount++;
937 }
938
939 void
940 _UnregisterRenderCallback(Evas_Object* pObject)
941 {
942         __registerCallbackCount--;
943
944         if (__registerCallbackCount == 0)
945         {
946                 Evas* pEvas = evas_object_evas_get(pObject);
947                 if (pEvas == null)
948                 {
949                         return;
950                 }
951
952                 Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
953                 if (pEcoreEvas == null)
954                 {
955                         return;
956                 }
957
958                 ecore_evas_callback_post_render_set(pEcoreEvas, NULL);
959         }
960 }
961 #endif //#if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
962
963 }
964
965 #ifdef __cplusplus
966 extern "C"
967 {
968 #endif
969
970 EGLint
971 _SglGetError()
972 {
973         return eglGetError();
974 }
975
976 EGLDisplay
977 _SglGetDisplay(EGLNativeDisplayType displayId)
978 {
979         if (displayId == (EGLNativeDisplayType) EGL_DEFAULT_DISPLAY)
980         {
981                 return eglGetDisplay((EGLNativeDisplayType) ecore_x_display_get());
982         }
983
984         return eglGetDisplay((EGLNativeDisplayType) displayId);
985 }
986
987 EGLBoolean
988 _SglInitialize(EGLDisplay dpy, EGLint* pMajor, EGLint* pMinor)
989 {
990         return eglInitialize(dpy, pMajor, pMinor);
991 }
992
993 EGLBoolean
994 _SglTerminate(EGLDisplay dpy)
995 {
996         _GlesInterfaceTerminate_1();
997         _GlesInterfaceTerminate_2();
998
999         _SglInfoTableManipulator::GetInstance()->DestroySglInfoTable();
1000
1001 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
1002         if (_fboContext != EGL_NO_CONTEXT)
1003         {
1004                 eglDestroyContext(dpy, _fboContext);
1005                 _fboContext = EGL_NO_CONTEXT;
1006         }
1007 #endif
1008
1009         if (!_IsEvasGlEnabled())
1010         {
1011                 eglTerminate(dpy);
1012         }
1013
1014         return EGL_TRUE;
1015 }
1016
1017 const char*
1018 _SglQueryString(EGLDisplay dpy, EGLint name)
1019 {
1020         return eglQueryString(dpy, name);
1021 }
1022
1023 EGLBoolean
1024 _SglGetConfigs(EGLDisplay dpy, EGLConfig* pConfigs, EGLint configSize, EGLint* pNumConfig)
1025 {
1026         return eglGetConfigs(dpy, pConfigs, configSize, pNumConfig);
1027 }
1028
1029 EGLBoolean
1030 _SglChooseConfig(EGLDisplay dpy, const EGLint* pAttribList, EGLConfig* pConfigs, EGLint configSize, EGLint* pNumConfig)
1031 {
1032         return eglChooseConfig(dpy, pAttribList, pConfigs, configSize, pNumConfig);
1033 }
1034
1035 EGLBoolean
1036 _SglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* pValue)
1037 {
1038         return eglGetConfigAttrib(dpy, config, attribute, pValue);
1039 }
1040
1041 EGLSurface
1042 _SglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* pAttribList)
1043 {
1044         _SglIndex sglIndex = INVALID_SGL_INDEX;
1045         Tizen::Graphics::Bitmap* pBitmap = null;
1046         VisualElementSurface* pVisualElementSurface = null;
1047         Object* pObj = (Object*)win;
1048         VisualElement* pVE = dynamic_cast<VisualElement*>(pObj);
1049         Tizen::Ui::Control* pControl = dynamic_cast<Tizen::Ui::Control*>(pObj);
1050 #if !defined(_OSP_EMUL_)
1051         Tizen::Ui::Controls::Frame* pFrame = dynamic_cast<Tizen::Ui::Controls::Frame*>(pControl);
1052 #endif
1053         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1054
1055         if (pControl == null && pVE == null)
1056         {
1057                 goto CATCH_01;
1058         }
1059
1060 #if !defined(_OSP_EMUL_)
1061         if (pFrame != null && !_IsEvasGlEnabled())
1062         {
1063                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(*pControl);
1064                 _WindowImpl* pWindowImpl = dynamic_cast<_WindowImpl*> (pControlImpl);
1065                 if (pWindowImpl == null)
1066                 {
1067                         goto CATCH_01;
1068                 }
1069
1070                 EGLNativeWindowType nativeWindow = (EGLNativeWindowType)pWindowImpl->GetNativeHandle();
1071
1072                 sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1073                 if (sglIndex <= INVALID_SGL_INDEX)
1074                 {
1075                         goto CATCH_01;
1076                 }
1077
1078                 EGLSurface windowSurface = eglCreateWindowSurface(dpy, config, nativeWindow, pAttribList);
1079                 if (windowSurface == EGL_NO_SURFACE)
1080                 {
1081                         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1082                         sglIndex = 0;
1083                 }
1084                 else
1085                 {
1086                         _VisualElementImpl* visualElementImpl = _VisualElementImpl::GetInstance(*pControlImpl->GetCore().GetVisualElement());
1087                         if (visualElementImpl == null)
1088                         {
1089                                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1090                                 sglIndex = 0;
1091                                 goto CATCH_01;
1092                         }
1093
1094                         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1095
1096 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
1097                         pSglInfo->pFrame = pFrame;
1098                         eglGetConfigAttrib(dpy, config, EGL_BUFFER_SIZE, &pSglInfo->colorSize);
1099                         eglGetConfigAttrib(dpy, config, EGL_DEPTH_SIZE, &pSglInfo->depthSize);
1100                         eglGetConfigAttrib(dpy, config, EGL_STENCIL_SIZE, &pSglInfo->stencilSize);
1101
1102                         pSglInfo->display = dpy;
1103                         pSglInfo->pVisualElementImpl = visualElementImpl;
1104                         pSglInfo->pVisualElementImpl->SetBoundsChangedCallback(_OnBoundsChangedFbo, pSglInfo);
1105 #endif
1106                         pSglInfo->surface = windowSurface;
1107
1108                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1109                 }
1110
1111                 return (EGLSurface)sglIndex;
1112         }
1113         else
1114 #endif //#if !defined(_OSP_EMUL_)
1115         {
1116                 _VisualElementImpl* pVisualElementImpl = null;
1117                 _VisualElementSurfaceImpl* pVisualElementSurfaceImpl = null;
1118                 int width = 0;
1119                 int height = 0;
1120                 result r = E_SUCCESS;
1121                 Tizen::Graphics::FloatRectangle rect;
1122                 _SglInfo* pSglInfo = null;
1123
1124                 if (pVE == null)
1125                 {
1126                         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(*pControl);
1127                         if (pControlImpl == null)
1128                         {
1129                                 goto CATCH_01;
1130                         }
1131                         pVE = pControlImpl->GetCore().GetVisualElement();
1132                 }
1133
1134                 pVisualElementImpl = _VisualElementImpl::GetInstance(*pVE);
1135                 if (pVisualElementImpl == null)
1136                 {
1137                         goto CATCH_01;
1138                 }
1139
1140                 rect = pVisualElementImpl->GetBounds();
1141                 width = int(rect.width);
1142                 height = int(rect.height);
1143                 if (width <= 0 || height <= 0)
1144                 {
1145                         goto CATCH_01;
1146                 }
1147
1148 #if defined (FGRAPHICS_INTERNAL_USE_EVAS_NATIVE_SURFACE)
1149                 isEvasNativeSetEnabled = _IsEvasGlEnabled();
1150 #else
1151                 isEvasNativeSetEnabled = false;
1152 #endif
1153
1154                 if (isEvasNativeSetEnabled)
1155                 {
1156                         Control* pFrame = pControl;
1157                         Control* pTemp = pFrame->GetParent();
1158                         while(pTemp != null)
1159                         {
1160                                 pFrame = pTemp;
1161                                 pTemp = pTemp->GetParent();
1162                         }
1163
1164                         Dimension size(width, height);
1165                         Tizen::Ui::Window* pWindow = dynamic_cast<Tizen::Ui::Window*> (pFrame);
1166                         if (pWindow == null)
1167                         {
1168                                 goto CATCH_01;
1169                         }
1170
1171                         pVisualElementSurface = new (std::nothrow) VisualElementSurface();
1172                         if (pVisualElementSurface == null)
1173                         {
1174                                 goto CATCH_01;
1175                         }
1176
1177                         r = pVisualElementSurface->Construct(*pWindow->GetDisplayContext(), size);
1178                         pVE->SetSurface(pVisualElementSurface);
1179                 }
1180                 else
1181                 {
1182                         pVisualElementSurface = pVisualElementImpl->GetSurfaceN();
1183                         if (pVisualElementSurface == null)
1184                         {
1185                                 goto CATCH_01;
1186                         }
1187                 }
1188
1189                 pBitmap = new (std::nothrow) Tizen::Graphics::Bitmap;
1190                 if (pBitmap == null)
1191                 {
1192                         goto CATCH_02;
1193                 }
1194
1195                 r = pBitmap->Construct(Tizen::Graphics::Rectangle(0, 0, width, height));
1196                 if (r != E_SUCCESS)
1197                 {
1198                         goto CATCH_03;
1199                 }
1200
1201                 sglIndex = (_SglIndex)_SglCreatePixmapSurface(dpy, config, (EGLNativePixmapType)pBitmap, null);
1202                 if (sglIndex <= INVALID_SGL_INDEX)
1203                 {
1204                         goto CATCH_03;
1205                 }
1206
1207                 pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1208
1209                 pSglInfo->sglIndex = sglIndex;
1210                 pSglInfo->display = dpy;
1211                 pSglInfo->config = config;
1212                 pSglInfo->pBitmap = pBitmap;
1213                 pSglInfo->pVisualElementImpl = pVisualElementImpl;
1214                 pSglInfo->pControl = pControl;
1215
1216                 pVisualElementImpl->SetBoundsChangedCallback(_OnBoundsChanged, pSglInfo);
1217
1218                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1219
1220                 pVisualElementSurfaceImpl = _VisualElementSurfaceImpl::GetInstance(*pVisualElementSurface);
1221                 if (pVisualElementSurfaceImpl == null)
1222                 {
1223                         goto CATCH_03;
1224                 }
1225
1226                 pSglInfo->pObject = (Evas_Object*)pVisualElementSurfaceImpl->GetNativeHandle();
1227                 if (pSglInfo->pObject == null)
1228                 {
1229                         goto CATCH_03;
1230                 }
1231
1232                 _EvasObjectImageChange(pSglInfo);
1233
1234 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
1235                 if (isEvasNativeSetEnabled)
1236                 {
1237                         _RegisterRenderCallback(pSglInfo->pObject);
1238                 }
1239 #endif
1240
1241                 return (EGLSurface)sglIndex;
1242         }
1243
1244 CATCH_03:
1245         delete pBitmap;
1246
1247         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1248         //fall through
1249
1250 CATCH_02:
1251         delete pVisualElementSurface;
1252         //fall through
1253
1254 CATCH_01:
1255         SysLog(NID_GRP, "_SglCreateWindowSurface failed!! dpy:%#x config:%#x pControl:%#x pAttribList:%#x",
1256                         (unsigned int)dpy, (unsigned int)config, (unsigned int)pControl, (unsigned int)pAttribList);
1257         return eglCreateWindowSurface(dpy, config, (EGLNativeWindowType) 0, pAttribList);
1258 }
1259
1260 EGLSurface
1261 _SglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* pAttribList)
1262 {
1263         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1264         _SglIndex sglIndex = INVALID_SGL_INDEX;
1265
1266         sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1267         if (sglIndex <= INVALID_SGL_INDEX)
1268         {
1269                 SysLog(NID_GRP, "_SglCreatePbufferSurface failed!! dpy:%#x config:%#x pAttribList:%#x",
1270                                 (unsigned int)dpy, (unsigned int)config, (unsigned int)pAttribList);
1271
1272                 return eglCreatePbufferSurface(EGL_NO_DISPLAY, config, pAttribList);
1273         }
1274
1275         EGLSurface pbufferSurface = eglCreatePbufferSurface(dpy, config, pAttribList);
1276         if (pbufferSurface == EGL_NO_SURFACE)
1277         {
1278                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1279                 sglIndex = 0;
1280         }
1281         else
1282         {
1283                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1284
1285                 pSglInfo->surface = pbufferSurface;
1286
1287                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1288         }
1289
1290         return (EGLSurface)sglIndex;
1291 }
1292
1293 _OSP_LOCAL_ EGLNativePixmapType
1294 _CreateNativePixmap(_SglIndex sglIndex, Tizen::Graphics::Bitmap* pBitmap)
1295 {
1296         int width = 0;
1297         int height = 0;
1298         int bitsPerPixel = 0;
1299         Display* pNativeDisplay = null;
1300         Drawable nativeWindow = 0;
1301         result r = E_FAILURE;
1302         Tizen::Graphics::BufferInfo bufferInfo;
1303         _PixmapInfo* pPixmapInfo = null;
1304 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1305         unsigned int attachments[] = { DRI2BufferFrontLeft };
1306         char* pDeviceName = null;
1307         char* pDriverName = null;
1308         DRI2Buffer* pDri2Buffer = null;
1309         int dri2Width = 0;
1310         int dri2Height = 0;
1311         int dri2BufferCount = 0;
1312         int drmFile = 0;
1313         void* pData = null;
1314         Bool ret = False;
1315         drm_magic_t magic = 0;
1316 #endif
1317         _SglInfo* pSglInfo = null;
1318         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1319
1320         pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1321         if (pBitmap == null || sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1322         {
1323                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1324                 goto CATCH_01;
1325         }
1326         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1327
1328         r = pBitmap->Lock(bufferInfo);
1329         if (r != E_SUCCESS)
1330         {
1331                 goto CATCH_01;
1332         }
1333
1334         width = bufferInfo.width;
1335         height = bufferInfo.height;
1336         bitsPerPixel = bufferInfo.bitsPerPixel;
1337
1338         r = pBitmap->Unlock();
1339         if (r != E_SUCCESS || width <= 0 || height <= 0 || bitsPerPixel <= 0)
1340         {
1341                 goto CATCH_01;
1342         }
1343
1344         pNativeDisplay = (Display*) ecore_x_display_get();
1345         nativeWindow = DefaultRootWindow(pNativeDisplay);
1346
1347         pPixmapInfo = new (std::nothrow) _PixmapInfo;
1348         if (pPixmapInfo == null)
1349         {
1350                 goto CATCH_01;
1351         }
1352
1353         pPixmapInfo->nativePixmap = XCreatePixmap(pNativeDisplay, nativeWindow, width, height,
1354                         ecore_x_default_depth_get(pNativeDisplay, ecore_x_default_screen_get()));
1355         if (pPixmapInfo->nativePixmap == (Pixmap)0)
1356         {
1357                 goto CATCH_02;
1358         }
1359
1360 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1361         DRI2CreateDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1362         XSync(pNativeDisplay, False);
1363
1364         ret = DRI2Connect(pNativeDisplay, nativeWindow, &pDriverName, &pDeviceName);
1365         free(pDriverName);
1366         if (!ret || pDeviceName == null)
1367         {
1368                 goto CATCH_03;
1369         }
1370
1371         drmFile = open(pDeviceName, O_RDWR);
1372         free(pDeviceName);
1373         if (drmFile < 0)
1374         {
1375                 goto CATCH_03;
1376         }
1377
1378         drmGetMagic(drmFile, &magic);
1379         ret = DRI2Authenticate(pNativeDisplay, nativeWindow, (unsigned int)magic);
1380         if (!ret)
1381         {
1382                 goto CATCH_04;
1383         }
1384
1385         pPixmapInfo->pDrmBufMgr = drm_slp_bufmgr_init(drmFile, null);
1386         if (pPixmapInfo->pDrmBufMgr == null)
1387         {
1388                 goto CATCH_04;
1389         }
1390
1391         pDri2Buffer = DRI2GetBuffers(pNativeDisplay, pPixmapInfo->nativePixmap, &dri2Width, &dri2Height, attachments, 1, &dri2BufferCount);
1392         if (pDri2Buffer == null)
1393         {
1394                 goto CATCH_05;
1395         }
1396
1397         pPixmapInfo->pDrmBufferObject = drm_slp_bo_import(pPixmapInfo->pDrmBufMgr, pDri2Buffer->name);
1398         free(pDri2Buffer);
1399         if (pPixmapInfo->pDrmBufferObject == null)
1400         {
1401                 goto CATCH_05;
1402         }
1403
1404         pData = (void*)drm_slp_bo_get_handle(pPixmapInfo->pDrmBufferObject, DRM_SLP_DEVICE_CPU);
1405         if (pData == null)
1406         {
1407                 goto CATCH_06;
1408         }
1409
1410         r = Tizen::Graphics::_BitmapTool::ChangeBuffer(*pBitmap, pData, width * bitsPerPixel / 8,
1411                         _PixmapSurfaceDestroyCallback, (void*)pPixmapInfo);
1412         if (r != E_SUCCESS)
1413         {
1414                 goto CATCH_06;
1415         }
1416
1417         if (!Tizen::Graphics::_BitmapTool::SetCallback(*pBitmap, _PixmapSurfaceDestroyCallback, pPixmapInfo,
1418                         _PixmapLockCallBack, pPixmapInfo->pDrmBufferObject,_PixmapUnlockCallBack, pPixmapInfo->pDrmBufferObject))
1419         {
1420                 goto CATCH_06;
1421         }
1422
1423 #else
1424 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
1425         {
1426                 pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1427
1428                 pSglInfo->pEcoreImage = ecore_x_image_new(width
1429                         , height
1430                         , ecore_x_default_visual_get(pNativeDisplay, ecore_x_default_screen_get())
1431                         , ecore_x_default_depth_get(pNativeDisplay, ecore_x_default_screen_get()));
1432
1433                 if (pSglInfo->pEcoreImage == null)
1434                 {
1435                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1436                         goto CATCH_06;
1437                 }
1438
1439                 ecore_x_image_get(pSglInfo->pEcoreImage
1440                         , pPixmapInfo->nativePixmap, 0, 0, 0, 0
1441                         , width
1442                         , height);
1443
1444                 int bpl = 0;
1445                 int rows = 0;
1446                 int bpp = 0;
1447
1448                 void* pSource = ecore_x_image_data_get(pSglInfo->pEcoreImage, &bpl, &rows, &bpp);
1449
1450                 r = Tizen::Graphics::_BitmapTool::ChangeBuffer(*pBitmap, pSource, width * bitsPerPixel / 8,
1451                 _PixmapSurfaceDestroyCallback, (void*)pPixmapInfo);
1452                 if (r != E_SUCCESS)
1453                 {
1454                         ecore_x_image_free(pSglInfo->pEcoreImage);
1455                         pSglInfo->pEcoreImage = null;
1456                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1457
1458                         SysLog(NID_GRP, "change buffer failed! pSource %#x %d %d %d", (unsigned int)pSource, bpl, rows, bpp);
1459                         goto CATCH_06;
1460                 }
1461
1462                 pSglInfo->width = width;
1463                 pSglInfo->height = height;
1464
1465                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1466         }
1467 #endif //#if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
1468 #endif //#if defined(FGRAPHICS_INTERNAL_USE_DRM)
1469
1470         return (EGLNativePixmapType)pPixmapInfo->nativePixmap;
1471
1472 CATCH_06:
1473 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1474         drm_slp_bo_unmap(pPixmapInfo->pDrmBufferObject, DRM_SLP_DEVICE_CPU);
1475         drm_slp_bo_unref(pPixmapInfo->pDrmBufferObject);
1476         //fall through
1477
1478 CATCH_05:
1479         drm_slp_bufmgr_destroy(pPixmapInfo->pDrmBufMgr);
1480         //fall through
1481
1482 CATCH_04:
1483         close(drmFile);
1484         //fall through
1485
1486 CATCH_03:
1487         DRI2DestroyDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1488 #endif
1489         XFreePixmap(pNativeDisplay, pPixmapInfo->nativePixmap);
1490         //fall through
1491
1492 CATCH_02:
1493         delete pPixmapInfo;
1494         //fall through
1495
1496 CATCH_01:
1497         SysLog(NID_GRP, "_CreateNativePixmap failed!! pBitmap:%#x", (unsigned int)pBitmap);
1498         return (EGLNativePixmapType)0;
1499 }
1500
1501 _OSP_LOCAL_ EGLNativePixmapType
1502 _CreateNativePixmapEx(Tizen::Graphics::Bitmap* pBitmap, Tizen::Graphics::BufferInfo bufferInfo)
1503 {
1504 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1505         int width = 0;
1506         int height = 0;
1507         int bitsPerPixel = 0;
1508         Display* pNativeDisplay = null;
1509         Drawable nativeWindow = 0;
1510         unsigned int attachments[] = { DRI2BufferFrontLeft };
1511         char* pDeviceName = null;
1512         char* pDriverName = null;
1513         DRI2Buffer* pDri2Buffer = null;
1514         int dri2Width = 0;
1515         int dri2Height = 0;
1516         int dri2BufferCount = 0;
1517         int drmFile = 0;
1518         Bool ret = False;
1519         result r = E_FAILURE;
1520         Tizen::Graphics::_BitmapImpl* pBitmapImpl = null;
1521         drm_magic_t magic = 0;
1522         _PixmapInfo* pPixmapInfo = null;
1523
1524         if (pBitmap == null)
1525         {
1526                 goto CATCH_01;
1527         }
1528
1529         pBitmapImpl = Tizen::Graphics::_BitmapImpl::GetInstance(*pBitmap);
1530         if (pBitmapImpl == null)
1531         {
1532                 goto CATCH_01;
1533         }
1534
1535         width = bufferInfo.width;
1536         height = bufferInfo.height;
1537         bitsPerPixel = bufferInfo.bitsPerPixel;
1538
1539         if (width <= 0 || height <= 0 || bitsPerPixel <= 0)
1540         {
1541                 goto CATCH_01;
1542         }
1543
1544         pNativeDisplay = (Display*) ecore_x_display_get();
1545         nativeWindow = DefaultRootWindow(pNativeDisplay);
1546
1547         pPixmapInfo = new (std::nothrow) _PixmapInfo;
1548         if (pPixmapInfo == null)
1549         {
1550                 goto CATCH_01;
1551         }
1552
1553         pPixmapInfo->nativePixmap = XCreatePixmap(pNativeDisplay, nativeWindow, width, height, bitsPerPixel);
1554         if (pPixmapInfo->nativePixmap == (Pixmap)0)
1555         {
1556                 goto CATCH_02;
1557         }
1558         DRI2CreateDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1559         XSync(pNativeDisplay, False);
1560
1561         ret = DRI2Connect(pNativeDisplay, nativeWindow, &pDriverName, &pDeviceName);
1562         free(pDriverName);
1563         if (!ret || pDeviceName == null)
1564         {
1565                 goto CATCH_03;
1566         }
1567
1568         drmFile = open(pDeviceName, O_RDWR);
1569         free(pDeviceName);
1570         if (drmFile < 0)
1571         {
1572                 goto CATCH_03;
1573         }
1574
1575         drmGetMagic(drmFile, &magic);
1576         ret = DRI2Authenticate(pNativeDisplay, nativeWindow, (unsigned int)magic);
1577         if (!ret)
1578         {
1579                 goto CATCH_04;
1580         }
1581
1582         pPixmapInfo->pDrmBufMgr = drm_slp_bufmgr_init(drmFile, null);
1583         if (pPixmapInfo->pDrmBufMgr == null)
1584         {
1585                 goto CATCH_04;
1586         }
1587
1588         pDri2Buffer = DRI2GetBuffers(pNativeDisplay, pPixmapInfo->nativePixmap, &dri2Width, &dri2Height, attachments, 1, &dri2BufferCount);
1589         if (pDri2Buffer == null)
1590         {
1591                 goto CATCH_05;
1592         }
1593
1594         pPixmapInfo->pDrmBufferObject = drm_slp_bo_import(pPixmapInfo->pDrmBufMgr, pDri2Buffer->name);
1595         free(pDri2Buffer);
1596         if (pPixmapInfo->pDrmBufferObject == null)
1597         {
1598                 goto CATCH_05;
1599         }
1600
1601         bufferInfo.pPixels = (void*)drm_slp_bo_get_handle(pPixmapInfo->pDrmBufferObject, DRM_SLP_DEVICE_CPU);
1602         if (bufferInfo.pPixels == null)
1603         {
1604                 goto CATCH_06;
1605         }
1606
1607         bufferInfo.bitsPerPixel = 32;
1608         bufferInfo.pixelFormat = PIXEL_FORMAT_ARGB8888;
1609         bufferInfo.pitch = bufferInfo.width*bufferInfo.bitsPerPixel/4;
1610         memset(bufferInfo.pPixels, 0, bufferInfo.width * bufferInfo.height * 4);
1611         r = pBitmapImpl->Construct(bufferInfo);
1612         if (r != E_SUCCESS)
1613         {
1614                 goto CATCH_06;
1615         }
1616
1617         if (!Tizen::Graphics::_BitmapTool::SetCallback(*pBitmap, _PixmapSurfaceDestroyCallback, pPixmapInfo,
1618                         _PixmapLockCallBack, pPixmapInfo->pDrmBufferObject,_PixmapUnlockCallBack, pPixmapInfo->pDrmBufferObject))
1619         {
1620                 goto CATCH_06;
1621         }
1622
1623         return (EGLNativePixmapType)pPixmapInfo->nativePixmap;
1624
1625 CATCH_06:
1626         drm_slp_bo_unmap(pPixmapInfo->pDrmBufferObject, DRM_SLP_DEVICE_CPU);
1627         drm_slp_bo_unref(pPixmapInfo->pDrmBufferObject);
1628         //fall through
1629
1630 CATCH_05:
1631         drm_slp_bufmgr_destroy(pPixmapInfo->pDrmBufMgr);
1632         //fall through
1633
1634 CATCH_04:
1635         close(drmFile);
1636         //fall through
1637
1638 CATCH_03:
1639         DRI2DestroyDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1640         XFreePixmap(pNativeDisplay, pPixmapInfo->nativePixmap);
1641         //fall through
1642
1643 CATCH_02:
1644         delete pPixmapInfo;
1645         //fall through
1646
1647 CATCH_01:
1648         SysLog(NID_GRP, "_CreateNativePixmap failed!! pBitmap:%#x", (unsigned int)pBitmap);
1649         return (EGLNativePixmapType)0;
1650 #else
1651         return (EGLNativePixmapType)0;
1652 #endif //#if !defined(FGRAPHICS_INTERNAL_USE_DRM)
1653 }
1654
1655 EGLSurface
1656 _SglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* pAttribList)
1657 {
1658         _SglIndex sglIndex = INVALID_SGL_INDEX;
1659         Tizen::Graphics::Bitmap* pBitmap = dynamic_cast<Tizen::Graphics::Bitmap*>((Tizen::Graphics::Bitmap*)pixmap);
1660         EGLNativePixmapType eglNativePixmap = 0;
1661         EGLSurface pixmapSurface = EGL_NO_SURFACE;
1662         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1663
1664         if (pBitmap == null)
1665         {
1666                 goto CATCH_01;
1667         }
1668
1669         sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1670         if (sglIndex <= INVALID_SGL_INDEX)
1671         {
1672                 goto CATCH_01;
1673         }
1674
1675         eglNativePixmap = _CreateNativePixmap(sglIndex, pBitmap);
1676         if (eglNativePixmap == 0)
1677         {
1678                 goto CATCH_02;
1679         }
1680
1681         pixmapSurface = eglCreatePixmapSurface(dpy, config, eglNativePixmap, pAttribList);
1682         if (pixmapSurface == EGL_NO_SURFACE)
1683         {
1684                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1685                 sglIndex = 0;
1686         }
1687         else
1688         {
1689                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1690
1691                 pSglInfo->nativePixmap = eglNativePixmap;
1692                 pSglInfo->surface = pixmapSurface;
1693
1694                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1695         }
1696
1697         return (EGLSurface)sglIndex;
1698
1699 CATCH_02:
1700         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1701         //fall through
1702
1703 CATCH_01:
1704         SysLog(NID_GRP, "_SglCreatePixmapSurface failed!! dpy:%#x config:%#x pixmap:%#x pAttribList:%#x",
1705                         (unsigned int)dpy, (unsigned int)config, (unsigned int)pixmap, (unsigned int)pAttribList);
1706         return eglCreatePixmapSurface(EGL_NO_DISPLAY, config, (EGLNativePixmapType) 0, pAttribList);
1707 }
1708
1709 EGLBoolean
1710 _SglDestroySurface(EGLDisplay dpy, EGLSurface surface)
1711 {
1712         EGLBoolean ret = EGL_FALSE;
1713         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1714
1715         _SglIndex sglIndex = (_SglIndex)surface;
1716         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1717
1718         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1719         {
1720                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1721                 SysLog(NID_GRP, "_SglDestroySurface failed!! dpy:%#x sglIndex:%#x", (unsigned int)dpy, (unsigned int)surface);
1722                 return eglDestroySurface(dpy, EGL_NO_SURFACE);
1723         }
1724
1725 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
1726         if (pSglInfo->isFboAvailable && pSglInfo->pFrame != null)
1727         {
1728                 if (pSglInfo->glVersion == 1)
1729                 {
1730                         _GlesFboTerminate_1(pSglInfo->frameBufferObject
1731                                 , pSglInfo->depthRenderBuffer
1732                                 , pSglInfo->stencilRenderBuffer
1733                                 , pSglInfo->textureId);
1734                 }
1735                 else if (pSglInfo->glVersion == 2)
1736                 {
1737                         _GlesFboTerminate_2(pSglInfo->frameBufferObject
1738                         , pSglInfo->depthRenderBuffer
1739                         , pSglInfo->stencilRenderBuffer
1740                         , pSglInfo->textureId
1741                         , pSglInfo->program);
1742                 }
1743                 else
1744                 {
1745                         SysLog(NID_GRP, "ambiguous gl Version %d", pSglInfo->glVersion);
1746                 }
1747         }
1748 #endif
1749         ret = eglDestroySurface(dpy, pSglInfo->surface);
1750         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1751
1752         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1753
1754         return ret;
1755 }
1756
1757 EGLBoolean
1758 _SglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* pValue)
1759 {
1760         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1761
1762         _SglIndex sglIndex = (_SglIndex)surface;
1763         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1764
1765         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1766         {
1767                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1768                 SysLog(NID_GRP, "_SglQuerySurface failed!! dpy:%#x sglIndex:%#x attribute:%#x pValue:%#x",
1769                         (unsigned int)dpy, (unsigned int)sglIndex, (unsigned int)attribute, (unsigned int)pValue);
1770                 return eglQuerySurface(dpy, EGL_NO_SURFACE, attribute, pValue);
1771         }
1772
1773         EGLBoolean ret = eglQuerySurface(dpy, pSglInfo->surface, attribute, pValue);
1774         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1775
1776         return ret;
1777 }
1778
1779 EGLBoolean
1780 _SglBindAPI(EGLenum api)
1781 {
1782         return eglBindAPI(api);
1783 }
1784
1785 EGLenum
1786 _SglQueryAPI()
1787 {
1788         return eglQueryAPI();
1789 }
1790
1791 EGLBoolean
1792 _SglWaitClient()
1793 {
1794         return eglWaitClient();
1795 }
1796
1797 EGLBoolean
1798 _SglReleaseThread(void)
1799 {
1800         return eglReleaseThread();
1801 }
1802
1803 EGLSurface
1804 _SglCreatePbufferFromClientBuffer(
1805                 EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint* pAttribList)
1806 {
1807         _SglIndex sglIndex = INVALID_SGL_INDEX;
1808         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1809
1810         sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1811         if (sglIndex <= INVALID_SGL_INDEX)
1812         {
1813                 SysLog(NID_GRP, "_SglCreatePbufferFromClientBuffer failed!!"
1814                         " dpy:%#x buftype:%#x buffer:%#x config:%#x pAttribList:%#x",
1815                         (unsigned int)dpy, (unsigned int)buftype, (unsigned int)buffer, (unsigned int)config, (unsigned int)pAttribList);
1816
1817                 return eglCreatePbufferFromClientBuffer(null, (EGLenum)0, null, null, null);
1818         }
1819
1820         EGLSurface pbufferFromClientBuffer = eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, pAttribList);
1821         if (pbufferFromClientBuffer == EGL_NO_SURFACE)
1822         {
1823                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1824                 sglIndex = 0;
1825         }
1826         else
1827         {
1828                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1829
1830                 pSglInfo->surface = pbufferFromClientBuffer;
1831
1832                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1833         }
1834
1835         return (EGLSurface)sglIndex;
1836 }
1837
1838 EGLBoolean
1839 _SglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1840 {
1841         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1842
1843         _SglIndex sglIndex = (_SglIndex)surface;
1844         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1845
1846         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1847         {
1848                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1849                 SysLog(NID_GRP, "_SglCreatePbufferFromClientBuffer failed!! "
1850                         "dpy:%#x surface:%#x attribute:%#x value:%#x",
1851                         (unsigned int)dpy, (unsigned int)surface, (unsigned int)attribute, (unsigned int)value);
1852
1853                 return eglSurfaceAttrib(dpy, EGL_NO_SURFACE, attribute, value);
1854         }
1855
1856         EGLBoolean ret = eglSurfaceAttrib(dpy, pSglInfo->surface, attribute, value);
1857         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1858
1859         return ret;
1860 }
1861
1862 EGLBoolean
1863 _SglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1864 {
1865         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1866
1867         _SglIndex sglIndex = (_SglIndex)surface;
1868         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1869
1870         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1871         {
1872                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1873                 SysLog(NID_GRP, "_SglBindTexImage failed!! dpy:%#x surface:%#x buffer:%#x",
1874                         (unsigned int)dpy, (unsigned int)surface, (unsigned int)buffer);
1875
1876                 return eglBindTexImage(dpy, EGL_NO_SURFACE, buffer);
1877         }
1878
1879         EGLBoolean ret = eglBindTexImage(dpy, pSglInfo->surface, buffer);
1880         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1881
1882         return ret;
1883 }
1884
1885 EGLBoolean
1886 _SglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1887 {
1888         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1889
1890         _SglIndex sglIndex = (_SglIndex)surface;
1891         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1892
1893         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1894         {
1895                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1896                 SysLog(NID_GRP, "_SglReleaseTexImage failed!! dpy:%#x surface:%#x buffer:%#x",
1897                         (unsigned int)dpy, (unsigned int)surface, (unsigned int)buffer);
1898
1899                 return eglReleaseTexImage(dpy, EGL_NO_SURFACE, buffer);
1900         }
1901
1902         EGLBoolean ret = eglReleaseTexImage(dpy, pSglInfo->surface, buffer);
1903         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1904
1905         return ret;
1906 }
1907
1908 EGLBoolean
1909 _SglSwapInterval(EGLDisplay dpy, EGLint interval)
1910 {
1911         return eglSwapInterval(dpy, interval);
1912 }
1913
1914 EGLContext
1915 _SglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareContext, const EGLint* pAttribList)
1916 {
1917 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
1918         EGLContext ret = EGL_NO_CONTEXT;
1919         if (shareContext == EGL_NO_CONTEXT)
1920         {
1921                 if (_fboContext == EGL_NO_CONTEXT)
1922                 {
1923                         _fboContext = eglCreateContext(dpy, config, EGL_NO_CONTEXT, pAttribList);
1924                         if (_fboContext == EGL_NO_CONTEXT)
1925                         {
1926                                 return EGL_NO_CONTEXT;
1927                         }
1928                 }
1929
1930                 ret = eglCreateContext(dpy, config, _fboContext, pAttribList);
1931         }
1932         else
1933         {
1934                 ret = eglCreateContext(dpy, config, shareContext, pAttribList);
1935         }
1936         return ret;
1937 #else
1938         return eglCreateContext(dpy, config, shareContext, pAttribList);
1939 #endif
1940 }
1941
1942 EGLBoolean
1943 _SglDestroyContext(EGLDisplay dpy, EGLContext ctx)
1944 {
1945         return eglDestroyContext(dpy, ctx);
1946 }
1947
1948 EGLBoolean
1949 _SglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
1950 {
1951         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1952
1953         _SglIndex sglIndexDraw = (_SglIndex)draw;
1954         _SglIndex sglIndexRead = (_SglIndex)read;
1955
1956         EGLSurface sglInfoReadSurface;
1957         {
1958                 _SglInfo* sglInfoRead = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndexRead);
1959
1960                 if (sglInfoRead == null)
1961                 {
1962                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1963                         SysLog(NID_GRP, "_SglMakeCurrent failed!! dpy:%#x draw:%#x read:%#x ctx:%#x",
1964                                 (unsigned int)dpy, (unsigned int)draw, (unsigned int)read, (unsigned int)ctx);
1965                         return eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
1966                 }
1967                 sglInfoReadSurface = sglInfoRead->surface;
1968
1969                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1970         }
1971
1972         _SglInfo* sglInfoDraw = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndexDraw);
1973         if (sglInfoDraw == null)
1974         {
1975                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1976                 SysLog(NID_GRP, "_SglMakeCurrent failed!! dpy:%#x draw:%#x read:%#x ctx:%#x",
1977                                 (unsigned int)dpy, (unsigned int)draw, (unsigned int)read, (unsigned int)ctx);
1978                 return eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
1979         }
1980
1981         sglInfoDraw->context = ctx;
1982
1983         EGLBoolean ret = eglMakeCurrent(dpy, sglInfoDraw->surface, sglInfoReadSurface, ctx);
1984
1985 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
1986         _SaveCurrentContext(dpy, sglInfoDraw->surface, sglInfoReadSurface, ctx);
1987 #endif
1988
1989 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
1990         if (ret != EGL_TRUE || sglInfoDraw->surface == EGL_NO_SURFACE
1991                 || sglInfoReadSurface == EGL_NO_SURFACE
1992                 || ctx == EGL_NO_CONTEXT)
1993         {
1994                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1995                 return ret;
1996         }
1997
1998         if (sglInfoDraw->glVersion == 0)
1999         {
2000                 eglQueryContext(dpy, ctx,  EGL_CONTEXT_CLIENT_VERSION, &sglInfoDraw->glVersion);
2001 #if defined(_OSP_EMUL_) //fixme
2002                 sglInfoDraw->isFboAvailable = false;
2003 #endif
2004         }
2005
2006         if (sglInfoDraw->pFrame != null)
2007         {
2008                 if (sglInfoDraw->isFboAvailable)
2009                 {
2010                         if (sglInfoDraw->frameBufferObject == 0)
2011                         {
2012                                 int x = 0;
2013                                 int y = 0;
2014                                 int width = 0;
2015                                 int height = 0;
2016                                 sglInfoDraw->pFrame->GetBounds(x, y, width, height);
2017
2018                                 sglInfoDraw->fboWidth = width;
2019                                 sglInfoDraw->fboHeight = height;
2020
2021                                 if (sglInfoDraw->glVersion == 1)
2022                                 {
2023                                         sglInfoDraw->isFboAvailable = _GlesFboInitialize_1(sglInfoDraw->fboWidth
2024                                                 , sglInfoDraw->fboHeight
2025                                                 , sglInfoDraw->frameBufferObject, sglInfoDraw->depthRenderBuffer
2026                                                 , sglInfoDraw->stencilRenderBuffer, sglInfoDraw->colorSize
2027                                                 , sglInfoDraw->depthSize, sglInfoDraw->stencilSize
2028                                                 , sglInfoDraw->textureId);
2029                                 }
2030                                 else if (sglInfoDraw->glVersion == 2)
2031                                 {
2032                                         sglInfoDraw->isFboAvailable = _GlesFboInitialize_2(sglInfoDraw->fboWidth
2033                                                 , sglInfoDraw->fboHeight
2034                                                 , sglInfoDraw->frameBufferObject, sglInfoDraw->depthRenderBuffer
2035                                                 , sglInfoDraw->stencilRenderBuffer, sglInfoDraw->colorSize
2036                                                 , sglInfoDraw->depthSize, sglInfoDraw->stencilSize
2037                                                 , sglInfoDraw->textureId, sglInfoDraw->program);
2038                                 }
2039                                 else
2040                                 {
2041                                         SysLog(NID_GRP, "ambiguous gl Version %d", sglInfoDraw->glVersion);
2042                                         sglInfoDraw->isFboAvailable = false;
2043                                 }
2044                         }
2045                         else
2046                         {
2047                                 if (sglInfoDraw->glVersion == 1)
2048                                 {
2049                                         _GlesFboBinding_1(sglInfoDraw->frameBufferObject);
2050                                 }
2051                                 else if (sglInfoDraw->glVersion == 2)
2052                                 {
2053                                         _GlesFboBinding_2(sglInfoDraw->frameBufferObject);
2054                                 }
2055                                 else
2056                                 {
2057                                         SysLog(NID_GRP, "ambiguous gl Version %d", sglInfoDraw->glVersion);
2058                                 }
2059                         }
2060                 }
2061         }
2062         else
2063         {
2064                 if (sglInfoDraw->frameBufferObject != 0 && sglInfoDraw->isFboAvailable)
2065                 {
2066                         if (sglInfoDraw->glVersion == 1)
2067                         {
2068                                 _GlesFboBinding_1(0);
2069                         }
2070                         else if (sglInfoDraw->glVersion == 2)
2071                         {
2072                                 _GlesFboBinding_2(0);
2073                         }
2074                         else
2075                         {
2076                                 SysLog(NID_GRP, "ambiguous gl Version %d", sglInfoDraw->glVersion);
2077                         }
2078                 }
2079         }
2080 #endif
2081         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2082
2083         return ret;
2084 }
2085
2086 EGLContext
2087 _SglGetCurrentContext()
2088 {
2089         return eglGetCurrentContext();
2090 }
2091
2092 EGLSurface
2093 _SglGetCurrentSurface(EGLint readDraw)
2094 {
2095         EGLSurface surface = EGL_NO_SURFACE;
2096         _SglIndex sglIndex = INVALID_SGL_INDEX;
2097
2098         surface = eglGetCurrentSurface(readDraw);
2099         sglIndex = _SglInfoTableManipulator::GetInstance()->GetSglIndexForSurface(surface);
2100
2101         if (sglIndex < INVALID_SGL_INDEX)
2102         {
2103                 SysLog(NID_GRP, "_SglGetCurrentSurface failed!! readDraw:%#x", (unsigned int)readDraw);
2104                 return EGL_NO_SURFACE;
2105         }
2106
2107         return (EGLSurface)sglIndex;
2108 }
2109
2110 EGLDisplay
2111 _SglGetCurrentDisplay(void)
2112 {
2113         return eglGetCurrentDisplay();
2114 }
2115
2116 EGLBoolean
2117 _SglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* pValue)
2118 {
2119         return eglQueryContext(dpy, ctx, attribute, pValue);
2120 }
2121
2122 EGLBoolean
2123 _SglWaitGL(void)
2124 {
2125         return eglWaitGL();
2126 }
2127
2128 EGLBoolean
2129 _SglWaitNative(EGLint engine)
2130 {
2131         return eglWaitNative(engine);
2132 }
2133
2134 EGLBoolean _SglUpdateBufferOSP(EGLDisplay dpy, EGLSurface surface);
2135
2136 EGLBoolean
2137 _SglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
2138 {
2139         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
2140
2141         _SglIndex sglIndex = (_SglIndex)surface;
2142         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
2143
2144         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
2145         {
2146                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2147                 SysLog(NID_GRP, "_SglSwapBuffers failed!! dpy:%#x sglIndex:%#x", (unsigned int)dpy, (unsigned int)sglIndex);
2148
2149                 return eglSwapBuffers(dpy, EGL_NO_SURFACE);
2150         }
2151
2152         if (pSglInfo->pBitmap != null)
2153         {
2154 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
2155                 _SglUpdateBufferOSP(dpy, surface);
2156 #else
2157                 if (!isEvasNativeSetEnabled)
2158                 {
2159                         eglWaitGL();
2160                 }
2161 #endif
2162
2163                 if (isEvasNativeSetEnabled)
2164                 {
2165                         evas_object_image_pixels_dirty_set(pSglInfo->pObject, EINA_TRUE);
2166                 }
2167                 else
2168                 {
2169                         if (pSglInfo->pVisualElementImpl != null)
2170                         {
2171                                 pSglInfo->pVisualElementImpl->SetFlushNeeded();
2172                         }
2173                 }
2174
2175                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2176                 return EGL_TRUE;
2177         }
2178         else
2179         {
2180 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
2181                 if (pSglInfo->pFrame != null)
2182                 {
2183                         if (pSglInfo->isFboAvailable)
2184                         {
2185                                 if (pSglInfo->glVersion == 1)
2186                                 {
2187                                         _GlesFboSwapBuffers_1(pSglInfo->pFrame
2188                                                 , pSglInfo->fboWidth
2189                                                 , pSglInfo->fboHeight
2190                                                 , pSglInfo->frameBufferObject
2191                                                 , pSglInfo->textureId);
2192                                 }
2193                                 else if (pSglInfo->glVersion == 2)
2194                                 {
2195                                         _GlesFboSwapBuffers_2(pSglInfo->pFrame
2196                                                 , pSglInfo->frameBufferObject
2197                                                 , pSglInfo->textureId
2198                                                 , pSglInfo->program);
2199                                 }
2200                                 else
2201                                 {
2202                                         SysLog(NID_GRP, "ambiguous gl Version %d", pSglInfo->glVersion);
2203                                         pSglInfo->isFboAvailable = false;
2204                                 }
2205                         }
2206                 }
2207 #endif
2208                 EGLBoolean ret = eglSwapBuffers(dpy, pSglInfo->surface);
2209                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2210
2211                 return ret;
2212         }
2213 }
2214
2215 EGLBoolean
2216 _SglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
2217 {
2218         Tizen::Graphics::Bitmap* pBitmap = (Tizen::Graphics::Bitmap*)target;
2219         EGLNativePixmapType nativePixmap = _CreateNativePixmap((_SglIndex)surface, pBitmap);
2220         return eglCopyBuffers(dpy, surface, nativePixmap);
2221 }
2222
2223 typedef void (*__EglMustCastToProperFunctionPointerType)(void);
2224
2225 __EglMustCastToProperFunctionPointerType
2226 _SglGetProcAddress(const char* pProcName)
2227 {
2228         return eglGetProcAddress(pProcName);
2229 }
2230
2231 EGLBoolean
2232 _SglUpdateBufferOSP(EGLDisplay dpy, EGLSurface surface)
2233 {
2234 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
2235         Tizen::Graphics::BufferInfo bufferInfo;
2236         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
2237
2238         _SglIndex sglIndex = (_SglIndex)surface;
2239         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
2240
2241         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
2242         {
2243                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2244                 SysLog(NID_GRP, "_SglUpdateBufferOSP failed!!");
2245                 return EGL_FALSE;
2246         }
2247
2248         eglCopyBuffers(dpy, pSglInfo->surface, pSglInfo->nativePixmap);
2249         ecore_x_image_get(pSglInfo->pEcoreImage, pSglInfo->nativePixmap,
2250                 0, 0, 0, 0, pSglInfo->width, pSglInfo->height);
2251
2252         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2253 #endif
2254         return EGL_TRUE;
2255 }
2256
2257 #if defined(FGRAPHICS_INTERNAL_USE_FBO)
2258 _OSP_LOCAL_ GLuint
2259 _GlesGetCurrentFbo(void)
2260 {
2261         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
2262
2263         _SglIndex sglIndex = (_SglIndex)_SglGetCurrentSurface(EGL_DRAW);
2264         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
2265
2266         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
2267         {
2268                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2269                 SysLog(NID_GRP, "Fbo binding failed!!");
2270                 return 0;
2271         }
2272
2273         GLuint ret = pSglInfo->frameBufferObject;
2274         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2275
2276         return ret;
2277 }
2278
2279 _OSP_LOCAL_ bool
2280 _GlesFboEnableStencil(GLuint& frameBufferObject, GLuint& renderBuffer)
2281 {
2282         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
2283
2284         _SglIndex sglIndex = (_SglIndex)_SglGetCurrentSurface(EGL_DRAW);
2285         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
2286
2287         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
2288         {
2289                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2290                 return false;
2291         }
2292
2293         if (!pSglInfo->isStencilEnabled)
2294         {
2295                 pSglInfo->isStencilEnabled =  true;
2296                 frameBufferObject = pSglInfo->frameBufferObject;
2297                 renderBuffer = pSglInfo->stencilRenderBuffer;
2298
2299                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2300                 return true;
2301         }
2302
2303         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2304         return false;
2305 }
2306
2307 #endif
2308
2309 #ifdef __cplusplus
2310 }
2311 #endif
2312
2313 } // Opengl
2314
2315 }} // Tizen::Graphics