2 Copyright (c) 2000-2013 Samsung Electronics Co., Ltd All Rights Reserved
4 This file is part of Dali Adaptor
6 PROPRIETARY/CONFIDENTIAL
8 This software is the confidential and proprietary information of
9 SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
10 disclose such Confidential Information and shall use it only in
11 accordance with the terms of the license agreement you entered
12 into with SAMSUNG ELECTRONICS.
14 SAMSUNG make no representations or warranties about the suitability
15 of the software, either express or implied, including but not limited
16 to the implied warranties of merchantability, fitness for a particular
17 purpose, or non-infringement. SAMSUNG shall not be liable for any
18 damages suffered by licensee as a result of using, modifying or
19 distributing this software or its derivatives.
24 #include <gl/egl-implementation.h>
28 #include <dali/integration-api/debug.h>
29 #include <dali/public-api/common/dali-common.h>
30 #include <dali/public-api/common/dali-vector.h>
36 #if defined(DEBUG_ENABLED)
38 void PrintConfigs(EGLDisplay d)
42 eglGetConfigs(d, NULL, 0, &numConfigs);
43 EGLConfig *configs = new EGLConfig[numConfigs];
45 eglGetConfigs(d, configs, numConfigs, &numConfigs);
47 printf("Configurations: N=%d\n", numConfigs);
48 printf(" - config id\n");
49 printf(" - buffer size\n");
51 printf(" - double buffer\n");
52 printf(" - stereo\n");
53 printf(" - r, g, b\n");
55 printf(" - stencil\n");
57 printf(" bf lv d st colorbuffer dp st supported \n");
58 printf(" id sz l b ro r g b a th cl surfaces \n");
59 printf("----------------------------------------------\n");
60 for (EGLint i = 0; i < numConfigs; i++) {
61 EGLint id, size, level;
62 EGLint red, green, blue, alpha;
63 EGLint depth, stencil;
65 EGLint doubleBuf = 1, stereo = 0;
66 char surfString[100] = "";
68 eglGetConfigAttrib(d, configs[i], EGL_CONFIG_ID, &id);
69 eglGetConfigAttrib(d, configs[i], EGL_BUFFER_SIZE, &size);
70 eglGetConfigAttrib(d, configs[i], EGL_LEVEL, &level);
72 eglGetConfigAttrib(d, configs[i], EGL_RED_SIZE, &red);
73 eglGetConfigAttrib(d, configs[i], EGL_GREEN_SIZE, &green);
74 eglGetConfigAttrib(d, configs[i], EGL_BLUE_SIZE, &blue);
75 eglGetConfigAttrib(d, configs[i], EGL_ALPHA_SIZE, &alpha);
76 eglGetConfigAttrib(d, configs[i], EGL_DEPTH_SIZE, &depth);
77 eglGetConfigAttrib(d, configs[i], EGL_STENCIL_SIZE, &stencil);
78 eglGetConfigAttrib(d, configs[i], EGL_SURFACE_TYPE, &surfaces);
80 if (surfaces & EGL_WINDOW_BIT)
81 strcat(surfString, "win,");
82 if (surfaces & EGL_PBUFFER_BIT)
83 strcat(surfString, "pb,");
84 if (surfaces & EGL_PIXMAP_BIT)
85 strcat(surfString, "pix,");
86 if (strlen(surfString) > 0)
87 surfString[strlen(surfString) - 1] = 0;
89 printf("0x%02x %2d %2d %c %c %2d %2d %2d %2d %2d %2d %-12s\n",
91 doubleBuf ? 'y' : '.',
93 red, green, blue, alpha,
94 depth, stencil, surfString);
111 #define TEST_EGL_ERROR(lastCommand) \
113 EGLint err = eglGetError(); \
114 if (err != EGL_SUCCESS) \
116 printf("EGL error after %s code=%x\n", lastCommand, err); \
117 DALI_LOG_ERROR("EGL error after %s code=%x\n", lastCommand,err); \
118 DALI_ASSERT_ALWAYS(0 && "EGL error"); \
122 EglImplementation::EglImplementation()
123 : mEglNativeDisplay(0),
124 mCurrentEglNativePixmap(0),
128 mCurrentEglSurface(0),
129 mGlesInitialized(false),
131 mContextCurrent(false),
133 mColorDepth(COLOR_DEPTH_24)
137 EglImplementation::~EglImplementation()
142 bool EglImplementation::InitializeGles( EGLNativeDisplayType display, bool isOwnSurface )
144 if ( !mGlesInitialized )
146 mEglNativeDisplay = display;
148 //@todo see if we can just EGL_DEFAULT_DISPLAY instead
149 mEglDisplay = eglGetDisplay(mEglNativeDisplay);
151 EGLint majorVersion = 0;
152 EGLint minorVersion = 0;
153 if ( !eglInitialize( mEglDisplay, &majorVersion, &minorVersion ) )
157 eglBindAPI(EGL_OPENGL_ES_API);
159 #if defined(DEBUG_ENABLED)
160 PrintConfigs(mEglDisplay);
163 mContextAttribs.Clear();
165 #if DALI_GLES_VERSION >= 30
167 mContextAttribs.Reserve(5);
168 mContextAttribs.PushBack( EGL_CONTEXT_MAJOR_VERSION_KHR );
169 mContextAttribs.PushBack( 3 );
170 mContextAttribs.PushBack( EGL_CONTEXT_MINOR_VERSION_KHR );
171 mContextAttribs.PushBack( 0 );
173 #else // DALI_GLES_VERSION >= 30
175 mContextAttribs.Reserve(3);
176 mContextAttribs.PushBack( EGL_CONTEXT_CLIENT_VERSION );
177 mContextAttribs.PushBack( 2 );
179 #endif // DALI_GLES_VERSION >= 30
181 mContextAttribs.PushBack( EGL_NONE );
183 mGlesInitialized = true;
184 mIsOwnSurface = isOwnSurface;
187 return mGlesInitialized;
190 bool EglImplementation::CreateContext()
192 // make sure a context isn't created twice
193 DALI_ASSERT_ALWAYS( (mEglContext == 0) && "EGL context recreated" );
194 DALI_ASSERT_ALWAYS( mGlesInitialized );
196 mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0]));
198 // if emscripten ignore this (egl spec says non gles2 implementation must return EGL_BAD_MATCH if it doesnt support gles2)
199 // so just ignore error for now....
200 // TEST_EGL_ERROR("eglCreateContext render thread");
201 // DALI_ASSERT_ALWAYS( EGL_NO_CONTEXT != mEglContext && "EGL context not created" );
206 void EglImplementation::DestroyContext()
208 DALI_ASSERT_ALWAYS( mEglContext && "no EGL context" );
210 eglDestroyContext( mEglDisplay, mEglContext );
214 void EglImplementation::DestroySurface()
216 if(mIsOwnSurface && mCurrentEglSurface)
218 eglDestroySurface( mEglDisplay, mCurrentEglSurface );
219 mCurrentEglSurface = 0;
223 void EglImplementation::MakeContextCurrent()
225 mContextCurrent = true;
229 eglMakeCurrent( mEglDisplay, mCurrentEglSurface, mCurrentEglSurface, mEglContext );
232 EGLint error = eglGetError();
234 if ( error != EGL_SUCCESS )
238 case EGL_BAD_DISPLAY:
240 DALI_LOG_ERROR("EGL_BAD_DISPLAY : Display is not an EGL display connection");
243 case EGL_NOT_INITIALIZED:
245 DALI_LOG_ERROR("EGL_NOT_INITIALIZED : Display has not been initialized");
248 case EGL_BAD_SURFACE:
250 DALI_LOG_ERROR("EGL_BAD_SURFACE : Draw or read is not an EGL surface");
253 case EGL_BAD_CONTEXT:
255 DALI_LOG_ERROR("EGL_BAD_CONTEXT : Context is not an EGL rendering context");
260 DALI_LOG_ERROR("EGL_BAD_MATCH : Draw or read are not compatible with context, or if context is set to EGL_NO_CONTEXT and draw or read are not set to EGL_NO_SURFACE, or if draw or read are set to EGL_NO_SURFACE and context is not set to EGL_NO_CONTEXT");
265 DALI_LOG_ERROR("EGL_BAD_ACCESS : Context is current to some other thread");
268 case EGL_BAD_NATIVE_PIXMAP:
270 DALI_LOG_ERROR("EGL_BAD_NATIVE_PIXMAP : A native pixmap underlying either draw or read is no longer valid.");
273 case EGL_BAD_NATIVE_WINDOW:
275 DALI_LOG_ERROR("EGL_BAD_NATIVE_WINDOW : A native window underlying either draw or read is no longer valid.");
278 case EGL_BAD_CURRENT_SURFACE:
280 DALI_LOG_ERROR("EGL_BAD_CURRENT_SURFACE : The previous context has unflushed commands and the previous surface is no longer valid.");
285 DALI_LOG_ERROR("EGL_BAD_ALLOC : Allocation of ancillary buffers for draw or read were delayed until eglMakeCurrent is called, and there are not enough resources to allocate them");
288 case EGL_CONTEXT_LOST:
290 DALI_LOG_ERROR("EGL_CONTEXT_LOST : If a power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering");
295 DALI_LOG_ERROR("Unknown error");
299 DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
302 DALI_LOG_WARNING("- EGL Information\nVendor: %s\nVersion: %s\nClient APIs: %s\nExtensions: %s\n",
303 eglQueryString(mEglDisplay, EGL_VENDOR),
304 eglQueryString(mEglDisplay, EGL_VERSION),
305 eglQueryString(mEglDisplay, EGL_CLIENT_APIS),
306 eglQueryString(mEglDisplay, EGL_EXTENSIONS));
310 void EglImplementation::MakeContextNull()
312 mContextCurrent = false;
313 // clear the current context
314 eglMakeCurrent( mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
317 void EglImplementation::TerminateGles()
319 if ( mGlesInitialized )
321 // in latest Mali DDK (r2p3 ~ r3p0 in April, 2012),
322 // MakeContextNull should be called before eglDestroy surface
323 // to prevent crash in _mali_surface_destroy_callback
326 if(mIsOwnSurface && mCurrentEglSurface)
328 eglDestroySurface(mEglDisplay, mCurrentEglSurface);
330 eglDestroyContext(mEglDisplay, mEglContext);
332 eglTerminate(mEglDisplay);
337 mCurrentEglSurface = NULL;
339 mGlesInitialized = false;
343 bool EglImplementation::IsGlesInitialized() const
345 return mGlesInitialized;
348 void EglImplementation::SwapBuffers()
350 eglSwapBuffers( mEglDisplay, mCurrentEglSurface );
353 void EglImplementation::CopyBuffers()
355 eglCopyBuffers( mEglDisplay, mCurrentEglSurface, mCurrentEglNativePixmap );
358 void EglImplementation::WaitGL()
363 void EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth )
365 if(mEglConfig && isWindowType == mIsWindow && mColorDepth == depth)
370 mIsWindow = isWindowType;
373 Vector<EGLint> configAttribs;
374 configAttribs.Reserve(31);
378 configAttribs.PushBack( EGL_SURFACE_TYPE );
379 configAttribs.PushBack( EGL_WINDOW_BIT );
383 DALI_ASSERT_ALWAYS(!"uninplemented");
384 configAttribs.PushBack( EGL_SURFACE_TYPE );
385 configAttribs.PushBack( EGL_PIXMAP_BIT );
388 configAttribs.PushBack( EGL_RENDERABLE_TYPE );
390 #if DALI_GLES_VERSION >= 30
391 DALI_ASSERT_ALWAYS(!"uninplemented");
394 configAttribs.PushBack( EGL_OPENGL_ES3_BIT_KHR );
396 // There is a bug in the desktop emulator
397 // Requesting for ES3 causes eglCreateContext even though it allows to ask
398 // for a configuration that supports GLES 3.0
399 configAttribs.PushBack( EGL_OPENGL_ES2_BIT );
402 #else // DALI_GLES_VERSION >= 30
404 configAttribs.PushBack( EGL_OPENGL_ES2_BIT );
406 #endif //DALI_GLES_VERSION >= 30
408 configAttribs.PushBack( EGL_RED_SIZE );
409 configAttribs.PushBack( 8 );
410 configAttribs.PushBack( EGL_GREEN_SIZE );
411 configAttribs.PushBack( 8 );
412 configAttribs.PushBack( EGL_BLUE_SIZE );
413 configAttribs.PushBack( 8 );
416 // Setting the alpha crashed .... need SDL_SetVideo(...) with alpha somehow??
419 configAttribs.PushBack( EGL_ALPHA_SIZE );
420 configAttribs.PushBack( 8 );
421 configAttribs.PushBack( EGL_DEPTH_SIZE );
422 configAttribs.PushBack( 24 );
424 configAttribs.PushBack( EGL_NONE );
426 if ( eglChooseConfig( mEglDisplay, &(configAttribs[0]), &mEglConfig, 1, &numConfigs ) != EGL_TRUE )
428 EGLint error = eglGetError();
431 case EGL_BAD_DISPLAY:
433 DALI_LOG_ERROR("Display is not an EGL display connection");
436 case EGL_BAD_ATTRIBUTE:
438 DALI_LOG_ERROR("The parameter confirAttribs contains an invalid frame buffer configuration attribute or an attribute value that is unrecognized or out of range");
441 case EGL_NOT_INITIALIZED:
443 DALI_LOG_ERROR("Display has not been initialized");
446 case EGL_BAD_PARAMETER:
448 DALI_LOG_ERROR("The parameter numConfig is NULL");
453 DALI_LOG_ERROR("Unknown error");
456 DALI_ASSERT_ALWAYS(false && "eglChooseConfig failed!");
459 if ( numConfigs != 1 )
461 DALI_LOG_ERROR("No configurations found.");
462 TEST_EGL_ERROR("eglChooseConfig");
467 void EglImplementation::CreateSurfaceWindow( EGLNativeWindowType window, ColorDepth depth )
469 DALI_ASSERT_ALWAYS( ( mCurrentEglSurface == 0 ) && "EGL surface already exists" );
475 static_cast<void>(window);
476 EGLNativeWindowType dummyWindow = NULL;
478 mCurrentEglSurface = eglCreateWindowSurface( mEglDisplay, mEglConfig, dummyWindow, NULL );
481 TEST_EGL_ERROR("eglCreateWindowSurface");
483 DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create window surface failed" );
487 EGLSurface EglImplementation::CreateSurfacePixmap( EGLNativePixmapType pixmap, ColorDepth depth )
489 DALI_ASSERT_ALWAYS( mCurrentEglSurface == 0 && "Cannot create more than one instance of surface pixmap" );
491 mCurrentEglNativePixmap = pixmap;
496 ChooseConfig(mIsWindow, mColorDepth);
498 mCurrentEglSurface = eglCreatePixmapSurface( mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL );
499 TEST_EGL_ERROR("eglCreatePixmapSurface");
501 DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create pixmap surface failed" );
503 return mCurrentEglSurface;
506 bool EglImplementation::ReplaceSurfaceWindow( EGLNativeWindowType window )
508 DALI_ASSERT_ALWAYS(!"Unimplemented");
510 bool contextLost = false;
512 // the surface is bound to the context, so set the context to null
515 // destroy the surface
518 // create the EGL surface
519 CreateSurfaceWindow( window, mColorDepth );
521 // set the context to be current with the new surface
522 MakeContextCurrent();
527 bool EglImplementation::ReplaceSurfacePixmap( EGLNativePixmapType pixmap, EGLSurface& eglSurface )
529 bool contextLost = false;
531 // the surface is bound to the context, so set the context to null
534 // destroy the surface
537 // create the EGL surface
538 eglSurface = CreateSurfacePixmap( pixmap, mColorDepth );
540 // set the context to be current with the new surface
541 MakeContextCurrent();
546 EGLDisplay EglImplementation::GetDisplay() const
551 EGLDisplay EglImplementation::GetContext() const
556 } // namespace Adaptor
558 } // namespace Internal