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