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