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