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