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