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