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