Support EGL_DONT_CARE for multi-sampling level
[platform/core/uifw/dali-adaptor.git] / adaptors / common / gl / egl-implementation.cpp
index c27a13d..7ca4366 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 // INTERNAL INCLUDES
 #include <gl/gl-implementation.h>
+#include <gl/egl-debug.h>
 
-namespace
-{
-
-void PrintEglError( EGLint error )
-{
-  switch (error)
-  {
-    case EGL_BAD_DISPLAY:
-    {
-      DALI_LOG_ERROR("EGL_BAD_DISPLAY : Display is not an EGL display connection\n");
-      break;
-    }
-    case EGL_NOT_INITIALIZED:
-    {
-      DALI_LOG_ERROR("EGL_NOT_INITIALIZED : Display has not been initialized\n");
-      break;
-    }
-    case EGL_BAD_SURFACE:
-    {
-      DALI_LOG_ERROR("EGL_BAD_SURFACE : Draw or read is not an EGL surface\n");
-      break;
-    }
-    case EGL_BAD_CONTEXT:
-    {
-      DALI_LOG_ERROR("EGL_BAD_CONTEXT : Context is not an EGL rendering context\n");
-      break;
-    }
-    case EGL_BAD_MATCH:
-    {
-      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\n");
-      break;
-    }
-    case EGL_BAD_ACCESS:
-    {
-      DALI_LOG_ERROR("EGL_BAD_ACCESS : Context is current to some other thread\n");
-      break;
-    }
-    case EGL_BAD_NATIVE_PIXMAP:
-    {
-      DALI_LOG_ERROR("EGL_BAD_NATIVE_PIXMAP : A native pixmap underlying either draw or read is no longer valid\n");
-      break;
-    }
-    case EGL_BAD_NATIVE_WINDOW:
-    {
-      DALI_LOG_ERROR("EGL_BAD_NATIVE_WINDOW : A native window underlying either draw or read is no longer valid\n");
-      break;
-    }
-    case EGL_BAD_CURRENT_SURFACE:
-    {
-      DALI_LOG_ERROR("EGL_BAD_CURRENT_SURFACE : The previous context has unflushed commands and the previous surface is no longer valid\n");
-      break;
-    }
-    case EGL_BAD_ALLOC:
-    {
-      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\n");
-      break;
-    }
-    case EGL_CONTEXT_LOST:
-    {
-      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\n");
-      break;
-    }
-    default:
-    {
-      DALI_LOG_ERROR("Unknown error with code: %d\n", error);
-      break;
-    }
-  }
-}
-
-} // unnamed namespace
+// EGL constants use C style casts
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
 
 namespace Dali
 {
@@ -114,24 +47,25 @@ namespace Adaptor
   if (err != EGL_SUCCESS) \
   { \
     DALI_LOG_ERROR("EGL error after %s\n", lastCommand); \
-    PrintEglError(err); \
+    Egl::PrintError(err); \
     DALI_ASSERT_ALWAYS(0 && "EGL error"); \
   } \
 }
 
-EglImplementation::EglImplementation()
+EglImplementation::EglImplementation( int multiSamplingLevel )
   : mEglNativeDisplay(0),
     mEglNativeWindow(0),
-    mEglNativePixmap(0),
+    mCurrentEglNativePixmap(0),
     mEglDisplay(0),
     mEglConfig(0),
     mEglContext(0),
-    mEglSurface(0),
+    mCurrentEglSurface(0),
     mGlesInitialized(false),
     mIsOwnSurface(true),
     mContextCurrent(false),
     mIsWindow(true),
-    mColorDepth(COLOR_DEPTH_24)
+    mColorDepth(COLOR_DEPTH_24),
+    mMultiSamplingLevel( multiSamplingLevel )
 {
 }
 
@@ -169,9 +103,9 @@ bool EglImplementation::InitializeGles( EGLNativeDisplayType display, bool isOwn
 
     mContextAttribs.Reserve(5);
     mContextAttribs.PushBack( EGL_CONTEXT_MAJOR_VERSION_KHR );
-    mContextAttribs.PushBack( 3 );
+    mContextAttribs.PushBack( DALI_GLES_VERSION / 10 );
     mContextAttribs.PushBack( EGL_CONTEXT_MINOR_VERSION_KHR );
-    mContextAttribs.PushBack( 0 );
+    mContextAttribs.PushBack( DALI_GLES_VERSION % 10 );
 
 #else // DALI_GLES_VERSION >= 30
 
@@ -219,10 +153,12 @@ void EglImplementation::DestroyContext()
 
 void EglImplementation::DestroySurface()
 {
-  if(mIsOwnSurface && mEglSurface)
+  if(mIsOwnSurface && mCurrentEglSurface)
   {
-    eglDestroySurface( mEglDisplay, mEglSurface );
-    mEglSurface = 0;
+    // Make context null to prevent crash in driver side
+    MakeContextNull();
+    eglDestroySurface( mEglDisplay, mCurrentEglSurface );
+    mCurrentEglSurface = 0;
   }
 }
 
@@ -232,14 +168,14 @@ void EglImplementation::MakeContextCurrent()
 
   if(mIsOwnSurface)
   {
-    eglMakeCurrent( mEglDisplay, mEglSurface, mEglSurface, mEglContext );
+    eglMakeCurrent( mEglDisplay, mCurrentEglSurface, mCurrentEglSurface, mEglContext );
   }
 
   EGLint error = eglGetError();
 
   if ( error != EGL_SUCCESS )
   {
-    PrintEglError(error);
+    Egl::PrintError(error);
 
     DALI_ASSERT_ALWAYS(false && "MakeContextCurrent failed!");
   }
@@ -256,6 +192,26 @@ void EglImplementation::MakeContextCurrent()
       eglQueryString(mEglDisplay, EGL_EXTENSIONS));
 }
 
+void EglImplementation::MakeCurrent( EGLNativePixmapType pixmap, EGLSurface eglSurface )
+{
+  mCurrentEglNativePixmap = pixmap;
+  mCurrentEglSurface = eglSurface;
+
+  if(mIsOwnSurface)
+  {
+    eglMakeCurrent( mEglDisplay, mCurrentEglSurface, mCurrentEglSurface, mEglContext );
+  }
+
+  EGLint error = eglGetError();
+
+  if ( error != EGL_SUCCESS )
+  {
+    Egl::PrintError(error);
+
+    DALI_ASSERT_ALWAYS(false && "MakeCurrent failed!");
+  }
+}
+
 void EglImplementation::MakeContextNull()
 {
   mContextCurrent = false;
@@ -267,14 +223,12 @@ void EglImplementation::TerminateGles()
 {
   if ( mGlesInitialized )
   {
-    // in latest Mali DDK (r2p3 ~ r3p0 in April, 2012),
-    // MakeContextNull should be called before eglDestroy surface
-    // to prevent crash in _mali_surface_destroy_callback
+    // Make context null to prevent crash in driver side
     MakeContextNull();
 
-    if(mIsOwnSurface && mEglSurface)
+    if(mIsOwnSurface && mCurrentEglSurface)
     {
-      eglDestroySurface(mEglDisplay, mEglSurface);
+      eglDestroySurface(mEglDisplay, mCurrentEglSurface);
     }
     eglDestroyContext(mEglDisplay, mEglContext);
 
@@ -283,7 +237,7 @@ void EglImplementation::TerminateGles()
     mEglDisplay = NULL;
     mEglConfig  = NULL;
     mEglContext = NULL;
-    mEglSurface = NULL;
+    mCurrentEglSurface = NULL;
 
     mGlesInitialized = false;
   }
@@ -296,12 +250,12 @@ bool EglImplementation::IsGlesInitialized() const
 
 void EglImplementation::SwapBuffers()
 {
-  eglSwapBuffers( mEglDisplay, mEglSurface );
+  eglSwapBuffers( mEglDisplay, mCurrentEglSurface );
 }
 
 void EglImplementation::CopyBuffers()
 {
-  eglCopyBuffers( mEglDisplay, mEglSurface, mEglNativePixmap );
+  eglCopyBuffers( mEglDisplay, mCurrentEglSurface, mCurrentEglNativePixmap );
 }
 
 void EglImplementation::WaitGL()
@@ -348,7 +302,7 @@ void EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth )
 
 #else // DALI_GLES_VERSION >= 30
 
-  DALI_LOG_WARNING( "Using OpenGL ES 2 \n" );
+  Integration::Log::LogMessage( Integration::Log::DebugInfo, "Using OpenGL ES 2 \n" );
   configAttribs.PushBack( EGL_OPENGL_ES2_BIT );
 
 #endif //DALI_GLES_VERSION >= 30
@@ -380,10 +334,13 @@ void EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth )
   configAttribs.PushBack( EGL_STENCIL_SIZE );
   configAttribs.PushBack( 8 );
 #ifndef DALI_PROFILE_UBUNTU
-  configAttribs.PushBack( EGL_SAMPLES );
-  configAttribs.PushBack( 4 );
-  configAttribs.PushBack( EGL_SAMPLE_BUFFERS );
-  configAttribs.PushBack( 1 );
+  if( mMultiSamplingLevel != EGL_DONT_CARE )
+  {
+    configAttribs.PushBack( EGL_SAMPLES );
+    configAttribs.PushBack( mMultiSamplingLevel );
+    configAttribs.PushBack( EGL_SAMPLE_BUFFERS );
+    configAttribs.PushBack( 1 );
+  }
 #endif // DALI_PROFILE_UBUNTU
   configAttribs.PushBack( EGL_NONE );
 
@@ -430,7 +387,7 @@ void EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth )
 
 void EglImplementation::CreateSurfaceWindow( EGLNativeWindowType window, ColorDepth depth )
 {
-  DALI_ASSERT_ALWAYS( ( mEglSurface == 0 ) && "EGL surface already exists" );
+  DALI_ASSERT_ALWAYS( ( mCurrentEglSurface == 0 ) && "EGL surface already exists" );
 
   mEglNativeWindow = window;
   mColorDepth = depth;
@@ -439,27 +396,27 @@ void EglImplementation::CreateSurfaceWindow( EGLNativeWindowType window, ColorDe
   // egl choose config
   ChooseConfig(mIsWindow, mColorDepth);
 
-  mEglSurface = eglCreateWindowSurface( mEglDisplay, mEglConfig, mEglNativeWindow, NULL );
+  mCurrentEglSurface = eglCreateWindowSurface( mEglDisplay, mEglConfig, mEglNativeWindow, NULL );
   TEST_EGL_ERROR("eglCreateWindowSurface");
 
-  DALI_ASSERT_ALWAYS( mEglSurface && "Create window surface failed" );
+  DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create window surface failed" );
 }
 
-void EglImplementation::CreateSurfacePixmap( EGLNativePixmapType pixmap, ColorDepth depth )
+EGLSurface EglImplementation::CreateSurfacePixmap( EGLNativePixmapType pixmap, ColorDepth depth )
 {
-  DALI_ASSERT_ALWAYS( mEglSurface == 0 && "Cannot create more than one instance of surface pixmap" );
-
-  mEglNativePixmap = pixmap;
+  mCurrentEglNativePixmap = pixmap;
   mColorDepth = depth;
   mIsWindow = false;
 
   // egl choose config
   ChooseConfig(mIsWindow, mColorDepth);
 
-  mEglSurface = eglCreatePixmapSurface( mEglDisplay, mEglConfig, mEglNativePixmap, NULL );
+  mCurrentEglSurface = eglCreatePixmapSurface( mEglDisplay, mEglConfig, mCurrentEglNativePixmap, NULL );
   TEST_EGL_ERROR("eglCreatePixmapSurface");
 
-  DALI_ASSERT_ALWAYS( mEglSurface && "Create pixmap surface failed" );
+  DALI_ASSERT_ALWAYS( mCurrentEglSurface && "Create pixmap surface failed" );
+
+  return mCurrentEglSurface;
 }
 
 bool EglImplementation::ReplaceSurfaceWindow( EGLNativeWindowType window )
@@ -482,22 +439,16 @@ bool EglImplementation::ReplaceSurfaceWindow( EGLNativeWindowType window )
   return contextLost;
 }
 
-bool EglImplementation::ReplaceSurfacePixmap( EGLNativePixmapType pixmap )
+bool EglImplementation::ReplaceSurfacePixmap( EGLNativePixmapType pixmap, EGLSurface& eglSurface )
 {
   bool contextLost = false;
 
-  //  the surface is bound to the context, so set the context to null
-  MakeContextNull();
-
-  // destroy the surface
-  DestroySurface();
-
   // display connection has not changed, then we can just create a new surface
   // create the EGL surface
-  CreateSurfacePixmap( pixmap, mColorDepth );
+  eglSurface = CreateSurfacePixmap( pixmap, mColorDepth );
 
-  // set the context to be current with the new surface
-  MakeContextCurrent();
+  // set the eglSurface to be current
+  MakeCurrent( pixmap, eglSurface );
 
   return contextLost;
 }
@@ -517,3 +468,5 @@ EGLDisplay EglImplementation::GetContext() const
 } // namespace Internal
 
 } // namespace Dali
+
+#pragma GCC diagnostic pop