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