X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fgraphics%2Fgles%2Fegl-implementation.cpp;h=359ac7dd10d172e89762a8ccf2a9069c33346041;hb=a61186ebb4fc7b72d2fa995cdb6eb2e7c1afa02b;hp=ae7c6bcc711333d748c08b55c5f0d51674ccd9bf;hpb=02a0b6a8425ee880dcf8e8a4d5dd5b6d79c38fe4;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/graphics/gles/egl-implementation.cpp b/dali/internal/graphics/gles/egl-implementation.cpp index ae7c6bc..359ac7d 100755 --- a/dali/internal/graphics/gles/egl-implementation.cpp +++ b/dali/internal/graphics/gles/egl-implementation.cpp @@ -35,7 +35,11 @@ namespace { + const uint32_t THRESHOLD_SWAPBUFFER_COUNT = 5; + const uint32_t CHECK_EXTENSION_NUMBER = 3; const std::string EGL_KHR_SURFACELESS_CONTEXT = "EGL_KHR_surfaceless_context"; + const std::string EGL_KHR_CREATE_CONTEXT = "EGL_KHR_create_context"; + const std::string EGL_KHR_PARTIAL_UPDATE = "EGL_KHR_partial_update"; } namespace Dali @@ -60,7 +64,8 @@ namespace Adaptor EglImplementation::EglImplementation( int multiSamplingLevel, Integration::DepthBufferAvailable depthBufferRequired, - Integration::StencilBufferAvailable stencilBufferRequired ) + Integration::StencilBufferAvailable stencilBufferRequired, + Integration::PartialUpdateAvailable partialUpdateAvailable ) : mContextAttribs(), mEglNativeDisplay( 0 ), mEglNativeWindow( 0 ), @@ -72,14 +77,35 @@ EglImplementation::EglImplementation( int multiSamplingLevel, mCurrentEglContext( EGL_NO_CONTEXT ), mMultiSamplingLevel( multiSamplingLevel ), mGlesVersion( 30 ), + mDamagedRectArray( 0 ), mColorDepth( COLOR_DEPTH_24 ), mGlesInitialized( false ), mIsOwnSurface( true ), mIsWindow( true ), mDepthBufferRequired( depthBufferRequired == Integration::DepthBufferAvailable::TRUE ), mStencilBufferRequired( stencilBufferRequired == Integration::StencilBufferAvailable::TRUE ), - mIsSurfacelessContextSupported( false ) + mIsSurfacelessContextSupported( false ), + mIsKhrCreateContextSupported( false ), + mSwapBufferCountAfterResume( 0 ), + mIsKhrPartialUpdateSupported( false ), + mPartialUpdateAvailable( partialUpdateAvailable == Integration::PartialUpdateAvailable::TRUE ), + mEglSetDamageRegionKHR( nullptr ), + mSwapBuffersWithDamage( nullptr ) { + if( mPartialUpdateAvailable ) + { + mEglSetDamageRegionKHR = reinterpret_cast< PFNEGLSETDAMAGEREGIONKHRPROC >( eglGetProcAddress( "eglSetDamageRegionKHR" ) ); + mSwapBuffersWithDamage = reinterpret_cast< PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC >( eglGetProcAddress( "eglSwapBuffersWithDamageEXT" ) ); + if( !mEglSetDamageRegionKHR || !mSwapBuffersWithDamage ) + { + mPartialUpdateAvailable = false; + DALI_LOG_ERROR("Initialization of partial update failed.\n"); + } + else + { + DALI_LOG_RELEASE_INFO("Initialization of partial update success!\n"); + } + } } EglImplementation::~EglImplementation() @@ -116,17 +142,33 @@ bool EglImplementation::InitializeGles( EGLNativeDisplayType display, bool isOwn // Query EGL extensions to check whether surfaceless context is supported const char* const extensionStr = eglQueryString( mEglDisplay, EGL_EXTENSIONS ); - std::istringstream stream(extensionStr); + std::istringstream stream( extensionStr ); std::string currentExtension; - while ( std::getline( stream, currentExtension, ' ' ) ) + uint32_t extensionCheckCount = 0; + while( std::getline( stream, currentExtension, ' ' ) && extensionCheckCount < CHECK_EXTENSION_NUMBER ) { - if ( currentExtension == EGL_KHR_SURFACELESS_CONTEXT ) + if( currentExtension == EGL_KHR_SURFACELESS_CONTEXT ) { mIsSurfacelessContextSupported = true; - break; + extensionCheckCount++; + } + if( currentExtension == EGL_KHR_CREATE_CONTEXT ) + { + mIsKhrCreateContextSupported = true; + extensionCheckCount++; + } + if( currentExtension == EGL_KHR_PARTIAL_UPDATE ) + { + mIsKhrPartialUpdateSupported = true; + extensionCheckCount++; } } + if( !mIsKhrPartialUpdateSupported ) + { + mPartialUpdateAvailable = false; + } + // We want to display this information all the time, so use the LogMessage directly Integration::Log::LogMessage(Integration::Log::DebugInfo, "EGL Information\n" " Vendor: %s\n" @@ -147,17 +189,6 @@ bool EglImplementation::CreateContext() DALI_ASSERT_ALWAYS( (mEglContext == 0) && "EGL context recreated" ); mEglContext = eglCreateContext(mEglDisplay, mEglConfig, NULL, &(mContextAttribs[0])); - if ( eglGetError() != EGL_SUCCESS ) - { - if( mGlesVersion >= 30 ) - { - eglDestroySurface( mEglDisplay, mEglContext ); - mEglContext = NULL; - mEglConfig = NULL; - DALI_LOG_ERROR("Fail to use OpenGL es 3.0. Retrying to use OpenGL es 2.0."); - return false; - } - } TEST_EGL_ERROR("eglCreateContext render thread"); DALI_ASSERT_ALWAYS( EGL_NO_CONTEXT != mEglContext && "EGL context not created" ); @@ -222,11 +253,6 @@ void EglImplementation::MakeContextCurrent( EGLSurface eglSurface, EGLContext eg if(mIsOwnSurface) { - if( mCurrentEglContext != EGL_NO_CONTEXT ) - { - glFinish(); - } - eglMakeCurrent( mEglDisplay, eglSurface, eglSurface, eglContext ); mCurrentEglContext = eglContext; @@ -254,11 +280,6 @@ void EglImplementation::MakeCurrent( EGLNativePixmapType pixmap, EGLSurface eglS if(mIsOwnSurface) { - if( mCurrentEglContext != EGL_NO_CONTEXT ) - { - glFinish(); - } - eglMakeCurrent( mEglDisplay, eglSurface, eglSurface, mEglContext ); mCurrentEglContext = mEglContext; @@ -318,11 +339,83 @@ bool EglImplementation::IsGlesInitialized() const return mGlesInitialized; } + +const char* GetEglErrorString(EGLint error) +{ + switch(error) + { + case EGL_SUCCESS: return "No error"; + case EGL_NOT_INITIALIZED: return "EGL not initialized or failed to initialize"; + case EGL_BAD_ACCESS: return "Resource inaccessible"; + case EGL_BAD_ALLOC: return "Cannot allocate resources"; + case EGL_BAD_ATTRIBUTE: return "Unrecognized attribute or attribute value"; + case EGL_BAD_CONTEXT: return "Invalid EGL context"; + case EGL_BAD_CONFIG: return "Invalid EGL frame buffer configuration"; + case EGL_BAD_CURRENT_SURFACE: return "Current surface is no longer valid"; + case EGL_BAD_DISPLAY: return "Invalid EGL display"; + case EGL_BAD_SURFACE: return "Invalid surface"; + case EGL_BAD_MATCH: return "Inconsistent arguments"; + case EGL_BAD_PARAMETER: return "Invalid argument"; + case EGL_BAD_NATIVE_PIXMAP: return "Invalid native pixmap"; + case EGL_BAD_NATIVE_WINDOW: return "Invalid native window"; + case EGL_CONTEXT_LOST: return "Context lost"; + } + return "Unknown error "; +} + void EglImplementation::SwapBuffers( EGLSurface& eglSurface ) { if ( eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context { - eglSwapBuffers( mEglDisplay, eglSurface ); +#ifndef DALI_PROFILE_UBUNTU + if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT ) + { + DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers started.\n" ); + } +#endif //DALI_PROFILE_UBUNTU+ + + if( mPartialUpdateAvailable && mSwapBuffersWithDamage ) + { + mSwapBuffersWithDamage( mEglDisplay, eglSurface, &mDamagedRectArray[0], mDamagedRectArray.size()/4 ); + } + else + { + eglSwapBuffers( mEglDisplay, eglSurface ); + } + +#ifndef DALI_PROFILE_UBUNTU + if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT ) + { + DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" ); + mSwapBufferCountAfterResume++; + } +#endif //DALI_PROFILE_UBUNTU + } +} + + +int EglImplementation::GetBufferAge( EGLSurface& eglSurface ) +{ + int bufferAge = 0; + if ( eglSurface != EGL_NO_SURFACE && mIsKhrPartialUpdateSupported ) + { + if( !eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge) ) + { + DALI_LOG_ERROR("EglImplementation::GetBufferAge() eglQuerySurface %s ", GetEglErrorString(eglGetError()) ); + } + } + return bufferAge; +} + +void EglImplementation::SetDamagedRect( std::vector damagedRectArray, EGLSurface& eglSurface ) +{ + mDamagedRectArray = damagedRectArray; + if ( eglSurface != EGL_NO_SURFACE && mPartialUpdateAvailable && mEglSetDamageRegionKHR ) + { + if( !mEglSetDamageRegionKHR( mEglDisplay, eglSurface, &damagedRectArray[0], damagedRectArray.size() / 4 ) ) + { + DALI_LOG_ERROR("EglImplementation::mEglSetDamageRegionKHR() error %s ", GetEglErrorString(eglGetError()) ); + } } } @@ -383,8 +476,7 @@ bool EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth ) configAttribs.PushBack( EGL_BLUE_SIZE ); configAttribs.PushBack( 8 ); - // In the previous code, there was a branch for ARM. - // If there is an issue in only ARM, we need to check here again. +// For underlay video playback, we also need to set the alpha value of the 24/32bit window. configAttribs.PushBack( EGL_ALPHA_SIZE ); configAttribs.PushBack( 8 ); @@ -457,7 +549,7 @@ bool EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth ) Integration::Log::LogMessage(Integration::Log::DebugInfo, "Using OpenGL es %d.%d.\n", mGlesVersion / 10, mGlesVersion % 10 ); mContextAttribs.Clear(); - if( mGlesVersion >= 30 ) + if( mIsKhrCreateContextSupported ) { mContextAttribs.Reserve(5); mContextAttribs.PushBack( EGL_CONTEXT_MAJOR_VERSION_KHR ); @@ -469,7 +561,7 @@ bool EglImplementation::ChooseConfig( bool isWindowType, ColorDepth depth ) { mContextAttribs.Reserve(3); mContextAttribs.PushBack( EGL_CONTEXT_CLIENT_VERSION ); - mContextAttribs.PushBack( 2 ); + mContextAttribs.PushBack( mGlesVersion / 10 ); } mContextAttribs.PushBack( EGL_NONE ); @@ -522,10 +614,10 @@ bool EglImplementation::ReplaceSurfaceWindow( EGLNativeWindowType window, EGLSur DestroySurface( eglSurface ); // create the EGL surface - CreateSurfaceWindow( window, mColorDepth ); + EGLSurface newEglSurface = CreateSurfaceWindow( window, mColorDepth ); // set the context to be current with the new surface - MakeContextCurrent( eglSurface, eglContext ); + MakeContextCurrent( newEglSurface, eglContext ); return contextLost; } @@ -549,6 +641,11 @@ void EglImplementation::SetGlesVersion( const int32_t glesVersion ) mGlesVersion = glesVersion; } +void EglImplementation::SetFirstFrameAfterResume() +{ + mSwapBufferCountAfterResume = 0; +} + EGLDisplay EglImplementation::GetDisplay() const { return mEglDisplay; @@ -569,6 +666,15 @@ bool EglImplementation::IsSurfacelessContextSupported() const return mIsSurfacelessContextSupported; } +void EglImplementation::WaitClient() +{ + // Wait for EGL to finish executing all rendering calls for the current context + if ( eglWaitClient() != EGL_TRUE ) + { + TEST_EGL_ERROR("eglWaitClient"); + } +} + } // namespace Adaptor } // namespace Internal