Merge "Applied SetImageSource() API when drawing bitmap elements" 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 #endif
131
132 #if !defined (_OSP_EMUL_)
133 #define FGRAPHICS_INTERNAL_USE_DOUBLE_PIXMAP
134 #endif
135
136 enum _engineType
137 {
138         ENGINE_TYPE_SOFEWARE_X11 = 0,
139         ENGINE_TYPE_OPENGL_X11,
140         ENGINE_TYPE_ETC,
141 };
142
143 _engineType __evasEngineType = ENGINE_TYPE_SOFEWARE_X11;
144 bool __isDoublePixmapEnabled = false;
145
146 void _OnBoundsChanged(void* pData);
147
148 const int INVALID_SGL_INDEX = 0;
149 const int MAX_SGL_INDEX = 100;
150
151 class _SglInfo
152 {
153 public:
154         _SglInfo(void)
155         : sglIndex(INVALID_SGL_INDEX)
156         , display(EGL_NO_DISPLAY)
157         , surface(EGL_NO_SURFACE)
158         , context(EGL_NO_CONTEXT)
159         , config((EGLConfig)0)
160         , pBitmap(null)
161         , pObject(null)
162         , nativePixmap((EGLNativePixmapType)0)
163         , pVisualElement(null)
164         , pVisualElementSurface(null)
165         , glVersion(0)
166         , pWindow(null)
167 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
168         , pEcoreImage(null)
169         , width(0)
170         , height(0)
171 #endif
172         , isBackbuffer(true)
173         , wasShown(false)
174         , swapDone(false)
175         , isFirstSwap(true)
176         , pSecondSglInfo(null)
177         {
178         }
179
180         virtual ~_SglInfo(void)
181         {
182 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
183                 if (pEcoreImage != null)
184                 {
185                         ecore_x_image_free(pEcoreImage);
186                 }
187 #endif
188
189                 if (pObject == null)
190                 {
191                         return;
192                 }
193
194                 if (pVisualElement != null)
195                 {
196                         _VisualElementImpl* pVisualElementImpl = _VisualElementImpl::GetInstance(*pVisualElement);
197                         if (pVisualElementImpl != null)
198                         {
199                                 pVisualElementImpl->SetDestroyedCallback(null, null);
200                         }
201                 }
202
203 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
204                 _UnregisterRenderCallback(pObject);
205 #endif
206                 evas_object_del(pObject);
207                 delete pVisualElementSurface;
208                 delete pBitmap;
209
210                 bool needAllocateObject = true;
211                 if (__isDoublePixmapEnabled)
212                 {
213                         if (!isBackbuffer)
214                         {
215                                 needAllocateObject = false;
216                         }
217                 }
218                 if (needAllocateObject)
219                 {
220                         if (pVisualElement != null)
221                         {
222                                 pVisualElement->SetSurface(null);
223                         }
224                 }
225
226                 sglIndex = INVALID_SGL_INDEX;
227                 display = EGL_NO_DISPLAY;
228                 surface = EGL_NO_SURFACE;
229                 context = EGL_NO_CONTEXT;
230                 config = (EGLConfig)0;
231                 pBitmap = null;
232                 pObject = null;
233                 nativePixmap = (EGLNativePixmapType)0;
234                 pVisualElement = null;
235                 pVisualElementSurface = null;
236                 glVersion = 0;
237                 pWindow = null;
238 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
239                 pEcoreImage = null;
240                 width = 0;
241                 height = 0;
242 #endif
243                 isBackbuffer = true;
244                 wasShown = false;
245                 swapDone = false;
246                 isFirstSwap = true;
247                 pSecondSglInfo = null;
248         }
249
250 public:
251         _SglIndex sglIndex;
252         EGLDisplay display;
253         EGLSurface surface;
254         EGLContext context;
255         EGLConfig config;
256         Bitmap* pBitmap;
257         Evas_Object* pObject;
258         EGLNativePixmapType nativePixmap;
259         VisualElement* pVisualElement;
260         VisualElementSurface* pVisualElementSurface;
261         int glVersion;
262         Tizen::Ui::Window* pWindow;
263 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
264         Ecore_X_Image* pEcoreImage;
265         int width;
266         int height;
267 #endif
268         bool isBackbuffer;
269         bool wasShown;
270         bool swapDone;
271         bool isFirstSwap;
272         _SglInfo* pSecondSglInfo;
273
274 private:
275         _SglInfo(const _SglInfo& sglInfo);
276         _SglInfo& operator =(const _SglInfo& rhs);
277 };
278
279 class _PixmapInfo
280 {
281 public:
282         _PixmapInfo(void)
283         : nativePixmap((Pixmap)0)
284 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
285         , pTbmBufMgr(null)
286         , pTbmBufferObject(null)
287         , drmFd(0)
288 #endif
289         {
290         }
291
292         virtual ~_PixmapInfo(void)
293         {
294                 Display* pDisplay = (Display*)ecore_x_display_get();
295 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
296                 tbm_bo_unmap(pTbmBufferObject);
297                 tbm_bo_unref(pTbmBufferObject);
298                 if (pTbmBufMgr)
299                 {
300                         close(drmFd);
301                 }
302
303                 tbm_bufmgr_deinit(pTbmBufMgr);
304                 DRI2DestroyDrawable(pDisplay, nativePixmap);
305 #endif
306                 XFreePixmap(pDisplay, nativePixmap);
307
308                 nativePixmap = (Pixmap)0;
309 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
310                 pTbmBufMgr = null;
311                 pTbmBufferObject = null;
312                 drmFd = 0;
313 #endif
314         }
315
316 public:
317         Pixmap nativePixmap;
318 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
319         tbm_bufmgr pTbmBufMgr;
320         tbm_bo pTbmBufferObject;
321         int drmFd;
322 #endif
323 };
324
325 void _EvasObjectImageChange(_SglInfo* pSglInfo);
326
327 void
328 _OnBoundsChanged(void* pData)
329 {
330         _SglInfo* pSglInfo = dynamic_cast<_SglInfo*> ((_SglInfo*)pData);
331         SysTryReturnVoidResult(NID_GRP, pSglInfo != null
332                         && pSglInfo->sglIndex > INVALID_SGL_INDEX
333                         && pSglInfo->pVisualElement != null
334                         && pSglInfo->pWindow != null
335                         , E_INVALID_STATE, "Invalid state.");
336
337         if (pSglInfo == __pPreviousSglInfo || pSglInfo->pSecondSglInfo == __pPreviousSglInfo)
338         {
339                 __pPreviousSglInfo = null;
340         }
341
342         bool needSglMakeCurrent = false;
343         EGLDisplay eglDisplay = eglGetCurrentDisplay();
344         EGLSurface drawSurface = _SglGetCurrentSurface(EGL_DRAW);
345         EGLSurface readSurface = _SglGetCurrentSurface(EGL_READ);
346         EGLSurface eglContext = eglGetCurrentContext();
347
348         if (drawSurface != EGL_NO_SURFACE && readSurface != EGL_NO_SURFACE)
349         {
350                 needSglMakeCurrent = true;
351         }
352         else
353         {
354                 drawSurface = eglGetCurrentSurface(EGL_DRAW);
355                 readSurface = eglGetCurrentSurface(EGL_READ);
356         }
357
358         eglMakeCurrent(pSglInfo->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
359         EGLBoolean ret = eglDestroySurface(pSglInfo->display, pSglInfo->surface);
360         pSglInfo->surface = null;
361         SysTryReturnVoidResult(NID_GRP, ret == EGL_TRUE, E_OPERATION_FAILED, "eglDestroySurface failed.");
362
363 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
364                 if (pSglInfo->pEcoreImage != null)
365                 {
366                         ecore_x_image_free(pSglInfo->pEcoreImage);
367                         pSglInfo->pEcoreImage = null;
368                 }
369 #endif
370
371         FloatRectangle rect = pSglInfo->pVisualElement->GetBounds();
372         int width = int(rect.width);
373         int height = int(rect.height);
374         SysTryReturnVoidResult(NID_GRP, width > 0 && height > 0, E_OUT_OF_RANGE, "Invalid size. w:%d h:%d", width, height);
375         int widthPhysical = static_cast<int> (CoordinateSystem::ConvertToPhysicalX(rect.width));
376         int heightPhysical = static_cast<int> (CoordinateSystem::ConvertToPhysicalY(rect.height));
377         SysTryReturnVoidResult(NID_GRP, widthPhysical > 0 && heightPhysical > 0, E_OUT_OF_RANGE, "Invalid size. w:%d h:%d", widthPhysical, heightPhysical);
378
379         evas_object_image_size_set(pSglInfo->pObject, widthPhysical, heightPhysical);
380         evas_object_resize(pSglInfo->pObject, widthPhysical, heightPhysical);
381
382         delete pSglInfo->pBitmap;
383         pSglInfo->pBitmap = null;
384         std::auto_ptr <Bitmap> bitmap(new (std::nothrow) Bitmap);
385         SysTryReturnVoidResult(NID_GRP, bitmap.get() != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
386         result r = bitmap.get()->Construct(Rectangle(0, 0, width, height));
387         SysTryReturnVoidResult(NID_GRP, r == E_SUCCESS, r, "Propagating.");
388         EGLNativePixmapType nativePixmap = _CreateNativePixmap(pSglInfo->sglIndex, bitmap.get());
389         SysTryReturnVoidResult(NID_GRP, nativePixmap != (EGLNativePixmapType)0, E_OPERATION_FAILED, "Propagating.");
390         EGLSurface eglSurface = eglCreatePixmapSurface(pSglInfo->display, pSglInfo->config, nativePixmap, null);
391         SysTryReturnVoidResult(NID_GRP, eglSurface != EGL_NO_SURFACE, E_OPERATION_FAILED, "eglCreatePixmapSurface failed.");
392
393         pSglInfo->nativePixmap = nativePixmap;
394         pSglInfo->surface = eglSurface;
395         pSglInfo->isBackbuffer = true;
396         pSglInfo->wasShown = false;
397         pSglInfo->swapDone = false;
398         pSglInfo->isFirstSwap = true;
399
400         if (__isDoublePixmapEnabled)
401         {
402                 _SglInfo* pSglInfoSecond = pSglInfo->pSecondSglInfo;
403                 SysTryReturnVoidResult(NID_GRP, pSglInfoSecond != null, E_INVALID_STATE, "Invalid pSecondSglInfo.");
404
405                 eglMakeCurrent(pSglInfo->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
406                 ret = eglDestroySurface(pSglInfoSecond->display, pSglInfoSecond->surface);
407                 pSglInfoSecond->surface = null;
408                 SysTryReturnVoidResult(NID_GRP, ret == EGL_TRUE, E_OPERATION_FAILED, "eglDestroySurface failed.");
409
410                 evas_object_image_size_set(pSglInfoSecond->pObject, widthPhysical, heightPhysical);
411                 evas_object_resize(pSglInfoSecond->pObject, widthPhysical, heightPhysical);
412
413                 delete pSglInfoSecond->pBitmap;
414                 pSglInfoSecond->pBitmap = null;
415                 std::auto_ptr <Bitmap> bitmapSecond(new (std::nothrow) Bitmap);
416                 SysTryReturnVoidResult(NID_GRP, bitmapSecond.get() != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
417                 r = bitmapSecond.get()->Construct(Rectangle(0, 0, width, height));
418                 SysTryReturnVoidResult(NID_GRP, r == E_SUCCESS, r, "Propagating.");
419                 EGLNativePixmapType nativePixmap = _CreateNativePixmap(pSglInfoSecond->sglIndex, bitmapSecond.get());
420                 SysTryReturnVoidResult(NID_GRP, nativePixmap != (EGLNativePixmapType)0, E_OPERATION_FAILED, "Propagating.");
421                 EGLSurface eglSurface = eglCreatePixmapSurface(pSglInfoSecond->display, pSglInfoSecond->config, nativePixmap, null);
422                 SysTryReturnVoidResult(NID_GRP, eglSurface != EGL_NO_SURFACE, E_OPERATION_FAILED, "eglCreatePixmapSurface failed.");
423
424                 pSglInfoSecond->nativePixmap = nativePixmap;
425                 pSglInfoSecond->surface = eglSurface;
426                 pSglInfoSecond->pBitmap = bitmapSecond.release();
427                 pSglInfoSecond->isBackbuffer = true;
428                 pSglInfoSecond->wasShown = false;
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 if (engineName.Contains(String("software_x11")))
726                 {
727                         return ENGINE_TYPE_SOFEWARE_X11;
728                 }
729                 else
730                 {
731                         pString = elm_config_engine_get();
732                         String engineName(pString);
733                         SysLog(NID_GRP, "system evas backend : %s", pString);
734                         if (engineName.Contains(String("opengl_x11")))
735                         {
736                                 return ENGINE_TYPE_OPENGL_X11;
737                         }
738                         else
739                         {
740                                 return ENGINE_TYPE_SOFEWARE_X11;
741                         }
742                 }
743         }
744         else
745         {
746                 Evas* pEvas = evas_object_evas_get(pObject);
747                 if (pEvas == null)
748                 {
749                         SysLogException(NID_GRP, E_OPERATION_FAILED, "Getting pEvas failed.");
750                         return ENGINE_TYPE_SOFEWARE_X11;
751                 }
752
753                 Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
754                 if (pEcoreEvas == null)
755                 {
756                         SysLogException(NID_GRP, E_OPERATION_FAILED, "Getting pEcoreEvas failed.");
757                         return ENGINE_TYPE_SOFEWARE_X11;
758                 }
759
760                 const char* pString = ecore_evas_engine_name_get(pEcoreEvas);
761                 String engineName(pString);
762                 SysLog(NID_GRP, "evas backend : %s", pString);
763
764                 if (engineName.Contains(String("opengl_x11")))
765                 {
766                         return ENGINE_TYPE_OPENGL_X11;
767                 }
768                 else if (engineName.Contains(String("software_x11")))
769                 {
770                         return ENGINE_TYPE_SOFEWARE_X11;
771                 }
772                 else
773                 {
774                         return ENGINE_TYPE_ETC;
775                 }
776         }
777 }
778
779 void
780 _EvasObjectImageChange(_SglInfo* pSglInfo)
781 {
782         if(__evasEngineType == ENGINE_TYPE_SOFEWARE_X11 || __evasEngineType == ENGINE_TYPE_OPENGL_X11)
783         {
784                 Evas* pEvas = evas_object_evas_get(pSglInfo->pObject);
785                 if (pEvas == null)
786                 {
787                         SysLogException(NID_GRP, E_OPERATION_FAILED, "Getting pEvas failed.");
788                         return;
789                 }
790
791                 Evas_Native_Surface nativeSurface = {0, };
792                 nativeSurface.type = EVAS_NATIVE_SURFACE_X11;
793                 nativeSurface.version = EVAS_NATIVE_SURFACE_VERSION;
794                 nativeSurface.data.x11.pixmap = (unsigned long)pSglInfo->nativePixmap;
795                 nativeSurface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
796                 evas_object_image_native_surface_set(pSglInfo->pObject, &nativeSurface);
797         }
798         else
799         {
800                 BufferInfo bufferInfo;
801                 pSglInfo->pBitmap->Lock(bufferInfo);
802                 evas_object_image_data_set(pSglInfo->pObject, bufferInfo.pPixels);
803                 pSglInfo->pBitmap->Unlock();
804         }
805 }
806
807 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
808 void
809 _PostRenderCallback(Ecore_Evas* ee)
810 {
811         if (__pPreviousSglInfo != null)
812         {
813                 EGLDisplay display = __pPreviousSglInfo->display;
814                 EGLSurface surface = __pPreviousSglInfo->surface;
815                 EGLContext context = __pPreviousSglInfo->context;
816
817                 if (__isDoublePixmapEnabled)
818                 {
819                         _SglInfo* pBackSglInfo = null;
820                         _SglInfo* pFrontSglInfo = null;
821
822                         if (__pPreviousSglInfo->isBackbuffer)
823                         {
824                                 pBackSglInfo = __pPreviousSglInfo;
825                                 pFrontSglInfo = __pPreviousSglInfo->pSecondSglInfo;
826                         }
827                         else
828                         {
829                                 pBackSglInfo = __pPreviousSglInfo->pSecondSglInfo;
830                                 pFrontSglInfo = __pPreviousSglInfo;
831                         }
832
833                         if (!pBackSglInfo->wasShown && __pPreviousSglInfo->pVisualElement != null)
834                         {
835                                 __pPreviousSglInfo->pVisualElement->SetSurface(pFrontSglInfo->pVisualElementSurface);
836                                 evas_object_image_pixels_dirty_set(pFrontSglInfo->pObject, EINA_TRUE);
837                                 evas_object_hide(pBackSglInfo->pObject);
838
839                                 pBackSglInfo->wasShown = true;
840                                 pFrontSglInfo->swapDone = true;
841                         }
842
843                         surface = pBackSglInfo->surface;
844                 }
845
846                 EGLBoolean ret = eglMakeCurrent(display, surface, surface, context);
847                 SysTryLog(NID_GRP, ret == EGL_TRUE, "fail to restore previous surface and context. %#x %#x %#x %#x egl error:%#x"
848                                 , (unsigned int)display
849                                 , (unsigned int)surface
850                                 , (unsigned int)surface
851                                 , (unsigned int)context
852                                 , (unsigned int)eglGetError());
853         }
854 }
855
856 void
857 _SaveCurrentContext(_SglInfo* pSglInfo)
858 {
859         __pPreviousSglInfo = pSglInfo;
860 }
861
862 void
863 _RegisterRenderCallback(Evas_Object* pObject)
864 {
865         if (__evasEngineType == ENGINE_TYPE_OPENGL_X11 && pObject != null)
866         {
867                 if (__registerCallbackCount == 0)
868                 {
869                         Evas* pEvas = evas_object_evas_get(pObject);
870                         if (pEvas == null)
871                         {
872                                 return;
873                         }
874
875                         Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
876                         if (pEcoreEvas == null)
877                         {
878                                 return;
879                         }
880
881                         ecore_evas_callback_post_render_set(pEcoreEvas, _PostRenderCallback);
882                 }
883                 __registerCallbackCount++;
884         }
885 }
886
887 void
888 _UnregisterRenderCallback(Evas_Object* pObject)
889 {
890         if (__evasEngineType == ENGINE_TYPE_OPENGL_X11 && pObject != null)
891         {
892                 __registerCallbackCount--;
893
894                 if (__registerCallbackCount == 0)
895                 {
896                         Evas* pEvas = evas_object_evas_get(pObject);
897                         if (pEvas == null)
898                         {
899                                 return;
900                         }
901
902                         Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
903                         if (pEcoreEvas == null)
904                         {
905                                 return;
906                         }
907
908                         ecore_evas_callback_post_render_set(pEcoreEvas, NULL);
909                 }
910         }
911 }
912 #endif //#if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
913
914 }
915
916 #ifdef __cplusplus
917 extern "C"
918 {
919 #endif
920
921 EGLint
922 _SglGetError()
923 {
924         return eglGetError();
925 }
926
927 EGLDisplay
928 _SglGetDisplay(EGLNativeDisplayType displayId)
929 {
930         if (displayId == (EGLNativeDisplayType) EGL_DEFAULT_DISPLAY)
931         {
932                 return eglGetDisplay((EGLNativeDisplayType) ecore_x_display_get());
933         }
934
935         return eglGetDisplay((EGLNativeDisplayType) displayId);
936 }
937
938 EGLBoolean
939 _SglInitialize(EGLDisplay dpy, EGLint* pMajor, EGLint* pMinor)
940 {
941         __evasEngineType = _GetEvasEngineType(null);
942         return eglInitialize(dpy, pMajor, pMinor);
943 }
944
945 EGLBoolean
946 _SglTerminate(EGLDisplay dpy)
947 {
948         _GlesInterfaceTerminate_1();
949         _GlesInterfaceTerminate_2();
950
951         _SglInfoTableManipulator::GetInstance()->DestroySglInfoTable();
952
953         if (__evasEngineType != ENGINE_TYPE_OPENGL_X11)
954         {
955                 eglTerminate(dpy);
956         }
957
958 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
959         __registerCallbackCount = 0;
960         __pPreviousSglInfo = null;
961 #endif
962
963
964         return EGL_TRUE;
965 }
966
967 const char*
968 _SglQueryString(EGLDisplay dpy, EGLint name)
969 {
970         return eglQueryString(dpy, name);
971 }
972
973 EGLBoolean
974 _SglGetConfigs(EGLDisplay dpy, EGLConfig* pConfigs, EGLint configSize, EGLint* pNumConfig)
975 {
976         return eglGetConfigs(dpy, pConfigs, configSize, pNumConfig);
977 }
978
979 EGLBoolean
980 _SglChooseConfig(EGLDisplay dpy, const EGLint* pAttribList, EGLConfig* pConfigs, EGLint configSize, EGLint* pNumConfig)
981 {
982         return eglChooseConfig(dpy, pAttribList, pConfigs, configSize, pNumConfig);
983 }
984
985 EGLBoolean
986 _SglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* pValue)
987 {
988         return eglGetConfigAttrib(dpy, config, attribute, pValue);
989 }
990
991 EGLSurface
992 _SglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* pAttribList)
993 {
994         _SglIndex sglIndex = INVALID_SGL_INDEX;
995         Object* pObj = (Object*)win;
996         VisualElement* pVisualElement = dynamic_cast<VisualElement*> (pObj);
997         Tizen::Ui::Control* pControl = dynamic_cast<Tizen::Ui::Control*> (pObj);
998 #if 0//!defined(_OSP_EMUL_)
999         Tizen::Ui::Controls::Frame* pFrame = dynamic_cast<Tizen::Ui::Controls::Frame*> (pControl);
1000 #endif
1001         SysTryReturn(NID_GRP, pControl != null || pVisualElement != null, EGL_NO_SURFACE, E_INVALID_ARG, "Invalid NativeWindow.");
1002         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1003
1004 #if 0//!defined(_OSP_EMUL_)
1005         if (pFrame != null && _GetEvasEngineType(null) != ENGINE_TYPE_OPENGL_X11)
1006         {
1007                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(*pControl);
1008                 _WindowImpl* pWindowImpl = dynamic_cast<_WindowImpl*> (pControlImpl);
1009                 SysTryReturn(NID_GRP, pWindowImpl != null, EGL_NO_SURFACE, E_INVALID_STATE, "Invalid window state.");
1010
1011                 EGLNativeWindowType nativeWindow = (EGLNativeWindowType)pWindowImpl->GetNativeHandle();
1012                 sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1013                 SysTryReturn(NID_GRP, sglIndex > INVALID_SGL_INDEX, EGL_NO_SURFACE, E_OPERATION_FAILED, "Invalid SglIndex.");
1014
1015                 EGLSurface windowSurface = eglCreateWindowSurface(dpy, config, nativeWindow, pAttribList);
1016                 if (windowSurface == EGL_NO_SURFACE)
1017                 {
1018                         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1019                         sglIndex = 0;
1020                 }
1021                 else
1022                 {
1023                         VisualElement* pVisualElement = pControlImpl->GetCore().GetVisualElement();
1024                         if (pVisualElement == null)
1025                         {
1026                                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1027                                 return EGL_NO_SURFACE;
1028                         }
1029
1030                         _VisualElementImpl* pVisualElementImpl = _VisualElementImpl::GetInstance(*pVisualElement);
1031                         if (pVisualElementImpl == null)
1032                         {
1033                                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1034                                 return EGL_NO_SURFACE;
1035                         }
1036
1037                         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1038
1039                         pSglInfo->surface = windowSurface;
1040
1041                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1042                 }
1043
1044                 return (EGLSurface)sglIndex;
1045         }
1046         else
1047 #endif //#if !defined(_OSP_EMUL_)
1048         {
1049                 result r = E_SUCCESS;
1050
1051                 if (pVisualElement == null)
1052                 {
1053                         pVisualElement = pControl->GetVisualElement();
1054                 }
1055                 SysTryReturn(NID_GRP, pVisualElement != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1056
1057                 _VisualElementImpl* pVisualElementImpl = _VisualElementImpl::GetInstance(*pVisualElement);
1058                 SysTryReturn(NID_GRP, pVisualElementImpl != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1059
1060                 FloatRectangle rect = pVisualElement->GetBounds();
1061                 int width = int(rect.width);
1062                 int height = int(rect.height);
1063                 SysTryReturn(NID_GRP, width > 0 && height > 0, EGL_NO_SURFACE, E_OUT_OF_RANGE, "Invalid size. w:%d h:%d", width, height);
1064
1065                 Control* pFrame = pControl;
1066                 Control* pTemp = pFrame->GetParent();
1067                 while(pTemp != null)
1068                 {
1069                         pFrame = pTemp;
1070                         pTemp = pTemp->GetParent();
1071                 }
1072
1073                 Tizen::Ui::Window* pWindow = dynamic_cast<Tizen::Ui::Window*> (pFrame);
1074                 SysTryReturn(NID_GRP, pWindow != null, EGL_NO_SURFACE, E_INVALID_STATE, "Invalid window.");
1075
1076                 VisualElementSurface* pVisualElementSurface = pVisualElement->GetSurfaceN();
1077                 SysTryReturn(NID_GRP, pVisualElementSurface != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1078
1079                 _VisualElementSurfaceImpl* pVisualElementSurfaceImpl = _VisualElementSurfaceImpl::GetInstance(*pVisualElementSurface);
1080                 if (pVisualElementSurfaceImpl == null)
1081                 {
1082                         SysLogException(NID_GRP, E_OPERATION_FAILED, "Propagating.");
1083                         delete pVisualElementSurface;
1084                         return EGL_NO_SURFACE;
1085                 }
1086
1087                 Evas_Object* pObject = (Evas_Object*)pVisualElementSurfaceImpl->GetNativeHandle();
1088                 delete pVisualElementSurface;
1089
1090                 Evas* pEvas = evas_object_evas_get(pObject);
1091                 pObject = evas_object_image_filled_add(pEvas);
1092                 SysTryReturn(NID_GRP, pObject != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Invalid object.");
1093
1094                 int widthPhysical = static_cast<int> (CoordinateSystem::ConvertToPhysicalX(rect.width));
1095                 int heightPhysical = static_cast<int> (CoordinateSystem::ConvertToPhysicalY(rect.height));
1096
1097                 evas_object_image_alpha_set(pObject, EINA_TRUE);
1098                 evas_object_image_size_set(pObject, widthPhysical, heightPhysical);
1099                 evas_object_resize(pObject, widthPhysical, heightPhysical);
1100                 evas_object_hide(pObject);
1101
1102                 pVisualElementSurface = _VisualElementSurfaceImpl::CreateSurfaceUsingExistingObjectN(
1103                                 *pWindow->GetDisplayContext(), (Handle)pObject, Dimension(width, height));
1104                 SysTryReturn(NID_GRP, pVisualElementSurface != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1105
1106                 std::auto_ptr <Bitmap> bitmap(new (std::nothrow) Bitmap);
1107                 SysTryReturn(NID_GRP, bitmap.get() != null, EGL_NO_SURFACE, E_OUT_OF_MEMORY, "The memory is insufficient.");
1108
1109                 r = bitmap.get()->Construct(Rectangle(0, 0, width, height));
1110                 SysTryReturn(NID_GRP, r == E_SUCCESS, EGL_NO_SURFACE, r, "Propagating.");
1111
1112                 sglIndex = (_SglIndex)_SglCreatePixmapSurface(dpy, config, (EGLNativePixmapType)bitmap.get(), null);
1113                 SysTryReturn(NID_GRP, sglIndex > INVALID_SGL_INDEX, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1114
1115                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1116                 pSglInfo->sglIndex = sglIndex;
1117                 pSglInfo->display = dpy;
1118                 pSglInfo->config = config;
1119                 pSglInfo->pVisualElement = pVisualElement;
1120                 pSglInfo->pWindow = pWindow;
1121                 pSglInfo->pObject = pObject;
1122                 pSglInfo->pVisualElementSurface = pVisualElementSurface;
1123                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1124
1125                 __evasEngineType = _GetEvasEngineType(pObject);
1126
1127 #if defined (FGRAPHICS_INTERNAL_USE_DOUBLE_PIXMAP)
1128                 if (__evasEngineType == ENGINE_TYPE_OPENGL_X11)
1129                 {
1130                         __isDoublePixmapEnabled = true;
1131                 }
1132                 else
1133                 {
1134                         __isDoublePixmapEnabled = false;
1135                 }
1136 #else
1137                 __isDoublePixmapEnabled = false;
1138 #endif
1139
1140                 if (__isDoublePixmapEnabled)
1141                 {
1142                         pObject = evas_object_image_filled_add(pEvas);
1143                         SysTryReturn(NID_GRP, pObject != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Invalid object.");
1144
1145                         evas_object_image_alpha_set(pObject, EINA_TRUE);
1146                         evas_object_image_size_set(pObject, widthPhysical, heightPhysical);
1147                         evas_object_resize(pObject, widthPhysical, heightPhysical);
1148                         evas_object_hide(pObject);
1149
1150                         pVisualElementSurface = _VisualElementSurfaceImpl::CreateSurfaceUsingExistingObjectN(
1151                                         *pWindow->GetDisplayContext(), (Handle)pObject, Dimension(width, height));
1152                         SysTryReturn(NID_GRP, pSglInfo->pVisualElementSurface != null, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1153
1154                         delete pSglInfo->pBitmap;
1155                         pSglInfo->pBitmap = null;
1156
1157                         std::auto_ptr <Bitmap> bitmapSecond(new (std::nothrow) Bitmap);
1158                         SysTryReturn(NID_GRP, bitmapSecond.get() != null, EGL_NO_SURFACE, E_OUT_OF_MEMORY, "The memory is insufficient.");
1159
1160                         r = bitmapSecond.get()->Construct(Rectangle(0, 0, width, height));
1161                         SysTryReturn(NID_GRP, r == E_SUCCESS, EGL_NO_SURFACE, r, "Propagating.");
1162
1163                         sglIndex = (_SglIndex)_SglCreatePixmapSurface(dpy, config, (EGLNativePixmapType)bitmapSecond.get(), null);
1164                         SysTryReturn(NID_GRP, sglIndex > INVALID_SGL_INDEX, EGL_NO_SURFACE, E_OPERATION_FAILED, "Propagating.");
1165
1166                         _SglInfo* pSglInfoSecond = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1167                         pSglInfoSecond->sglIndex = sglIndex;
1168                         pSglInfoSecond->display = dpy;
1169                         pSglInfoSecond->config = config;
1170                         pSglInfoSecond->pVisualElement = pVisualElement;
1171                         pSglInfoSecond->pWindow = pWindow;
1172                         pSglInfoSecond->pObject = pObject;
1173                         pSglInfoSecond->pVisualElementSurface = pVisualElementSurface;
1174                         pSglInfoSecond->swapDone = true;
1175                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1176
1177                         pSglInfo->pSecondSglInfo = pSglInfoSecond;
1178                         pSglInfoSecond->pSecondSglInfo = pSglInfo;
1179
1180                         pSglInfoSecond->pBitmap = bitmapSecond.release();
1181                         _EvasObjectImageChange(pSglInfoSecond);
1182                 }
1183                 else
1184                 {
1185                         pVisualElement->SetSurface(pSglInfo->pVisualElementSurface);
1186                 }
1187
1188                 pSglInfo->pBitmap = bitmap.release();
1189                 _EvasObjectImageChange(pSglInfo);
1190
1191                 pVisualElementImpl->SetBoundsChangedCallback(_OnBoundsChanged, pSglInfo);
1192                 pVisualElementImpl->SetDestroyedCallback(_OnDestroyed, pSglInfo);
1193 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
1194                 _RegisterRenderCallback(pSglInfo->pObject);
1195 #endif
1196                 return (EGLSurface)pSglInfo->sglIndex;
1197         }
1198 }
1199
1200 EGLSurface
1201 _SglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* pAttribList)
1202 {
1203         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1204         _SglIndex sglIndex = INVALID_SGL_INDEX;
1205
1206         sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1207         if (sglIndex <= INVALID_SGL_INDEX)
1208         {
1209                 SysLog(NID_GRP, "_SglCreatePbufferSurface failed!! dpy:%#x config:%#x pAttribList:%#x",
1210                                 (unsigned int)dpy, (unsigned int)config, (unsigned int)pAttribList);
1211
1212                 return eglCreatePbufferSurface(EGL_NO_DISPLAY, config, pAttribList);
1213         }
1214
1215         EGLSurface pbufferSurface = eglCreatePbufferSurface(dpy, config, pAttribList);
1216         if (pbufferSurface == EGL_NO_SURFACE)
1217         {
1218                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1219                 sglIndex = 0;
1220         }
1221         else
1222         {
1223                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1224
1225                 pSglInfo->surface = pbufferSurface;
1226
1227                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1228         }
1229
1230         return (EGLSurface)sglIndex;
1231 }
1232
1233 _OSP_LOCAL_ EGLNativePixmapType
1234 _CreateNativePixmap(_SglIndex sglIndex, Tizen::Graphics::Bitmap* pBitmap)
1235 {
1236         int width = 0;
1237         int height = 0;
1238         int bitsPerPixel = 0;
1239         Display* pNativeDisplay = null;
1240         Drawable nativeWindow = 0;
1241         result r = E_FAILURE;
1242         Tizen::Graphics::BufferInfo bufferInfo;
1243         _PixmapInfo* pPixmapInfo = null;
1244 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1245         unsigned int attachments[] = { DRI2BufferFrontLeft };
1246         char* pDeviceName = null;
1247         char* pDriverName = null;
1248         DRI2Buffer* pDri2Buffer = null;
1249         int dri2Width = 0;
1250         int dri2Height = 0;
1251         int dri2BufferCount = 0;
1252         tbm_bo_handle tbmData = { null, };
1253
1254         Bool ret = False;
1255         drm_magic_t magic = 0;
1256 #endif
1257         _SglInfo* pSglInfo = null;
1258         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1259
1260         pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1261         if (pBitmap == null || sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1262         {
1263                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1264                 goto CATCH_01;
1265         }
1266         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1267
1268         r = pBitmap->Lock(bufferInfo);
1269         if (r != E_SUCCESS)
1270         {
1271                 goto CATCH_01;
1272         }
1273
1274         width = bufferInfo.width;
1275         height = bufferInfo.height;
1276         bitsPerPixel = bufferInfo.bitsPerPixel;
1277
1278         r = pBitmap->Unlock();
1279         if (r != E_SUCCESS || width <= 0 || height <= 0 || bitsPerPixel <= 0)
1280         {
1281                 goto CATCH_01;
1282         }
1283
1284         pNativeDisplay = (Display*) ecore_x_display_get();
1285         nativeWindow = DefaultRootWindow(pNativeDisplay);
1286
1287         pPixmapInfo = new (std::nothrow) _PixmapInfo;
1288         if (pPixmapInfo == null)
1289         {
1290                 goto CATCH_01;
1291         }
1292
1293         pPixmapInfo->nativePixmap = XCreatePixmap(pNativeDisplay, nativeWindow, width, height,
1294                         ecore_x_default_depth_get(pNativeDisplay, ecore_x_default_screen_get()));
1295         if (pPixmapInfo->nativePixmap == (Pixmap)0)
1296         {
1297                 goto CATCH_02;
1298         }
1299
1300 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1301         DRI2CreateDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1302         XSync(pNativeDisplay, False);
1303
1304         ret = DRI2Connect(pNativeDisplay, nativeWindow, &pDriverName, &pDeviceName);
1305         free(pDriverName);
1306         if (!ret || pDeviceName == null)
1307         {
1308                 goto CATCH_03;
1309         }
1310
1311         pPixmapInfo->drmFd = open(pDeviceName, O_RDWR);
1312
1313         free(pDeviceName);
1314         if (pPixmapInfo->drmFd < 0)
1315         {
1316                 goto CATCH_03;
1317         }
1318
1319         drmGetMagic(pPixmapInfo->drmFd, &magic);
1320         ret = DRI2Authenticate(pNativeDisplay, nativeWindow, (unsigned int)magic);
1321         if (!ret)
1322         {
1323                 goto CATCH_04;
1324         }
1325
1326         pPixmapInfo->pTbmBufMgr = tbm_bufmgr_init(pPixmapInfo->drmFd);
1327         if (pPixmapInfo->pTbmBufMgr == null)
1328         {
1329                 goto CATCH_04;
1330         }
1331
1332         pDri2Buffer = DRI2GetBuffers(pNativeDisplay, pPixmapInfo->nativePixmap, &dri2Width, &dri2Height, attachments, 1, &dri2BufferCount);
1333         if (pDri2Buffer == null)
1334         {
1335                 goto CATCH_05;
1336         }
1337
1338         pPixmapInfo->pTbmBufferObject = tbm_bo_import(pPixmapInfo->pTbmBufMgr, pDri2Buffer->name);
1339         free(pDri2Buffer);
1340         if (pPixmapInfo->pTbmBufferObject == null)
1341         {
1342                 goto CATCH_05;
1343         }
1344
1345         tbmData = tbm_bo_get_handle(pPixmapInfo->pTbmBufferObject, TBM_DEVICE_CPU);
1346         if (tbmData.ptr == null)
1347         {
1348                 goto CATCH_06;
1349         }
1350
1351         r = Tizen::Graphics::_BitmapTool::ChangeBuffer(*pBitmap, tbmData.ptr, width * bitsPerPixel / 8,
1352                         _PixmapSurfaceDestroyCallback, (void*)pPixmapInfo);
1353         if (r != E_SUCCESS)
1354         {
1355                 goto CATCH_06;
1356         }
1357
1358         if (!Tizen::Graphics::_BitmapTool::SetCallback(*pBitmap, _PixmapSurfaceDestroyCallback, pPixmapInfo,
1359                         _PixmapLockCallBack, pPixmapInfo->pTbmBufferObject,_PixmapUnlockCallBack, pPixmapInfo->pTbmBufferObject))
1360         {
1361                 goto CATCH_06;
1362         }
1363
1364 #else
1365 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
1366         {
1367                 pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1368
1369                 pSglInfo->pEcoreImage = ecore_x_image_new(width
1370                         , height
1371                         , ecore_x_default_visual_get(pNativeDisplay, ecore_x_default_screen_get())
1372                         , ecore_x_default_depth_get(pNativeDisplay, ecore_x_default_screen_get()));
1373
1374                 if (pSglInfo->pEcoreImage == null)
1375                 {
1376                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1377                         goto CATCH_06;
1378                 }
1379
1380                 ecore_x_image_get(pSglInfo->pEcoreImage
1381                         , pPixmapInfo->nativePixmap, 0, 0, 0, 0
1382                         , width
1383                         , height);
1384
1385                 int bpl = 0;
1386                 int rows = 0;
1387                 int bpp = 0;
1388
1389                 void* pSource = ecore_x_image_data_get(pSglInfo->pEcoreImage, &bpl, &rows, &bpp);
1390
1391                 r = Tizen::Graphics::_BitmapTool::ChangeBuffer(*pBitmap, pSource, width * bitsPerPixel / 8,
1392                 _PixmapSurfaceDestroyCallback, (void*)pPixmapInfo);
1393                 if (r != E_SUCCESS)
1394                 {
1395                         ecore_x_image_free(pSglInfo->pEcoreImage);
1396                         pSglInfo->pEcoreImage = null;
1397                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1398
1399                         SysLog(NID_GRP, "change buffer failed! pSource %#x %d %d %d", (unsigned int)pSource, bpl, rows, bpp);
1400                         goto CATCH_06;
1401                 }
1402
1403                 pSglInfo->width = width;
1404                 pSglInfo->height = height;
1405
1406                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1407         }
1408 #endif //#if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
1409 #endif //#if defined(FGRAPHICS_INTERNAL_USE_DRM)
1410
1411         pBitmap->Lock(bufferInfo);
1412         memset(bufferInfo.pPixels, 0, bufferInfo.pitch * bufferInfo.height);
1413         pBitmap->Unlock();
1414
1415         return (EGLNativePixmapType)pPixmapInfo->nativePixmap;
1416
1417 CATCH_06:
1418 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1419         tbm_bo_unmap(pPixmapInfo->pTbmBufferObject);
1420         tbm_bo_unref(pPixmapInfo->pTbmBufferObject);
1421         //fall through
1422
1423 CATCH_05:
1424         tbm_bufmgr_deinit(pPixmapInfo->pTbmBufMgr);
1425         //fall through
1426
1427 CATCH_04:
1428         close(pPixmapInfo->drmFd);
1429         //fall through
1430
1431 CATCH_03:
1432         DRI2DestroyDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1433 #endif
1434         XFreePixmap(pNativeDisplay, pPixmapInfo->nativePixmap);
1435         //fall through
1436
1437 CATCH_02:
1438         delete pPixmapInfo;
1439         //fall through
1440
1441 CATCH_01:
1442         SysLog(NID_GRP, "_CreateNativePixmap failed!! pBitmap:%#x", (unsigned int)pBitmap);
1443         return (EGLNativePixmapType)0;
1444 }
1445
1446 _OSP_LOCAL_ EGLNativePixmapType
1447 _CreateNativePixmapEx(Tizen::Graphics::Bitmap* pBitmap, Tizen::Graphics::BufferInfo bufferInfo)
1448 {
1449         int width = 0;
1450         int height = 0;
1451         int bitsPerPixel = 0;
1452         Display* pNativeDisplay = null;
1453         Drawable nativeWindow = 0;
1454         Tizen::Graphics::_BitmapImpl* pBitmapImpl = null;
1455         _PixmapInfo* pPixmapInfo = null;
1456 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1457         unsigned int attachments[] = { DRI2BufferFrontLeft };
1458         char* pDeviceName = null;
1459         char* pDriverName = null;
1460         DRI2Buffer* pDri2Buffer = null;
1461         int dri2Width = 0;
1462         int dri2Height = 0;
1463         int dri2BufferCount = 0;
1464         tbm_bo_handle tbmData = { null, };
1465
1466         Bool ret = False;
1467         result r = E_FAILURE;
1468         drm_magic_t magic = 0;
1469 #endif
1470         if (pBitmap == null)
1471         {
1472                 goto CATCH_01;
1473         }
1474
1475         pBitmapImpl = Tizen::Graphics::_BitmapImpl::GetInstance(*pBitmap);
1476         if (pBitmapImpl == null)
1477         {
1478                 goto CATCH_01;
1479         }
1480
1481         width = bufferInfo.width;
1482         height = bufferInfo.height;
1483         bitsPerPixel = bufferInfo.bitsPerPixel;
1484
1485         if (width <= 0 || height <= 0 || bitsPerPixel <= 0)
1486         {
1487                 goto CATCH_01;
1488         }
1489
1490         pNativeDisplay = (Display*) ecore_x_display_get();
1491         nativeWindow = DefaultRootWindow(pNativeDisplay);
1492
1493         pPixmapInfo = new (std::nothrow) _PixmapInfo;
1494         if (pPixmapInfo == null)
1495         {
1496                 goto CATCH_01;
1497         }
1498
1499         pPixmapInfo->nativePixmap = XCreatePixmap(pNativeDisplay, nativeWindow, width, height
1500                         , bitsPerPixel);
1501         if (pPixmapInfo->nativePixmap == (Pixmap)0)
1502         {
1503                 goto CATCH_02;
1504         }
1505
1506 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1507         DRI2CreateDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1508         XSync(pNativeDisplay, False);
1509
1510         ret = DRI2Connect(pNativeDisplay, nativeWindow, &pDriverName, &pDeviceName);
1511         free(pDriverName);
1512         if (!ret || pDeviceName == null)
1513         {
1514                 goto CATCH_03;
1515         }
1516
1517         pPixmapInfo->drmFd = open(pDeviceName, O_RDWR);
1518         free(pDeviceName);
1519         if (pPixmapInfo->drmFd < 0)
1520         {
1521                 goto CATCH_03;
1522         }
1523
1524         drmGetMagic(pPixmapInfo->drmFd, &magic);
1525         ret = DRI2Authenticate(pNativeDisplay, nativeWindow, (unsigned int)magic);
1526         if (!ret)
1527         {
1528                 goto CATCH_04;
1529         }
1530
1531         pPixmapInfo->pTbmBufMgr = tbm_bufmgr_init(pPixmapInfo->drmFd);
1532         if (pPixmapInfo->pTbmBufMgr == null)
1533         {
1534                 goto CATCH_04;
1535         }
1536
1537         pDri2Buffer = DRI2GetBuffers(pNativeDisplay, pPixmapInfo->nativePixmap, &dri2Width, &dri2Height, attachments, 1, &dri2BufferCount);
1538         if (pDri2Buffer == null)
1539         {
1540                 goto CATCH_05;
1541         }
1542
1543         pPixmapInfo->pTbmBufferObject = tbm_bo_import(pPixmapInfo->pTbmBufMgr, pDri2Buffer->name);
1544         free(pDri2Buffer);
1545         if (pPixmapInfo->pTbmBufferObject == null)
1546         {
1547                 goto CATCH_05;
1548         }
1549
1550         tbmData = tbm_bo_get_handle(pPixmapInfo->pTbmBufferObject, TBM_DEVICE_CPU);
1551         if (tbmData.ptr == null)
1552         {
1553                 goto CATCH_06;
1554         }
1555         bufferInfo.pPixels = tbmData.ptr;
1556
1557         bufferInfo.bitsPerPixel = 32;
1558         bufferInfo.pixelFormat = PIXEL_FORMAT_ARGB8888;
1559         bufferInfo.pitch = bufferInfo.width * bufferInfo.bitsPerPixel / 8;
1560         memset(bufferInfo.pPixels, 0, bufferInfo.pitch * bufferInfo.height);
1561         r = pBitmapImpl->Construct(bufferInfo);
1562         if (r != E_SUCCESS)
1563         {
1564                 goto CATCH_06;
1565         }
1566
1567         if (!Tizen::Graphics::_BitmapTool::SetCallback(*pBitmap
1568                         , _PixmapSurfaceDestroyCallback, pPixmapInfo
1569                         , _PixmapLockCallBack, pPixmapInfo->pTbmBufferObject
1570                         ,_PixmapUnlockCallBack, pPixmapInfo->pTbmBufferObject))
1571         {
1572                 goto CATCH_06;
1573         }
1574 #endif //#if defined(FGRAPHICS_INTERNAL_USE_DRM)
1575
1576         return (EGLNativePixmapType)pPixmapInfo->nativePixmap;
1577
1578 #if defined(FGRAPHICS_INTERNAL_USE_DRM)
1579 CATCH_06:
1580         tbm_bo_unmap(pPixmapInfo->pTbmBufferObject);
1581         tbm_bo_unref(pPixmapInfo->pTbmBufferObject);
1582         //fall through
1583
1584 CATCH_05:
1585         tbm_bufmgr_deinit(pPixmapInfo->pTbmBufMgr);
1586         //fall through
1587
1588 CATCH_04:
1589         close(pPixmapInfo->drmFd);
1590         //fall through
1591
1592 CATCH_03:
1593         DRI2DestroyDrawable(pNativeDisplay, pPixmapInfo->nativePixmap);
1594         XFreePixmap(pNativeDisplay, pPixmapInfo->nativePixmap);
1595         //fall through
1596 #endif
1597
1598 CATCH_02:
1599         delete pPixmapInfo;
1600         //fall through
1601
1602 CATCH_01:
1603         SysLog(NID_GRP, "_CreateNativePixmap failed!! pBitmap:%#x", (unsigned int)pBitmap);
1604         return (EGLNativePixmapType)0;
1605 }
1606
1607 EGLSurface
1608 _SglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* pAttribList)
1609 {
1610         _SglIndex sglIndex = INVALID_SGL_INDEX;
1611         Tizen::Graphics::Bitmap* pBitmap = dynamic_cast<Tizen::Graphics::Bitmap*>((Tizen::Graphics::Bitmap*)pixmap);
1612         EGLNativePixmapType eglNativePixmap = 0;
1613         EGLSurface pixmapSurface = EGL_NO_SURFACE;
1614         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1615
1616         if (pBitmap == null)
1617         {
1618                 goto CATCH_01;
1619         }
1620
1621         sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1622         if (sglIndex <= INVALID_SGL_INDEX)
1623         {
1624                 goto CATCH_01;
1625         }
1626
1627         eglNativePixmap = _CreateNativePixmap(sglIndex, pBitmap);
1628         if (eglNativePixmap == 0)
1629         {
1630                 goto CATCH_02;
1631         }
1632
1633         pixmapSurface = eglCreatePixmapSurface(dpy, config, eglNativePixmap, pAttribList);
1634         if (pixmapSurface == EGL_NO_SURFACE)
1635         {
1636                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1637                 sglIndex = 0;
1638         }
1639         else
1640         {
1641                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1642
1643                 pSglInfo->nativePixmap = eglNativePixmap;
1644                 pSglInfo->surface = pixmapSurface;
1645
1646                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1647         }
1648
1649         return (EGLSurface)sglIndex;
1650
1651 CATCH_02:
1652         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1653         //fall through
1654
1655 CATCH_01:
1656         SysLog(NID_GRP, "_SglCreatePixmapSurface failed!! dpy:%#x config:%#x pixmap:%#x pAttribList:%#x",
1657                         (unsigned int)dpy, (unsigned int)config, (unsigned int)pixmap, (unsigned int)pAttribList);
1658         return eglCreatePixmapSurface(EGL_NO_DISPLAY, config, (EGLNativePixmapType) 0, pAttribList);
1659 }
1660
1661 EGLBoolean
1662 _SglDestroySurface(EGLDisplay dpy, EGLSurface surface)
1663 {
1664         EGLBoolean ret = EGL_FALSE;
1665         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1666
1667         _SglIndex sglIndex = (_SglIndex)surface;
1668         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1669
1670         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1671         {
1672                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1673                 SysLog(NID_GRP, "_SglDestroySurface failed!! dpy:%#x sglIndex:%#x", (unsigned int)dpy
1674                                 , (unsigned int)surface);
1675                 return eglDestroySurface(dpy, EGL_NO_SURFACE);
1676         }
1677
1678 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
1679         if (pSglInfo == __pPreviousSglInfo || pSglInfo->pSecondSglInfo == __pPreviousSglInfo)
1680         {
1681                 __pPreviousSglInfo = null;
1682         }
1683 #endif
1684
1685         ret = eglDestroySurface(dpy, pSglInfo->surface);
1686         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1687
1688         if (__isDoublePixmapEnabled && pSglInfo->pSecondSglInfo != null)
1689         {
1690                 eglDestroySurface(dpy, pSglInfo->pSecondSglInfo->surface);
1691                 pSglInfoTableManipulatorInstance->DestroySglIndex(pSglInfo->pSecondSglInfo->sglIndex);
1692         }
1693
1694         pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1695
1696         return ret;
1697 }
1698
1699 EGLBoolean
1700 _SglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* pValue)
1701 {
1702         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1703
1704         _SglIndex sglIndex = (_SglIndex)surface;
1705         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1706
1707         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1708         {
1709                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1710                 SysLog(NID_GRP, "_SglQuerySurface failed!! dpy:%#x sglIndex:%#x attribute:%#x pValue:%#x",
1711                         (unsigned int)dpy, (unsigned int)sglIndex, (unsigned int)attribute, (unsigned int)pValue);
1712                 return eglQuerySurface(dpy, EGL_NO_SURFACE, attribute, pValue);
1713         }
1714
1715         EGLBoolean ret = eglQuerySurface(dpy, pSglInfo->surface, attribute, pValue);
1716         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1717
1718         return ret;
1719 }
1720
1721 EGLBoolean
1722 _SglBindAPI(EGLenum api)
1723 {
1724         return eglBindAPI(api);
1725 }
1726
1727 EGLenum
1728 _SglQueryAPI()
1729 {
1730         return eglQueryAPI();
1731 }
1732
1733 EGLBoolean
1734 _SglWaitClient()
1735 {
1736         return eglWaitClient();
1737 }
1738
1739 EGLBoolean
1740 _SglReleaseThread(void)
1741 {
1742         return eglReleaseThread();
1743 }
1744
1745 EGLSurface
1746 _SglCreatePbufferFromClientBuffer(
1747                 EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint* pAttribList)
1748 {
1749         _SglIndex sglIndex = INVALID_SGL_INDEX;
1750         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1751
1752         sglIndex = pSglInfoTableManipulatorInstance->CreateSglIndex();
1753         if (sglIndex <= INVALID_SGL_INDEX)
1754         {
1755                 SysLog(NID_GRP, "_SglCreatePbufferFromClientBuffer failed!!"
1756                         " dpy:%#x buftype:%#x buffer:%#x config:%#x pAttribList:%#x",
1757                         (unsigned int)dpy, (unsigned int)buftype, (unsigned int)buffer, (unsigned int)config, (unsigned int)pAttribList);
1758
1759                 return eglCreatePbufferFromClientBuffer(null, (EGLenum)0, null, null, null);
1760         }
1761
1762         EGLSurface pbufferFromClientBuffer = eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, pAttribList);
1763         if (pbufferFromClientBuffer == EGL_NO_SURFACE)
1764         {
1765                 pSglInfoTableManipulatorInstance->DestroySglIndex(sglIndex);
1766                 sglIndex = 0;
1767         }
1768         else
1769         {
1770                 _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1771
1772                 pSglInfo->surface = pbufferFromClientBuffer;
1773
1774                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1775         }
1776
1777         return (EGLSurface)sglIndex;
1778 }
1779
1780 EGLBoolean
1781 _SglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1782 {
1783         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1784
1785         _SglIndex sglIndex = (_SglIndex)surface;
1786         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1787
1788         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1789         {
1790                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1791                 SysLog(NID_GRP, "_SglCreatePbufferFromClientBuffer failed!! "
1792                         "dpy:%#x surface:%#x attribute:%#x value:%#x",
1793                         (unsigned int)dpy, (unsigned int)surface, (unsigned int)attribute, (unsigned int)value);
1794
1795                 return eglSurfaceAttrib(dpy, EGL_NO_SURFACE, attribute, value);
1796         }
1797
1798         EGLBoolean ret = eglSurfaceAttrib(dpy, pSglInfo->surface, attribute, value);
1799         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1800
1801         return ret;
1802 }
1803
1804 EGLBoolean
1805 _SglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1806 {
1807         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1808
1809         _SglIndex sglIndex = (_SglIndex)surface;
1810         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1811
1812         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1813         {
1814                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1815                 SysLog(NID_GRP, "_SglBindTexImage failed!! dpy:%#x surface:%#x buffer:%#x",
1816                         (unsigned int)dpy, (unsigned int)surface, (unsigned int)buffer);
1817
1818                 return eglBindTexImage(dpy, EGL_NO_SURFACE, buffer);
1819         }
1820
1821         EGLBoolean ret = eglBindTexImage(dpy, pSglInfo->surface, buffer);
1822         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1823
1824         return ret;
1825 }
1826
1827 EGLBoolean
1828 _SglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1829 {
1830         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1831
1832         _SglIndex sglIndex = (_SglIndex)surface;
1833         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1834
1835         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1836         {
1837                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1838                 SysLog(NID_GRP, "_SglReleaseTexImage failed!! dpy:%#x surface:%#x buffer:%#x",
1839                         (unsigned int)dpy, (unsigned int)surface, (unsigned int)buffer);
1840
1841                 return eglReleaseTexImage(dpy, EGL_NO_SURFACE, buffer);
1842         }
1843
1844         EGLBoolean ret = eglReleaseTexImage(dpy, pSglInfo->surface, buffer);
1845         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1846
1847         return ret;
1848 }
1849
1850 EGLBoolean
1851 _SglSwapInterval(EGLDisplay dpy, EGLint interval)
1852 {
1853         return eglSwapInterval(dpy, interval);
1854 }
1855
1856 EGLContext
1857 _SglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareContext, const EGLint* pAttribList)
1858 {
1859         return eglCreateContext(dpy, config, shareContext, pAttribList);
1860 }
1861
1862 EGLBoolean
1863 _SglDestroyContext(EGLDisplay dpy, EGLContext ctx)
1864 {
1865         return eglDestroyContext(dpy, ctx);
1866 }
1867
1868 EGLBoolean
1869 _SglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
1870 {
1871         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1872
1873         _SglIndex sglIndexDraw = (_SglIndex)draw;
1874         _SglIndex sglIndexRead = (_SglIndex)read;
1875
1876         EGLSurface sglInfoReadSurface;
1877         {
1878                 _SglInfo* sglInfoRead = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndexRead);
1879
1880                 if (sglInfoRead == null)
1881                 {
1882                         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1883                         SysLog(NID_GRP, "_SglMakeCurrent failed!! dpy:%#x draw:%#x read:%#x ctx:%#x",
1884                                 (unsigned int)dpy, (unsigned int)draw, (unsigned int)read, (unsigned int)ctx);
1885                         return eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
1886                 }
1887                 sglInfoReadSurface = sglInfoRead->surface;
1888
1889                 if (__isDoublePixmapEnabled && !sglInfoRead->isBackbuffer && sglInfoRead->pSecondSglInfo != null)
1890                 {
1891                         sglInfoReadSurface = sglInfoRead->pSecondSglInfo->surface;
1892                 }
1893
1894                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1895         }
1896
1897         _SglInfo* pSglInfoDraw = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndexDraw);
1898         if (pSglInfoDraw == null)
1899         {
1900                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1901                 SysLog(NID_GRP, "_SglMakeCurrent failed!! dpy:%#x draw:%#x read:%#x ctx:%#x",
1902                                 (unsigned int)dpy, (unsigned int)draw, (unsigned int)read, (unsigned int)ctx);
1903                 return eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
1904         }
1905
1906         if (__isDoublePixmapEnabled && !pSglInfoDraw->isBackbuffer && pSglInfoDraw->pSecondSglInfo != null)
1907         {
1908                 pSglInfoDraw = pSglInfoDraw->pSecondSglInfo;
1909         }
1910
1911         pSglInfoDraw->context = ctx;
1912
1913         EGLBoolean ret = eglMakeCurrent(dpy, pSglInfoDraw->surface, sglInfoReadSurface, ctx);
1914
1915 #if defined(FGRAPHICS_INTERNAL_USE_RESTORE_CONTEXT)
1916         if (draw != EGL_NO_SURFACE)
1917         {
1918                 _SaveCurrentContext(pSglInfoDraw);
1919         }
1920 #endif
1921
1922         if (pSglInfoDraw->glVersion == 0 && ctx != EGL_NO_CONTEXT)
1923         {
1924                 eglQueryContext(dpy, ctx,  EGL_CONTEXT_CLIENT_VERSION, &pSglInfoDraw->glVersion);
1925         }
1926
1927         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1928
1929         return ret;
1930 }
1931
1932 EGLContext
1933 _SglGetCurrentContext()
1934 {
1935         return eglGetCurrentContext();
1936 }
1937
1938 EGLSurface
1939 _SglGetCurrentSurface(EGLint readDraw)
1940 {
1941         EGLSurface surface = EGL_NO_SURFACE;
1942         _SglIndex sglIndex = INVALID_SGL_INDEX;
1943
1944         surface = eglGetCurrentSurface(readDraw);
1945         sglIndex = _SglInfoTableManipulator::GetInstance()->GetSglIndexForSurface(surface);
1946
1947         if (sglIndex < INVALID_SGL_INDEX)
1948         {
1949                 SysLog(NID_GRP, "_SglGetCurrentSurface failed!! readDraw:%#x", (unsigned int)readDraw);
1950                 return EGL_NO_SURFACE;
1951         }
1952
1953         return (EGLSurface)sglIndex;
1954 }
1955
1956 EGLDisplay
1957 _SglGetCurrentDisplay(void)
1958 {
1959         return eglGetCurrentDisplay();
1960 }
1961
1962 EGLBoolean
1963 _SglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* pValue)
1964 {
1965         return eglQueryContext(dpy, ctx, attribute, pValue);
1966 }
1967
1968 EGLBoolean
1969 _SglWaitGL(void)
1970 {
1971         return eglWaitGL();
1972 }
1973
1974 EGLBoolean
1975 _SglWaitNative(EGLint engine)
1976 {
1977         return eglWaitNative(engine);
1978 }
1979
1980 EGLBoolean _SglUpdateBufferOSP(EGLDisplay dpy, EGLSurface surface);
1981
1982 EGLBoolean
1983 _SglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1984 {
1985         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
1986
1987         _SglIndex sglIndex = (_SglIndex)surface;
1988         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
1989
1990         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
1991         {
1992                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
1993                 SysLog(NID_GRP, "_SglSwapBuffers failed!! dpy:%#x sglIndex:%#x", (unsigned int)dpy
1994                                 , (unsigned int)sglIndex);
1995
1996                 return eglSwapBuffers(dpy, EGL_NO_SURFACE);
1997         }
1998
1999         if (pSglInfo->pBitmap != null)
2000         {
2001 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
2002                 _SglUpdateBufferOSP(dpy, surface);
2003 #else
2004                 if(__evasEngineType == ENGINE_TYPE_OPENGL_X11)
2005                 {
2006                         if (pSglInfo->glVersion == 1)
2007                         {
2008                                 _GlFlush_1();
2009                         }
2010                         else
2011                         {
2012                                 _GlFlush_2();
2013                         }
2014                 }
2015                 else
2016                 {
2017                         eglWaitGL();
2018                 }
2019 #endif
2020
2021                 if(__evasEngineType == ENGINE_TYPE_SOFEWARE_X11 || __evasEngineType == ENGINE_TYPE_OPENGL_X11)
2022                 {
2023                         if (__isDoublePixmapEnabled && pSglInfo->pSecondSglInfo != null)
2024                         {
2025                                 if (pSglInfo->swapDone || pSglInfo->pSecondSglInfo->swapDone)
2026                                 {
2027                                         _SglInfo* pBackSglInfo = null;
2028                                         _SglInfo* pFrontSglInfo = null;
2029
2030                                         if (pSglInfo->isBackbuffer)
2031                                         {
2032                                                 pBackSglInfo = pSglInfo;
2033                                                 pFrontSglInfo = pSglInfo->pSecondSglInfo;
2034                                         }
2035                                         else
2036                                         {
2037                                                 pBackSglInfo = pSglInfo->pSecondSglInfo;
2038                                                 pFrontSglInfo = pSglInfo;
2039                                         }
2040                                         pBackSglInfo->isBackbuffer = false;
2041                                         pFrontSglInfo->isBackbuffer = true;
2042
2043                                         pFrontSglInfo->wasShown = false;
2044                                         pFrontSglInfo->swapDone = false;
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 __EglMustCastToProperFunctionPointerType
2105 _SglGetProcAddress(const char* pProcName)
2106 {
2107         return eglGetProcAddress(pProcName);
2108 }
2109
2110 EGLBoolean
2111 _SglUpdateBufferOSP(EGLDisplay dpy, EGLSurface surface)
2112 {
2113 #if defined(FGRAPHICS_INTERNAL_USE_EGLCOPYBUFFER)
2114         Tizen::Graphics::BufferInfo bufferInfo;
2115         _SglInfoTableManipulator* pSglInfoTableManipulatorInstance = _SglInfoTableManipulator::GetInstance();
2116
2117         _SglIndex sglIndex = (_SglIndex)surface;
2118         _SglInfo* pSglInfo = pSglInfoTableManipulatorInstance->LockSglInfoTable(sglIndex);
2119
2120         if (sglIndex <= INVALID_SGL_INDEX || pSglInfo == null)
2121         {
2122                 pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2123                 SysLog(NID_GRP, "_SglUpdateBufferOSP failed!!");
2124                 return EGL_FALSE;
2125         }
2126
2127         eglCopyBuffers(dpy, pSglInfo->surface, pSglInfo->nativePixmap);
2128         ecore_x_image_get(pSglInfo->pEcoreImage, (Ecore_X_Drawable)pSglInfo->nativePixmap,
2129                 0, 0, 0, 0, pSglInfo->width, pSglInfo->height);
2130
2131         pSglInfoTableManipulatorInstance->UnlockSglInfoTable();
2132 #endif
2133         return EGL_TRUE;
2134 }
2135
2136 #ifdef __cplusplus
2137 }
2138 #endif
2139
2140 } // Opengl
2141
2142 }} // Tizen::Graphics