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