From: Cheng-Shiun Tsai Date: Fri, 13 Nov 2020 14:54:16 +0000 (+0000) Subject: [dali_2.0.1] Merge branch 'devel/master' X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6f0ffcfd5697457ea73154ae014c6419b4a24cdc;hp=0366343efc863a305b2131559b17d6ad026394fe;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git [dali_2.0.1] Merge branch 'devel/master' Change-Id: I3f065ad7ddbcc699653c9c630541b87ef0c4671f --- diff --git a/automated-tests/images/circle1-LA88.png b/automated-tests/images/circle1-LA88.png new file mode 100644 index 0000000..a958733 Binary files /dev/null and b/automated-tests/images/circle1-LA88.png differ diff --git a/automated-tests/patch-coverage.pl b/automated-tests/patch-coverage.pl index 3a97dac..b3cf098 100755 --- a/automated-tests/patch-coverage.pl +++ b/automated-tests/patch-coverage.pl @@ -1105,7 +1105,7 @@ sub calc_patch_coverage_percentage my $percent = 0; if($total_exec > 0) { $percent = 100 * $total_covered_lines / $total_exec; } - return [ $total_exec, $percent ]; + return [ $total_exec, $percent, $total_covered_lines ]; } # @@ -1417,6 +1417,7 @@ elsif( ! $opt_quiet ) print RESET; } +printf("Line Coverage: %d/%d\n", $percentref->[2], $percentref->[0]); printf("Percentage of change covered: %5.2f%\n", $percent); exit($percent<90); diff --git a/automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp b/automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp index 8a323ba..dcc6a3a 100644 --- a/automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp +++ b/automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp @@ -25,9 +25,19 @@ // Internal headers are allowed here #include +#include using namespace Dali; using namespace Dali::Internal::Adaptor; + +namespace +{ + +// resolution: 96*96, pixel format: LA88 +const char* TEST_IMAGE_LA88 = TEST_IMAGE_DIR "/circle1-LA88.png"; + +} // namespace + void utc_dali_internal_pixel_data_startup() { test_return_value = TET_UNDEF; @@ -167,6 +177,38 @@ int UtcDaliPixelManipulation02(void) END_TEST; } +int UtcDaliPixelManipulationLA88(void) +{ + tet_infoline("Testing Dali::Internal::AdaptorManipulation Read/WriteChannel - LA88 format"); + + Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile(TEST_IMAGE_LA88); + DALI_TEST_CHECK(pixelBuffer); + + unsigned int width = pixelBuffer.GetWidth(); + unsigned int height = pixelBuffer.GetHeight(); + DALI_TEST_EQUALS(width, 96u, TEST_LOCATION); + DALI_TEST_EQUALS(height, 96u, TEST_LOCATION); + DALI_TEST_EQUALS(pixelBuffer.GetPixelFormat(), Pixel::LA88, TEST_LOCATION); + + unsigned char* pixel = pixelBuffer.GetBuffer(); + unsigned int value; + + value = Dali::Internal::Adaptor::ReadChannel(&pixel[0], Dali::Pixel::LA88, Dali::Internal::Adaptor::LUMINANCE); + DALI_TEST_EQUALS(value, 0x0, TEST_LOCATION); + value = Dali::Internal::Adaptor::ReadChannel(&pixel[0], Dali::Pixel::LA88, Dali::Internal::Adaptor::ALPHA); + DALI_TEST_EQUALS(value, 0x0, TEST_LOCATION); + + // Get center pixel + unsigned int stride = width * Pixel::GetBytesPerPixel(Dali::Pixel::LA88); + unsigned int center = height / 2 * stride + width / 2 * Pixel::GetBytesPerPixel(Dali::Pixel::LA88); + value = Dali::Internal::Adaptor::ReadChannel(&pixel[center], Dali::Pixel::LA88, Dali::Internal::Adaptor::LUMINANCE); + DALI_TEST_EQUALS(value, 0x0, TEST_LOCATION); + value = Dali::Internal::Adaptor::ReadChannel(&pixel[center], Dali::Pixel::LA88, Dali::Internal::Adaptor::ALPHA); + DALI_TEST_EQUALS(value, 0xFF, TEST_LOCATION); + + END_TEST; +} + int UtcDaliPixelManipulation03N(void) { tet_infoline("Testing Dali::Internal::AdaptorManipulation Read/WriteChannel"); diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp index a694eeb..9e8c7a8 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp @@ -112,6 +112,31 @@ bool TestGlAbstraction::IsSurfacelessContextSupported() const return true; } +bool TestGlAbstraction::IsAdvancedBlendEquationSupported() +{ + return true; +} + +bool TestGlAbstraction::IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) +{ + return true; +} + +std::string TestGlAbstraction::GetShaderVersionPrefix() +{ + return std::string(""); +} + +std::string TestGlAbstraction::GetVertexShaderPrefix() +{ + return std::string(""); +} + +std::string TestGlAbstraction::GetFragmentShaderPrefix() +{ + return std::string(""); +} + bool TestGlAbstraction::TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const { return ((imageGlFormat == GL_RGB) && (textureGlFormat == GL_RGBA)); diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h index 99dca10..861f4ae 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h @@ -61,6 +61,16 @@ public: bool IsSurfacelessContextSupported() const override; + bool IsAdvancedBlendEquationSupported() override; + + bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override; + + std::string GetShaderVersionPrefix(); + + std::string GetVertexShaderPrefix(); + + std::string GetFragmentShaderPrefix(); + bool TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const override; /* OpenGL ES 2.0 */ @@ -1889,6 +1899,10 @@ public: { } + inline void BlendBarrier(void) + { + } + private: inline void AddUniformCallToTraceStack(GLint location, std::string& value) { diff --git a/dali/internal/adaptor/android/framework-android.cpp b/dali/internal/adaptor/android/framework-android.cpp index f91f596..3212f4d 100644 --- a/dali/internal/adaptor/android/framework-android.cpp +++ b/dali/internal/adaptor/android/framework-android.cpp @@ -180,7 +180,7 @@ struct Framework::Impl { if ( callback() ) // keep the callback { - AddIdle( callback.timeout, callback.data, callback.callback ); + AddIdle( callback.timeout, callback.data, callback.callback, callback.id ); } } @@ -199,21 +199,30 @@ struct Framework::Impl } } - unsigned int AddIdle( int timeout, void* data, bool ( *callback )( void *data ) ) + unsigned int AddIdle( int timeout, void* data, bool ( *callback )( void *data ) , unsigned int existingId = 0 ) { - ++mIdleId; - if( mIdleId == 0 ) + unsigned int chosenId; + if (existingId) + { + chosenId = existingId; + } + else { ++mIdleId; + if( mIdleId == 0 ) + { + ++mIdleId; + } + chosenId = mIdleId; } - mIdleCallbacks.push( IdleCallback( timeout, mIdleId, data, callback ) ); + mIdleCallbacks.push( IdleCallback( timeout, chosenId, data, callback ) ); // To wake up the idle pipe and to trigger OnIdle int8_t msg = 1; write( mIdleWritePipe, &msg, sizeof( msg ) ); - return mIdleId; + return chosenId; } void RemoveIdle( unsigned int id ) diff --git a/dali/internal/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index 502ec75..bc70e9b 100755 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -427,6 +427,13 @@ void Adaptor::Start() Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize ); } + // Set cached isAdvancedBlendEquationSupported + GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match + auto eglGraphics = static_cast( graphics ); + GlImplementation& mGLES = eglGraphics->GetGlesInterface(); + mGLES.SetIsAdvancedBlendEquationSupported( mConfigurationManager->IsAdvancedBlendEquationSupported() ); + mGLES.SetShadingLanguageVersion( mConfigurationManager->GetShadingLanguageVersion() ); + ProcessCoreEvents(); // Ensure any startup messages are processed. // Initialize the image loader plugin diff --git a/dali/internal/adaptor/common/combined-update-render-controller.cpp b/dali/internal/adaptor/common/combined-update-render-controller.cpp index eb28975..a0f690e 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -561,7 +561,9 @@ void CombinedUpdateRenderController::UpdateRenderThread() } } - eglGraphics->GetGlesInterface().ContextCreated(); + GlImplementation& gles = eglGraphics->GetGlesInterface(); + gles.ContextCreated(); + eglGraphics->SetGlesVersion( gles.GetGlesVersion() ); // Tell core it has a context mCore.ContextCreated(); diff --git a/dali/internal/graphics/gles/egl-implementation.cpp b/dali/internal/graphics/gles/egl-implementation.cpp index 984b4e1..ee4e08e 100755 --- a/dali/internal/graphics/gles/egl-implementation.cpp +++ b/dali/internal/graphics/gles/egl-implementation.cpp @@ -37,6 +37,7 @@ namespace { const uint32_t THRESHOLD_SWAPBUFFER_COUNT = 5; const uint32_t CHECK_EXTENSION_NUMBER = 4; + const uint32_t EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT = 15; 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"; @@ -131,38 +132,51 @@ bool EglImplementation::InitializeGles( EGLNativeDisplayType display, bool isOwn mIsOwnSurface = isOwnSurface; } - // Query EGL extensions to check whether surfaceless context is supported + const char* const versionStr = eglQueryString( mEglDisplay, EGL_VERSION ); const char* const extensionStr = eglQueryString( mEglDisplay, EGL_EXTENSIONS ); - std::istringstream stream( extensionStr ); - std::string currentExtension; + + // Query EGL extensions to check whether required extensions are supported + std::istringstream versionStream( versionStr ); + std::string majorVersion, minorVersion; + std::getline( versionStream, majorVersion, '.' ); + std::getline( versionStream, minorVersion ); uint32_t extensionCheckCount = 0; + if( stoul( majorVersion ) * 10 + stoul( minorVersion ) >= EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT ) + { + mIsSurfacelessContextSupported = true; + mIsKhrCreateContextSupported = true; + extensionCheckCount += 2; + } + + std::istringstream stream(extensionStr); + std::string currentExtension; bool isKhrPartialUpdateSupported = false; bool isKhrSwapBuffersWithDamageSupported = false; - while( std::getline( stream, currentExtension, ' ' ) && extensionCheckCount < CHECK_EXTENSION_NUMBER ) + while(std::getline(stream, currentExtension, ' ') && extensionCheckCount < CHECK_EXTENSION_NUMBER) { - if( currentExtension == EGL_KHR_SURFACELESS_CONTEXT ) + if(currentExtension == EGL_KHR_SURFACELESS_CONTEXT && !mIsSurfacelessContextSupported) { mIsSurfacelessContextSupported = true; extensionCheckCount++; } - if( currentExtension == EGL_KHR_CREATE_CONTEXT ) + if(currentExtension == EGL_KHR_CREATE_CONTEXT && !mIsKhrCreateContextSupported) { mIsKhrCreateContextSupported = true; extensionCheckCount++; } - if( currentExtension == EGL_KHR_PARTIAL_UPDATE ) + if(currentExtension == EGL_KHR_PARTIAL_UPDATE) { isKhrPartialUpdateSupported = true; extensionCheckCount++; } - if( currentExtension == EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE ) + if(currentExtension == EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE) { isKhrSwapBuffersWithDamageSupported = true; extensionCheckCount++; } } - if( !isKhrPartialUpdateSupported || !isKhrSwapBuffersWithDamageSupported ) + if(!isKhrPartialUpdateSupported || !isKhrSwapBuffersWithDamageSupported) { mPartialUpdateRequired = false; } @@ -178,7 +192,7 @@ bool EglImplementation::InitializeGles( EGLNativeDisplayType display, bool isOwn " Extensions: %s\n", mPartialUpdateRequired, eglQueryString( mEglDisplay, EGL_VENDOR ), - eglQueryString( mEglDisplay, EGL_VERSION ), + versionStr, eglQueryString( mEglDisplay, EGL_CLIENT_APIS ), extensionStr); diff --git a/dali/internal/graphics/gles/egl-implementation.h b/dali/internal/graphics/gles/egl-implementation.h index 6d9e3c9..8a23ef1 100644 --- a/dali/internal/graphics/gles/egl-implementation.h +++ b/dali/internal/graphics/gles/egl-implementation.h @@ -65,7 +65,7 @@ public: public: /** - * (Called from ECoreX::RenderSurface, not RenderThread, so not in i/f, hence, not virtual) + * (Called from RenderSurface, not RenderThread, so not in i/f, hence, not virtual) * Initialize GL * @param display The display * @param isOwnSurface whether the surface is own or not diff --git a/dali/internal/graphics/gles/gl-extensions.cpp b/dali/internal/graphics/gles/gl-extensions.cpp index 429cbd5..f61d9dd 100644 --- a/dali/internal/graphics/gles/gl-extensions.cpp +++ b/dali/internal/graphics/gles/gl-extensions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -33,17 +33,17 @@ namespace Internal namespace Adaptor { -namespace ECoreX -{ - GlExtensions::GlExtensions() : #ifdef GL_EXT_discard_framebuffer - mGlDiscardFramebuffer( NULL ), + mGlDiscardFramebuffer( nullptr ), #endif #ifdef GL_OES_get_program_binary - mGlGetProgramBinaryOES( NULL ), - mGlProgramBinaryOES( NULL ), + mGlGetProgramBinaryOES( nullptr ), + mGlProgramBinaryOES( nullptr ), +#endif +#ifdef GL_KHR_blend_equation_advanced + mBlendBarrierKHR( nullptr ), #endif mInitialized( false ) { @@ -118,6 +118,27 @@ void GlExtensions::ProgramBinaryOES(GLuint program, GLenum binaryFormat, const G #endif } +bool GlExtensions::BlendBarrierKHR() +{ + // initialize extension on first use as on some hw platforms a context + // has to be bound for the extensions to return correct pointer + if( !mInitialized ) + { + Initialize(); + } + +#ifdef GL_KHR_blend_equation_advanced + if (mBlendBarrierKHR) + { + mBlendBarrierKHR(); + return true; + } + return false; +#endif + + return false; +} + void GlExtensions::Initialize() { mInitialized = true; @@ -130,9 +151,11 @@ void GlExtensions::Initialize() mGlGetProgramBinaryOES = reinterpret_cast< PFNGLGETPROGRAMBINARYOESPROC >( eglGetProcAddress("glGetProgramBinaryOES") ); mGlProgramBinaryOES = reinterpret_cast< PFNGLPROGRAMBINARYOESPROC >( eglGetProcAddress("glProgramBinaryOES") ); #endif -} -} // namespace ECoreX +#ifdef GL_KHR_blend_equation_advanced + mBlendBarrierKHR = reinterpret_cast< PFNGLBLENDBARRIERKHRPROC >( eglGetProcAddress("glBlendBarrierKHR") ); +#endif +} } // namespace Adaptor diff --git a/dali/internal/graphics/gles/gl-extensions.h b/dali/internal/graphics/gles/gl-extensions.h index b3a8085..887c714 100644 --- a/dali/internal/graphics/gles/gl-extensions.h +++ b/dali/internal/graphics/gles/gl-extensions.h @@ -34,9 +34,6 @@ namespace Internal namespace Adaptor { -namespace ECoreX -{ - /** * GlExtensions class provides GL extensions support */ @@ -91,6 +88,12 @@ public: */ void ProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); + /** + * KHR extension + * Specify a boundary between passes when using advanced blend equations. + */ + bool BlendBarrierKHR (); + private: /** @@ -107,12 +110,14 @@ private: PFNGLPROGRAMBINARYOESPROC mGlProgramBinaryOES; #endif +#ifdef GL_KHR_blend_equation_advanced + PFNGLBLENDBARRIERKHRPROC mBlendBarrierKHR; +#endif + bool mInitialized; }; -} // namespace ECoreX - } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/graphics/gles/gl-implementation.h b/dali/internal/graphics/gles/gl-implementation.h index 1cd7ed9..5f1078e 100644 --- a/dali/internal/graphics/gles/gl-implementation.h +++ b/dali/internal/graphics/gles/gl-implementation.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_GL_IMPLEMENTATION_H /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -22,8 +22,10 @@ #include #include #include +#include #include #include +#include // INTERNAL INCLUDES #include @@ -39,6 +41,24 @@ namespace Internal namespace Adaptor { +namespace +{ + +const int32_t INITIAL_GLES_VERSION = 30; +const int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32; +const char* KHR_BLEND_EQUATION_ADVANCED = "GL_KHR_blend_equation_advanced"; + +const char* FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX = + "#extension GL_KHR_blend_equation_advanced : enable\n" + + "#if GL_KHR_blend_equation_advanced==1 || __VERSION__>=320\n" + " layout(blend_support_all_equations) out;\n" + "#endif\n"; + +const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING = + "out mediump vec4 fragColor;\n"; +} + /** * GlImplementation is a concrete implementation for GlAbstraction. * The class provides an OpenGL-ES 2.0 or 3.0 implementation. @@ -49,11 +69,16 @@ class GlImplementation : public Dali::Integration::GlAbstraction public: GlImplementation() - : mGlesVersion( 30 ), + : mContextCreatedWaitCondition(), + mMaxTextureSize( 0 ), + mVertexShaderPrefix(""), + mGlesVersion( INITIAL_GLES_VERSION ), + mShadingLanguageVersion( 100 ), + mShadingLanguageVersionCached( false ), mIsSurfacelessContextSupported( false ), - mIsContextCreated( false ), - mContextCreatedWaitCondition(), - mMaxTextureSize( 0 ) + mIsAdvancedBlendEquationSupportedCached( false ), + mIsAdvancedBlendEquationSupported( false ), + mIsContextCreated( false ) { mImpl.reset( new Gles3Implementation() ); } @@ -74,16 +99,64 @@ public: { glGetIntegerv( GL_MAX_TEXTURE_SIZE, &mMaxTextureSize ); - if( !mIsContextCreated ) + GLint majorVersion, minorVersion; + glGetIntegerv( GL_MAJOR_VERSION, &majorVersion ); + glGetIntegerv( GL_MINOR_VERSION, &minorVersion ); + mGlesVersion = majorVersion * 10 + minorVersion; + + if( mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED ) + { + mIsAdvancedBlendEquationSupported = true; + } + else { - mContextCreatedWaitCondition.Notify(); + // when mIsAdvancedBlendEquationSupported is cached, we don't need to check all the extensions. + if( !mIsAdvancedBlendEquationSupportedCached ) + { + const char* const extensionStr = reinterpret_cast(glGetString(GL_EXTENSIONS)); + std::istringstream stream(extensionStr); + std::string currentExtension; + while(std::getline(stream, currentExtension, ' ')) + { + if(currentExtension == KHR_BLEND_EQUATION_ADVANCED) + { + mIsAdvancedBlendEquationSupported = true; + break; + } + } + } + } + + if(!mShadingLanguageVersionCached) + { + std::istringstream shadingLanguageVersionStream(reinterpret_cast(glGetString(GL_SHADING_LANGUAGE_VERSION))); + std::string token; + uint32_t tokenCount = 0; + while(std::getline(shadingLanguageVersionStream, token, ' ')) + { + if(tokenCount == 3 && token == "ES") + { + std::getline(shadingLanguageVersionStream, token, '.'); + mShadingLanguageVersion = std::atoi(token.c_str()); + mShadingLanguageVersion *= 100; + std::getline(shadingLanguageVersionStream, token, '.'); + mShadingLanguageVersion += std::atoi(token.c_str()); + break; + } + tokenCount++; + } + } + + { + ConditionalWait::ScopedLock lock( mContextCreatedWaitCondition ); + mIsContextCreated = true; + mContextCreatedWaitCondition.Notify( lock ); } - mIsContextCreated = true; } void SetGlesVersion( const int32_t glesVersion ) { - if( mGlesVersion != glesVersion ) + if( mGlesVersion / 10 != glesVersion / 10 ) { mGlesVersion = glesVersion; if( mGlesVersion >= 30 ) @@ -107,6 +180,131 @@ public: return mIsSurfacelessContextSupported; } + void SetIsAdvancedBlendEquationSupported(const bool isSupported) + { + mIsAdvancedBlendEquationSupported = isSupported; + mIsAdvancedBlendEquationSupportedCached = true; + } + + bool IsAdvancedBlendEquationSupported() + { + ConditionalWait::ScopedLock lock( mContextCreatedWaitCondition ); + if(!mIsContextCreated && !mIsAdvancedBlendEquationSupportedCached) + { + mContextCreatedWaitCondition.Wait( lock ); + } + return mIsAdvancedBlendEquationSupported; + } + + bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) + { + switch(blendEquation) + { + case DevelBlendEquation::ADD: + case DevelBlendEquation::SUBTRACT: + case DevelBlendEquation::REVERSE_SUBTRACT: + { + return true; + } + case DevelBlendEquation::MIN: + case DevelBlendEquation::MAX: + { + return (GetGlesVersion() >= 30); + } + case DevelBlendEquation::MULTIPLY: + case DevelBlendEquation::SCREEN: + case DevelBlendEquation::OVERLAY: + case DevelBlendEquation::DARKEN: + case DevelBlendEquation::LIGHTEN: + case DevelBlendEquation::COLOR_DODGE: + case DevelBlendEquation::COLOR_BURN: + case DevelBlendEquation::HARD_LIGHT: + case DevelBlendEquation::SOFT_LIGHT: + case DevelBlendEquation::DIFFERENCE: + case DevelBlendEquation::EXCLUSION: + case DevelBlendEquation::HUE: + case DevelBlendEquation::SATURATION: + case DevelBlendEquation::COLOR: + case DevelBlendEquation::LUMINOSITY: + { + return IsAdvancedBlendEquationSupported(); + } + + default: + { + return false; + } + } + + return false; + } + + std::string GetShaderVersionPrefix() + { + if(mShaderVersionPrefix == "") + { + mShaderVersionPrefix = "#version " + std::to_string( GetShadingLanguageVersion() ); + if(GetShadingLanguageVersion() < 300) + { + mShaderVersionPrefix += "\n"; + } + else + { + mShaderVersionPrefix += " es\n"; + } + } + return mShaderVersionPrefix; + } + + std::string GetVertexShaderPrefix() + { + if(mVertexShaderPrefix == "") + { + mVertexShaderPrefix = GetShaderVersionPrefix(); + + if(GetShadingLanguageVersion() < 300) + { + mVertexShaderPrefix += "#define INPUT attribute\n"; + mVertexShaderPrefix += "#define OUTPUT varying\n"; + } + else + { + mVertexShaderPrefix += "#define INPUT in\n"; + mVertexShaderPrefix += "#define OUTPUT out\n"; + } + } + return mVertexShaderPrefix; + } + + std::string GetFragmentShaderPrefix() + { + if(mFragmentShaderPrefix == "") + { + mFragmentShaderPrefix = GetShaderVersionPrefix(); + + if(GetShadingLanguageVersion() < 300) + { + mFragmentShaderPrefix += "#define INPUT varying\n"; + mFragmentShaderPrefix += "#define OUT_COLOR gl_FragColor\n"; + mFragmentShaderPrefix += "#define TEXTURE texture2D\n"; + } + else + { + mFragmentShaderPrefix += "#define INPUT in\n"; + mFragmentShaderPrefix += "#define OUT_COLOR fragColor\n"; + mFragmentShaderPrefix += "#define TEXTURE texture\n"; + + if(IsAdvancedBlendEquationSupported()) + { + mFragmentShaderPrefix += FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX; + } + + mFragmentShaderPrefix += FRAGMENT_SHADER_OUTPUT_COLOR_STRING; + } + } + return mFragmentShaderPrefix; + } + bool TextureRequiresConverting( const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage ) const override { bool convert = ( ( imageGlFormat == GL_RGB ) && ( textureGlFormat == GL_RGBA ) ); @@ -120,13 +318,40 @@ public: int GetMaxTextureSize() { + ConditionalWait::ScopedLock lock( mContextCreatedWaitCondition ); if( !mIsContextCreated ) { - mContextCreatedWaitCondition.Wait(); + mContextCreatedWaitCondition.Wait( lock ); } return mMaxTextureSize; } + int GetGlesVersion() + { + ConditionalWait::ScopedLock lock( mContextCreatedWaitCondition ); + if( !mIsContextCreated ) + { + mContextCreatedWaitCondition.Wait( lock ); + } + return mGlesVersion; + } + + void SetShadingLanguageVersion( int shadingLanguageVersion ) + { + mShadingLanguageVersion = shadingLanguageVersion; + mShadingLanguageVersionCached = true; + } + + int GetShadingLanguageVersion() + { + ConditionalWait::ScopedLock lock( mContextCreatedWaitCondition ); + if( !mIsContextCreated && !mShadingLanguageVersionCached ) + { + mContextCreatedWaitCondition.Wait( lock ); + } + return mShadingLanguageVersion; + } + /* OpenGL ES 2.0 */ void ActiveTexture( GLenum texture ) override @@ -1361,13 +1586,29 @@ public: mImpl->GetInternalformativ( target, internalformat, pname, bufSize, params ); } + void BlendBarrier(void) + { + if(mIsAdvancedBlendEquationSupported) + { + mImpl->BlendBarrier(); + } + } + private: - int32_t mGlesVersion; - bool mIsSurfacelessContextSupported; - bool mIsContextCreated; - ConditionalWait mContextCreatedWaitCondition; - GLint mMaxTextureSize; std::unique_ptr mImpl; + + ConditionalWait mContextCreatedWaitCondition; + GLint mMaxTextureSize; + std::string mShaderVersionPrefix; + std::string mVertexShaderPrefix; + std::string mFragmentShaderPrefix; + int32_t mGlesVersion; + int32_t mShadingLanguageVersion; + bool mShadingLanguageVersionCached; + bool mIsSurfacelessContextSupported; + bool mIsAdvancedBlendEquationSupportedCached; + bool mIsAdvancedBlendEquationSupported; + bool mIsContextCreated; }; } // namespace Adaptor diff --git a/dali/internal/graphics/gles/gles-abstraction.h b/dali/internal/graphics/gles/gles-abstraction.h index 8dc63e6..6334b27 100644 --- a/dali/internal/graphics/gles/gles-abstraction.h +++ b/dali/internal/graphics/gles/gles-abstraction.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_GLES_ABSTRACTION_H /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -244,6 +244,8 @@ public: virtual void TexStorage3D( GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth ) = 0; virtual void GetInternalformativ( GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params ) = 0; + + virtual void BlendBarrier( void ) = 0; }; } // namespace Adaptor diff --git a/dali/internal/graphics/gles/gles2-implementation.h b/dali/internal/graphics/gles/gles2-implementation.h index 5bab59b..cee1c77 100644 --- a/dali/internal/graphics/gles/gles2-implementation.h +++ b/dali/internal/graphics/gles/gles2-implementation.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_GLES2_IMPLEMENTATION_H /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -574,8 +574,13 @@ public: DALI_LOG_ERROR( "glGetInternalformativ is not supported in OpenGL es 2.0\n" ); } + void BlendBarrier( void ) override + { + DALI_LOG_ERROR( "BlendBarrier is not supported in OpenGL es 2.0\n" ); + } + private: - ECoreX::GlExtensions mGlExtensions; + GlExtensions mGlExtensions; }; } // namespace Adaptor diff --git a/dali/internal/graphics/gles/gles3-implementation.h b/dali/internal/graphics/gles/gles3-implementation.h index ace3849..173cd6a 100644 --- a/dali/internal/graphics/gles/gles3-implementation.h +++ b/dali/internal/graphics/gles/gles3-implementation.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_GLES3_IMPLEMENTATION_H /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include @@ -560,6 +561,17 @@ public: { glGetInternalformativ( target, internalformat, pname, bufSize, params ); } + + void BlendBarrier( void ) override + { + if(!mGlExtensions.BlendBarrierKHR()) + { + glBlendBarrier(); + } + } + +private: + GlExtensions mGlExtensions; }; } // namespace Adaptor diff --git a/dali/internal/imaging/common/pixel-manipulation.cpp b/dali/internal/imaging/common/pixel-manipulation.cpp index fa5094a..fff8604 100644 --- a/dali/internal/imaging/common/pixel-manipulation.cpp +++ b/dali/internal/imaging/common/pixel-manipulation.cpp @@ -33,7 +33,7 @@ namespace constexpr Channel ALPHA_CHANNEL_ONLY[] = {ALPHA}; constexpr Channel LUMINANCE_CHANNEL_ONLY[] = {LUMINANCE}; -constexpr Channel LUMINANCE_ALPHA_CHANNELS[] = {ALPHA, LUMINANCE}; +constexpr Channel LUMINANCE_ALPHA_CHANNELS[] = {LUMINANCE, ALPHA}; constexpr Channel RGB_CHANNELS[] = {RED, GREEN, BLUE}; constexpr Channel BGR_CHANNELS[] = {BLUE, GREEN, RED}; constexpr Channel RGBA_CHANNELS[] = {RED, GREEN, BLUE, ALPHA}; diff --git a/dali/internal/system/common/configuration-manager.cpp b/dali/internal/system/common/configuration-manager.cpp index 63b62dc..8ab98aa 100644 --- a/dali/internal/system/common/configuration-manager.cpp +++ b/dali/internal/system/common/configuration-manager.cpp @@ -43,6 +43,8 @@ namespace const std::string SYSTEM_CACHE_FILE = "gpu-environment.conf"; const std::string DALI_ENV_MULTIPLE_WINDOW_SUPPORT = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT"; +const std::string DALI_BLEND_EQUATION_ADVANCED_SUPPORT = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT"; +const std::string DALI_GLSL_VERSION = "DALI_GLSL_VERSION"; bool RetrieveKeyFromConfigFile( std::iostream& stream, const std::string& key, std::string& value ) { @@ -80,9 +82,13 @@ ConfigurationManager::ConfigurationManager( std::string systemCachePath, EglGrap mEglGraphics( eglGraphics ), mThreadController( threadController ), mMaxTextureSize( 0u ), + mGlslVersion( 0u), mIsMultipleWindowSupported( true ), - mMaxTextureSizeCached( false ) , - mIsMultipleWindowSupportedCached( false ) + mIsAdvancedBlendEquationSupported( true ), + mMaxTextureSizeCached( false ), + mIsMultipleWindowSupportedCached( false ), + mIsAdvancedBlendEquationSupportedCached( false ), + mGlslVersionCached( false ) { } @@ -104,16 +110,30 @@ void ConfigurationManager::RetrieveKeysFromConfigFile( const std::string& config mMaxTextureSizeCached = true; } + if( !mGlslVersionCached && + RetrieveKeyFromConfigFile( stream, DALI_GLSL_VERSION, value ) ) + { + mGlslVersion = std::atoi( value.c_str() ); + mGlslVersionCached = true; + } + if( !mIsMultipleWindowSupportedCached && RetrieveKeyFromConfigFile( stream, DALI_ENV_MULTIPLE_WINDOW_SUPPORT, value ) ) { mIsMultipleWindowSupported = std::atoi( value.c_str() ); mIsMultipleWindowSupportedCached = true; } + + if( !mIsAdvancedBlendEquationSupportedCached && + RetrieveKeyFromConfigFile( stream, DALI_BLEND_EQUATION_ADVANCED_SUPPORT, value ) ) + { + mIsAdvancedBlendEquationSupported = std::atoi( value.c_str() ); + mIsAdvancedBlendEquationSupportedCached = true; + } } } -unsigned int ConfigurationManager::GetMaxTextureSize() +uint32_t ConfigurationManager::GetMaxTextureSize() { if( !mMaxTextureSizeCached ) { @@ -141,6 +161,43 @@ unsigned int ConfigurationManager::GetMaxTextureSize() return mMaxTextureSize; } +uint32_t ConfigurationManager::GetShadingLanguageVersion() +{ + if ( !mGlslVersionCached ) + { + RetrieveKeysFromConfigFile( mSystemCacheFilePath ); + + if ( !mGlslVersionCached ) + { + EglImplementation& eglImpl = mEglGraphics->GetEglImplementation(); + if ( !eglImpl.IsGlesInitialized() ) + { + // Wait until GLES is initialised, but this will happen once. + // This method blocks until the render thread has initialised the graphics. + mThreadController->WaitForGraphicsInitialization(); + } + + // Query from GLES and save the cache + mGlslVersion = mEglGraphics->GetGlesInterface().GetShadingLanguageVersion(); + DALI_LOG_ERROR("mGlslVersion : %d\n", mGlslVersion); + mGlslVersionCached = true; + + Dali::FileStream configFile( mSystemCacheFilePath, Dali::FileStream::READ | Dali::FileStream::APPEND | Dali::FileStream::TEXT ); + std::fstream& stream = dynamic_cast( configFile.GetStream() ); + if ( stream.is_open() ) + { + stream << DALI_GLSL_VERSION << " " << mGlslVersion << std::endl; + } + else + { + DALI_LOG_ERROR( "Fail to open file : %s\n", mSystemCacheFilePath.c_str() ); + } + } + } + + return mGlslVersion; +} + bool ConfigurationManager::IsMultipleWindowSupported() { if ( !mIsMultipleWindowSupportedCached ) @@ -177,6 +234,42 @@ bool ConfigurationManager::IsMultipleWindowSupported() return mIsMultipleWindowSupported; } +bool ConfigurationManager::IsAdvancedBlendEquationSupported() +{ + if ( !mIsAdvancedBlendEquationSupportedCached ) + { + RetrieveKeysFromConfigFile( mSystemCacheFilePath ); + + if ( !mIsAdvancedBlendEquationSupportedCached ) + { + EglImplementation& eglImpl = mEglGraphics->GetEglImplementation(); + if ( !eglImpl.IsGlesInitialized() ) + { + // Wait until GLES is initialised, but this will happen once. + // This method blocks until the render thread has initialised the graphics. + mThreadController->WaitForGraphicsInitialization(); + } + + // Query from GLES and save the cache + mIsAdvancedBlendEquationSupported = mEglGraphics->GetGlesInterface().IsAdvancedBlendEquationSupported(); + mIsAdvancedBlendEquationSupportedCached = true; + + Dali::FileStream configFile( mSystemCacheFilePath, Dali::FileStream::READ | Dali::FileStream::APPEND | Dali::FileStream::TEXT ); + std::fstream& stream = dynamic_cast( configFile.GetStream() ); + if ( stream.is_open() ) + { + stream << DALI_BLEND_EQUATION_ADVANCED_SUPPORT << " " << mIsAdvancedBlendEquationSupported << std::endl; + } + else + { + DALI_LOG_ERROR( "Fail to open file : %s\n", mSystemCacheFilePath.c_str() ); + } + } + } + + return mIsAdvancedBlendEquationSupported; +} + } // Adaptor } // Internal diff --git a/dali/internal/system/common/configuration-manager.h b/dali/internal/system/common/configuration-manager.h index a6721ee..a3375ac 100644 --- a/dali/internal/system/common/configuration-manager.h +++ b/dali/internal/system/common/configuration-manager.h @@ -37,7 +37,8 @@ class ThreadController; /** * This class retrieves and caches the system configuration. - * + * Some of the methods in this class can block system until GL has been initialized, + * only at the first time the DALi application is launched in the system. */ class ConfigurationManager { @@ -62,7 +63,13 @@ public: * @brief Get the maximum texture size. * @return The maximum texture size */ - unsigned int GetMaxTextureSize(); + uint32_t GetMaxTextureSize(); + + /** + * @brief Get the GLSL version that the system supports + * @return the GLSL version. + */ + uint32_t GetShadingLanguageVersion(); /** * @brief Check whether multiple window is supported @@ -70,6 +77,12 @@ public: */ bool IsMultipleWindowSupported(); + /** + * @brief Check whether blend equation advanced (extension) is supported + * @return Whether blend equation advanced (extension is supported + */ + bool IsAdvancedBlendEquationSupported(); + // Deleted copy constructor. ConfigurationManager( const ConfigurationManager& ) = delete; @@ -88,9 +101,13 @@ private: // Data EglGraphics* mEglGraphics; ///< EGL graphics ThreadController* mThreadController; ///< The thread controller unsigned int mMaxTextureSize; ///< The largest texture that the GL can handle + unsigned int mGlslVersion; ///< The GLSL version that the system supports. bool mIsMultipleWindowSupported:1; ///< Whether multiple window is supported by the GLES + bool mIsAdvancedBlendEquationSupported:1; ///< Whether blend equation advanced (extension) is supported by the GLES bool mMaxTextureSizeCached:1; ///< Whether we have checked the maximum texture size bool mIsMultipleWindowSupportedCached:1; ///< Whether we have checked the support of multiple window + bool mIsAdvancedBlendEquationSupportedCached:1;///< Whether we have checked the support of blend equation advanced (extension) + bool mGlslVersionCached:1; ///< Whether we have checked the GLSL version }; } // Adaptor diff --git a/dali/public-api/adaptor-framework/tts-player.h b/dali/public-api/adaptor-framework/tts-player.h index c148f3f..d4f4137 100644 --- a/dali/public-api/adaptor-framework/tts-player.h +++ b/dali/public-api/adaptor-framework/tts-player.h @@ -42,7 +42,6 @@ class TtsPlayer; /** * @brief The Text-to-speech (TTS) Player. - * @deprecated Instead of this class use Dali::Accessibility::Say() method * @SINCE_1_0.0 */ class DALI_ADAPTOR_API TtsPlayer : public BaseHandle diff --git a/dali/public-api/dali-adaptor-version.cpp b/dali/public-api/dali-adaptor-version.cpp index 3c446ed..33ba5ea 100644 --- a/dali/public-api/dali-adaptor-version.cpp +++ b/dali/public-api/dali-adaptor-version.cpp @@ -27,7 +27,7 @@ namespace Dali { const unsigned int ADAPTOR_MAJOR_VERSION = 2; const unsigned int ADAPTOR_MINOR_VERSION = 0; -const unsigned int ADAPTOR_MICRO_VERSION = 0; +const unsigned int ADAPTOR_MICRO_VERSION = 1; const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index e829bcf..f516875 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -17,7 +17,7 @@ Name: dali2-adaptor Summary: The DALi Tizen Adaptor -Version: 2.0.0 +Version: 2.0.1 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT @@ -476,7 +476,7 @@ exit 0 %post pushd %{_libdir} -for i in mobile tv wearable ivi; do [[ -f libdali2-adaptor.so.$i ]] && ln -sf libdali2-adaptor.so.$i libdali2-adaptor.so.2.0.0; done +for i in mobile tv wearable ivi; do [[ -f libdali2-adaptor.so.$i ]] && ln -sf libdali2-adaptor.so.$i libdali2-adaptor.so.2.0.1; done popd /sbin/ldconfig exit 0 @@ -496,7 +496,7 @@ exit 0 %post profile_mobile %if "%{?profile}" != "mobile" pushd %{_libdir} -ln -sf libdali2-adaptor.so.mobile libdali2-adaptor.so.2.0.0 +ln -sf libdali2-adaptor.so.mobile libdali2-adaptor.so.2.0.1 popd %endif /sbin/ldconfig @@ -514,7 +514,7 @@ exit 0 %post profile_tv %if "%{?profile}" != "tv" pushd %{_libdir} -ln -sf libdali2-adaptor.so.tv libdali2-adaptor.so.2.0.0 +ln -sf libdali2-adaptor.so.tv libdali2-adaptor.so.2.0.1 popd %endif /sbin/ldconfig @@ -532,7 +532,7 @@ exit 0 %post profile_wearable %if "%{?profile}" != "wearable" pushd %{_libdir} -ln -sf libdali2-adaptor.so.wearable libdali2-adaptor.so.2.0.0 +ln -sf libdali2-adaptor.so.wearable libdali2-adaptor.so.2.0.1 popd %endif /sbin/ldconfig @@ -550,7 +550,7 @@ exit 0 %post profile_ivi %if "%{?profile}" != "ivi" pushd %{_libdir} -ln -sf libdali2-adaptor.so.ivi libdali2-adaptor.so.2.0.0 +ln -sf libdali2-adaptor.so.ivi libdali2-adaptor.so.2.0.1 popd %endif /sbin/ldconfig @@ -586,7 +586,7 @@ exit 0 %defattr(-,root,root,-) %{_libdir}/libdali2-adaptor.so %{_libdir}/libdali2-adaptor.so.2 -%{_libdir}/libdali2-adaptor.so.2.0.0 +%{_libdir}/libdali2-adaptor.so.2.0.1 #################################################