From: Joogab Yun Date: Mon, 16 Apr 2018 01:47:23 +0000 (+0900) Subject: Replaced ImageVisual to Renderer for video texture X-Git-Tag: dali_1.3.22~4 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=3eed10ef4379cfd9f8af38c1d0fc8cc084ffe80d Replaced ImageVisual to Renderer for video texture - VideoView renders video textures sequentially. - Renderer will be suitable for it. - remove native image Change-Id: I81d59582642be1732a4cf3d817e3dd63aa5e5c34 --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp index d1d35b1..03da3ff 100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp @@ -48,9 +48,10 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( }\n ); +const char* fragmentShaderPrefix( "#extension GL_OES_EGL_image_external:require\n" ); const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n + uniform samplerExternalOES sTexture;\n uniform lowp vec4 uColor;\n \n void main()\n @@ -347,6 +348,12 @@ int UtcDaliVideoViewCustomShaderForCoverage(void) VideoView videoView = VideoView::New(); DALI_TEST_CHECK( videoView ); + ToolkitApplication::DECODED_IMAGES_SUPPORTED = true; + + videoView.SetProperty( Toolkit::VideoView::Property::UNDERLAY, false ); + bool isUnderlay = videoView.GetProperty( Toolkit::VideoView::Property::UNDERLAY ).Get< bool >(); + DALI_TEST_CHECK( !isUnderlay ); + Stage::GetCurrent().Add( videoView ); videoView.SetProperty( VideoView::Property::VIDEO, "testvideo" ); @@ -528,3 +535,61 @@ int UtcDaliVideoViewPropertyDisplayMode(void) END_TEST; } + + +int UtcDaliVideoViewCustomShader(void) +{ + ToolkitTestApplication application; + tet_infoline( "VideoView with custom shader" ); + + VideoView view = VideoView::New(); + DALI_TEST_CHECK( view ); + + ToolkitApplication::DECODED_IMAGES_SUPPORTED = true; + + view.SetProperty( Toolkit::VideoView::Property::UNDERLAY, false ); + bool isUnderlay = view.GetProperty( Toolkit::VideoView::Property::UNDERLAY ).Get< bool >(); + DALI_TEST_CHECK( !isUnderlay ); + + Stage::GetCurrent().Add( view ); + view.SetProperty( VideoView::Property::VIDEO, "testvideo" ); + + /* insert custom shader */ + Property::Map customShader; + std::string fragmentShaderString; + fragmentShaderString.reserve( strlen( fragmentShaderPrefix ) + strlen( FRAGMENT_SHADER ) ); + fragmentShaderString.append( fragmentShaderPrefix ); + fragmentShaderString.append( FRAGMENT_SHADER ); + customShader.Insert( "vertexShader", VERTEX_SHADER ); + customShader.Insert( "fragmentShader", fragmentShaderString ); + + Property::Map map; + map.Insert( "shader", customShader ); + + view.SetProperty( VideoView::Property::VIDEO, map ); + + /* do render for check custom shader */ + Stage::GetCurrent().Add( view ); + view.Play(); + + application.SendNotification(); + application.Render(); + + /* get renderer */ + DALI_TEST_CHECK( view.GetRendererCount() == 1u ); + Renderer renderer = view.GetRendererAt( 0 ); + Shader shader = renderer.GetShader(); + DALI_TEST_CHECK( shader ); + + Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); + Property::Map* shaderMap = value.GetMap(); + DALI_TEST_CHECK( shaderMap ); + + Property::Value* fragment = shaderMap->Find( "fragment" ); // fragment key name from shader-impl.cpp + DALI_TEST_EQUALS( fragmentShaderString, fragment->Get(), TEST_LOCATION ); + + Property::Value* vertex = shaderMap->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( VERTEX_SHADER, vertex->Get(), TEST_LOCATION ); + + END_TEST; +} diff --git a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp index 1e6da13..3db94fa 100755 --- a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp @@ -32,11 +32,6 @@ // INTERNAL INCLUDES #include -#include -#include -#include -#include -#include #include namespace Dali @@ -84,6 +79,12 @@ const char* const RENDERING_TARGET( "renderingTarget" ); const char* const WINDOW_SURFACE_TARGET( "windowSurfaceTarget" ); const char* const NATIVE_IMAGE_TARGET( "nativeImageTarget" ); +const char* const CUSTOM_SHADER( "shader" ); +const char* const CUSTOM_VERTEX_SHADER( "vertexShader" ); +const char* const CUSTOM_FRAGMENT_SHADER( "fragmentShader" ); +const char* const DEFAULT_SAMPLER_TYPE_NAME( "sampler2D" ); +const char* const CUSTOM_SAMPLER_TYPE_NAME( "samplerExternalOES" ); + const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n uniform mediump mat4 uMvpMatrix;\n @@ -107,6 +108,29 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( }\n ); +const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + varying mediump vec2 vTexCoord;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + varying mediump vec2 sTexCoordRect;\n + void main()\n + {\n + gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n + vTexCoord = aPosition + vec2(0.5);\n + }\n +); + +const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER( + uniform lowp vec4 uColor;\n + varying mediump vec2 vTexCoord;\n + uniform samplerExternalOES sTexture;\n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n + }\n +); + } // anonymous namepsace VideoView::VideoView() @@ -140,17 +164,8 @@ void VideoView::OnInitialize() void VideoView::SetUrl( const std::string& url ) { - if( mUrl != url || !mPropertyMap.Empty() ) - { mUrl = url; mPropertyMap.Clear(); - } - - if( !mIsUnderlay ) - { - Actor self( Self() ); - Internal::InitializeVisual( self, mVisual, mNativeImage ); - } mVideoPlayer.SetUrl( mUrl ); } @@ -159,29 +174,6 @@ void VideoView::SetPropertyMap( Property::Map map ) { mPropertyMap = map; - Actor self( Self() ); - Internal::InitializeVisual( self, mVisual, mPropertyMap ); - - Property::Value* widthValue = mPropertyMap.Find( "width" ); - if( widthValue ) - { - int width; - if( widthValue->Get( width ) ) - { - mVideoSize = ImageDimensions( width, mVideoSize.GetHeight() ); - } - } - - Property::Value* heightValue = mPropertyMap.Find( "height" ); - if( heightValue ) - { - int height; - if( heightValue->Get( height ) ) - { - mVideoSize = ImageDimensions( mVideoSize.GetWidth(), height ); - } - } - Property::Value* target = map.Find( RENDERING_TARGET ); std::string targetType; @@ -196,6 +188,24 @@ void VideoView::SetPropertyMap( Property::Map map ) SetNativeImageTarget(); } + // Custom shader + Property::Value* shaderValue; + if( !map.Empty() ) + { + shaderValue = map.Find( CUSTOM_SHADER ); + + if( shaderValue ) + { + mEffectPropertyMap = *( shaderValue->GetMap() ); + } + } + + if( mTextureRenderer && !mEffectPropertyMap.Empty() ) + { + Dali::Shader shader = CreateShader(); + mTextureRenderer.SetShader( shader ); + } + RelayoutRequest(); } @@ -204,7 +214,7 @@ std::string VideoView::GetUrl() return mUrl; } -void VideoView::SetLooping(bool looping) +void VideoView::SetLooping( bool looping ) { mVideoPlayer.SetLooping( looping ); } @@ -218,7 +228,7 @@ void VideoView::Play() { if( mIsUnderlay ) { - Self().AddRenderer( mRenderer ); + Self().AddRenderer( mOverlayRenderer ); } mVideoPlayer.Play(); @@ -285,7 +295,7 @@ void VideoView::EmitSignalFinish() { if( mIsUnderlay ) { - Self().RemoveRenderer( mRenderer ); + Self().RemoveRenderer( mOverlayRenderer ); } if ( !mFinishedSignal.Empty() ) @@ -387,27 +397,8 @@ void VideoView::SetProperty( BaseObject* object, Property::Index index, const Pr } else if( value.Get( map ) ) { - Property::Value* shaderValue = map.Find( Toolkit::Visual::Property::SHADER, CUSTOM_SHADER ); - - if( map.Count() > 1u || !shaderValue ) - { impl.SetPropertyMap( map ); } - else if( impl.mVisual && map.Count() == 1u && shaderValue ) - { - Property::Map shaderMap; - if( shaderValue->Get( shaderMap ) ) - { - Internal::Visual::Base& visual = Toolkit::GetImplementation( impl.mVisual ); - visual.SetCustomShader( shaderMap ); - if( videoView.OnStage() ) - { - visual.SetOffStage( videoView ); - visual.SetOnStage( videoView ); - } - } - } - } break; } case Toolkit::VideoView::Property::LOOPING: @@ -541,31 +532,19 @@ Property::Value VideoView::GetProperty( BaseObject* object, Property::Index prop void VideoView::SetDepthIndex( int depthIndex ) { - if( mVisual ) + if( mTextureRenderer ) { - mVisual.SetDepthIndex( depthIndex ); + mTextureRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depthIndex ); } } void VideoView::OnStageConnection( int depth ) { - if( mVisual ) - { - CustomActor self = Self(); - Toolkit::GetImplementation(mVisual).SetOnStage( self ); - } - Control::OnStageConnection( depth ); } void VideoView::OnStageDisconnection() { - if( mVisual ) - { - CustomActor self = Self(); - Toolkit::GetImplementation(mVisual).SetOffStage( self ); - } - Control::OnStageDisconnection(); } @@ -615,12 +594,6 @@ void VideoView::SetWindowSurfaceTarget() Actor self = Self(); int curPos = mVideoPlayer.GetPlayPosition(); - if( mVisual ) - { - Toolkit::GetImplementation(mVisual).SetOffStage(self); - mVisual.Reset(); - } - if( mIsPlay ) { mVideoPlayer.Pause(); @@ -633,21 +606,26 @@ void VideoView::SetWindowSurfaceTarget() mSizeUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea ); mScaleUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea ); + if( mTextureRenderer ) + { + self.RemoveRenderer( mTextureRenderer ); + } + mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle() ); mVideoPlayer.SetUrl( mUrl ); - if( !mRenderer ) + if( !mOverlayRenderer ) { // For underlay rendering mode, video display area have to be transparent. Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - mRenderer = Renderer::New( geometry, shader ); + mOverlayRenderer = Renderer::New( geometry, shader ); - mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON ); - mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE ); - mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ZERO ); - mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE ); - mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ZERO ); + mOverlayRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON ); + mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE ); + mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ZERO ); + mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE ); + mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ZERO ); } if( mIsPlay ) @@ -676,8 +654,11 @@ void VideoView::SetNativeImageTarget() } Actor self( Self() ); - self.RemoveRenderer( mRenderer ); - Dali::Stage::GetCurrent().KeepRendering( 0.0f ); + + if( mOverlayRenderer ) + { + self.RemoveRenderer( mOverlayRenderer ); + } self.RemovePropertyNotification( mPositionUpdateNotification ); self.RemovePropertyNotification( mSizeUpdateNotification ); @@ -687,14 +668,28 @@ void VideoView::SetNativeImageTarget() Any source; Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source ); - mNativeImage = Dali::NativeImage::New( *nativeImageSourcePtr ); + mNativeTexture = Dali::Texture::New( *nativeImageSourcePtr ); + + if( !mTextureRenderer ) + { + Dali::Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); + Dali::Shader shader = CreateShader(); + Dali::TextureSet textureSet = Dali::TextureSet::New(); + textureSet.SetTexture( 0u, mNativeTexture ); + + mTextureRenderer = Renderer::New( geometry, shader ); + mTextureRenderer.SetTextures( textureSet ); + } + else + { + Dali::TextureSet textureSet = mTextureRenderer.GetTextures(); + textureSet.SetTexture( 0u, mNativeTexture ); + } + Self().AddRenderer( mTextureRenderer ); mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr ); mVideoPlayer.SetUrl( mUrl ); - Internal::InitializeVisual( self, mVisual, mNativeImage ); - Self().RemoveRenderer( mRenderer ); - if( mIsPlay ) { Play(); @@ -787,6 +782,62 @@ int VideoView::GetDisplayMode() const return static_cast< int >( mVideoPlayer.GetDisplayMode() ); } +Dali::Shader VideoView::CreateShader() +{ + std::string fragmentShader = "#extension GL_OES_EGL_image_external:require\n"; + std::string vertexShader; + std::string customFragmentShader; + bool checkShader = false; + + if( !mEffectPropertyMap.Empty() ) + { + Property::Value* vertexShaderValue = mEffectPropertyMap.Find( CUSTOM_VERTEX_SHADER ); + if( vertexShaderValue ) + { + checkShader = GetStringFromProperty( *vertexShaderValue, vertexShader ); + } + + if( !vertexShaderValue || !checkShader ) + { + vertexShader = VERTEX_SHADER_TEXTURE; + } + + Property::Value* fragmentShaderValue = mEffectPropertyMap.Find( CUSTOM_FRAGMENT_SHADER ); + if( fragmentShaderValue ) + { + checkShader = GetStringFromProperty( *fragmentShaderValue, customFragmentShader ); + + if( checkShader ) + { + fragmentShader = customFragmentShader; + } + } + + if( !fragmentShaderValue || !checkShader ) + { + fragmentShader += FRAGMENT_SHADER_TEXTURE; + } + } + else + { + vertexShader = VERTEX_SHADER_TEXTURE; + fragmentShader += FRAGMENT_SHADER_TEXTURE; + } + + return Dali::Shader::New( vertexShader, fragmentShader ); +} + +bool VideoView::GetStringFromProperty( const Dali::Property::Value& value, std::string& output ) +{ + bool extracted = false; + if( value.Get( output ) ) + { + extracted = true; + } + + return extracted; +} + } // namespace Internal } // namespace toolkit diff --git a/dali-toolkit/internal/controls/video-view/video-view-impl.h b/dali-toolkit/internal/controls/video-view/video-view-impl.h index 728539a..bed7c9f 100755 --- a/dali-toolkit/internal/controls/video-view/video-view-impl.h +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.h @@ -25,9 +25,11 @@ #include #include #include +#include +#include +#include // INTERNAL INCLUDES -#include #include #include @@ -283,26 +285,49 @@ private: // From Control private: - // Undefined + /** + * @brief Construct a new VideoView. + */ VideoView( const VideoView& videoView ); + // Undefined assignment operator. VideoView& operator=( const VideoView& videoView ); + /** + * @brief SetWindowSurfaceTarget for underlay video playback. + */ void SetWindowSurfaceTarget(); + /** + * @brief SetNativeImageTarget for native image video playback. + */ void SetNativeImageTarget(); + /** + * @brief CreateShader for native image target + */ + Dali::Shader CreateShader(); + + /** + * @brief Checks whether the property has a string value. + * @param Property value + * @param String output + * @return true if the output was found + */ + bool GetStringFromProperty( const Dali::Property::Value& value, std::string& output ); + private: Dali::VideoPlayer mVideoPlayer; Dali::ImageDimensions mVideoSize; - Toolkit::Visual::Base mVisual; Dali::Property::Map mPropertyMap; - Dali::NativeImage mNativeImage; ///< Native image handle for video rendering by texture streaming + Dali::Property::Map mEffectPropertyMap; + Dali::Texture mNativeTexture; Dali::Toolkit::VideoView::VideoViewSignalType mFinishedSignal; std::string mUrl; Dali::DisplayArea mDisplayArea; - Dali::Renderer mRenderer; + Dali::Renderer mOverlayRenderer; + Dali::Renderer mTextureRenderer; Dali::PropertyNotification mPositionUpdateNotification; Dali::PropertyNotification mSizeUpdateNotification; Dali::PropertyNotification mScaleUpdateNotification;