X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Frendering%2Fshader-impl.cpp;h=3c3dcf944ee6b4af61ae2457b20e660e26c3443f;hb=24cf3ec005ffb58f751fe8f1ff41beb52128917d;hp=ecf64cb70e84c35d192ee2c04d02aaf879499782;hpb=b745b2700ef2150f05bc91b71e05f512f300e776;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/rendering/shader-impl.cpp b/dali/internal/event/rendering/shader-impl.cpp index ecf64cb..3c3dcf9 100644 --- a/dali/internal/event/rendering/shader-impl.cpp +++ b/dali/internal/event/rendering/shader-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 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,14 +20,10 @@ // INTERNAL INCLUDES #include -#include // Dali::ShaderEffect::GeometryHints // TODO: MESH_REWORK REMOVE -#include // Dali::Shader - -#include // Dali::Internal::ObjectHelper +#include #include // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END #include #include -#include #include namespace Dali @@ -43,102 +39,128 @@ namespace */ DALI_PROPERTY_TABLE_BEGIN DALI_PROPERTY( "program", MAP, true, false, false, Dali::Shader::Property::PROGRAM ) -DALI_PROPERTY( "shader-hints", INTEGER, true, false, true, Dali::Shader::Property::SHADER_HINTS ) -DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX ) +DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ShaderDefaultProperties ) + +Dali::Scripting::StringEnum ShaderHintsTable[] = + { { "NONE", Dali::Shader::Hint::NONE}, + { "OUTPUT_IS_TRANSPARENT", Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT}, + { "MODIFIES_GEOMETRY", Dali::Shader::Hint::MODIFIES_GEOMETRY} + }; -const ObjectImplHelper SHADER_IMPL = { DEFAULT_PROPERTY_DETAILS }; +const uint32_t ShaderHintsTableSize = static_cast( sizeof( ShaderHintsTable ) / sizeof( ShaderHintsTable[0] ) ); BaseHandle Create() { return Dali::BaseHandle(); } -TypeRegistration mType( typeid( Dali::Shader ), typeid( Dali::Handle ), Create ); +TypeRegistration mType( typeid( Dali::Shader ), typeid( Dali::Handle ), Create, ShaderDefaultProperties ); -} // unnamed namespace +#define TOKEN_STRING(x) (#x) -ShaderPtr Shader::New( const std::string& vertexShader, - const std::string& fragmentShader, - Dali::Shader::ShaderHints hints ) +void AppendString(std::string& to, const std::string& append) { - //TODO: MESH_REWORK - ShaderPtr shader( new Shader() ); - shader->Initialize( vertexShader, fragmentShader, hints ); - return shader; + if(to.size()) + { + to += ","; + } + to += append; } -const SceneGraph::Shader* Shader::GetShaderSceneObject() const +Property::Value HintString(const Dali::Shader::Hint::Value& hints) { - return mSceneObject; -} + std::string s; -unsigned int Shader::GetDefaultPropertyCount() const -{ - return SHADER_IMPL.GetDefaultPropertyCount(); -} + if(hints == Dali::Shader::Hint::NONE) + { + s = "NONE"; + } -void Shader::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const -{ - SHADER_IMPL.GetDefaultPropertyIndices( indices ); -} + if(hints & Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT) + { + AppendString(s, "OUTPUT_IS_TRANSPARENT"); + } -const char* Shader::GetDefaultPropertyName(Property::Index index) const -{ - return SHADER_IMPL.GetDefaultPropertyName( index ); -} + if(hints & Dali::Shader::Hint::MODIFIES_GEOMETRY) + { + AppendString(s, "MODIFIES_GEOMETRY"); + } -Property::Index Shader::GetDefaultPropertyIndex( const std::string& name ) const -{ - return SHADER_IMPL.GetDefaultPropertyIndex( name ); + return Property::Value(s); } -bool Shader::IsDefaultPropertyWritable( Property::Index index ) const -{ - return SHADER_IMPL.IsDefaultPropertyWritable( index ); -} +} // unnamed namespace -bool Shader::IsDefaultPropertyAnimatable( Property::Index index ) const +ShaderPtr Shader::New( const std::string& vertexShader, + const std::string& fragmentShader, + Dali::Shader::Hint::Value hints ) { - return SHADER_IMPL.IsDefaultPropertyAnimatable( index ); -} + // create scene object first so it's guaranteed to exist for the event side + auto sceneObject = new SceneGraph::Shader( hints ); + OwnerPointer< SceneGraph::Shader > transferOwnership( sceneObject ); + // pass the pointer to base for message passing + ShaderPtr shader( new Shader( sceneObject ) ); + // transfer scene object ownership to update manager + auto&& services = shader->GetEventThreadServices(); + SceneGraph::UpdateManager& updateManager = services.GetUpdateManager(); + AddShaderMessage( updateManager, transferOwnership ); -bool Shader::IsDefaultPropertyAConstraintInput( Property::Index index ) const -{ - return SHADER_IMPL.IsDefaultPropertyAConstraintInput( index ); + services.RegisterObject( shader.Get() ); + shader->SetShader( vertexShader, fragmentShader, hints ); + + return shader; } -Property::Type Shader::GetDefaultPropertyType( Property::Index index ) const +const SceneGraph::Shader& Shader::GetShaderSceneObject() const { - return SHADER_IMPL.GetDefaultPropertyType( index ); + return static_cast( GetSceneObject() ); } -void Shader::SetDefaultProperty( Property::Index index, - const Property::Value& propertyValue ) +void Shader::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue ) { switch(index) { case Dali::Shader::Property::PROGRAM: { - // @todo MESH_REWORK Set program again? - DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" ); - break; - } - case Dali::Shader::Property::SHADER_HINTS: - { - DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" ); + if( propertyValue.GetType() == Property::MAP ) + { + const Dali::Property::Map* map = propertyValue.GetMap(); + if( map ) + { + std::string vertex; + std::string fragment; + Dali::Shader::Hint::Value hints(Dali::Shader::Hint::NONE); + + if( Property::Value* value = map->Find("vertex") ) + { + vertex = value->Get(); + } + + if( Property::Value* value = map->Find("fragment") ) + { + fragment = value->Get(); + } + + if( Property::Value* value = map->Find("hints") ) + { + static_cast( // ignore return + Scripting::GetEnumeration< Dali::Shader::Hint::Value >(value->Get().c_str(), + ShaderHintsTable, ShaderHintsTableSize, hints) + ); + } + + SetShader( vertex, fragment, hints ); + } + } + else + { + DALI_LOG_WARNING( "Shader program property should be a map\n" ); + } break; } } } -void Shader::SetSceneGraphProperty( Property::Index index, - const PropertyMetadata& entry, - const Property::Value& value ) -{ - SHADER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value ); - OnPropertySet(index, value); -} - Property::Value Shader::GetDefaultProperty( Property::Index index ) const { Property::Value value; @@ -147,12 +169,14 @@ Property::Value Shader::GetDefaultProperty( Property::Index index ) const { case Dali::Shader::Property::PROGRAM: { - DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" ); - break; - } - case Dali::Shader::Property::SHADER_HINTS: - { - DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" ); + Dali::Property::Map map; + if( mShaderData ) + { + map["vertex"] = Property::Value(mShaderData->GetVertexShader()); + map["fragment"] = Property::Value(mShaderData->GetFragmentShader()); + map["hints"] = HintString(mShaderData->GetHints()); + } + value = map; break; } } @@ -160,110 +184,31 @@ Property::Value Shader::GetDefaultProperty( Property::Index index ) const return value; } -const SceneGraph::PropertyOwner* Shader::GetPropertyOwner() const -{ - return mSceneObject; -} - -const SceneGraph::PropertyOwner* Shader::GetSceneObject() const +Property::Value Shader::GetDefaultPropertyCurrentValue( Property::Index index ) const { - return mSceneObject; + return GetDefaultProperty( index ); // Event-side only properties } -const SceneGraph::PropertyBase* Shader::GetSceneObjectAnimatableProperty( Property::Index index ) const +Shader::Shader( const SceneGraph::Shader* sceneObject ) +: Object( sceneObject ), + mShaderData( nullptr ) { - DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" ); - const SceneGraph::PropertyBase* property = NULL; - - property = SHADER_IMPL.GetRegisteredSceneGraphProperty( this, - &Shader::FindAnimatableProperty, - &Shader::FindCustomProperty, - index ); - - if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT ) - { - DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" ); - } - - return property; } -const PropertyInputImpl* Shader::GetSceneObjectInputProperty( Property::Index index ) const +void Shader::SetShader( const std::string& vertexSource, + const std::string& fragmentSource, + Dali::Shader::Hint::Value hints ) { - const PropertyInputImpl* property = NULL; - - const SceneGraph::PropertyBase* baseProperty = - SHADER_IMPL.GetRegisteredSceneGraphProperty( this, - &Shader::FindAnimatableProperty, - &Shader::FindCustomProperty, - index ); - property = static_cast( baseProperty ); - - if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT ) - { - if( index == Dali::Shader::Property::SHADER_HINTS ) - { - // @todo MESH_REWORK - return the property - } - else - { - DALI_ASSERT_ALWAYS( 0 && "Property is not a valid constraint input" ); - } - } - - return property; -} - -int Shader::GetPropertyComponentIndex( Property::Index index ) const -{ - return Property::INVALID_COMPONENT_INDEX; -} - -Shader::Shader() -: mSceneObject( NULL ) -{ -} - -void Shader::Initialize( - const std::string& vertexSource, - const std::string& fragmentSource, - Dali::Shader::ShaderHints hints ) -{ - EventThreadServices& eventThreadServices = GetEventThreadServices(); - SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); - - // @todo MESH_REWORK - Pass hints directly to a new scene graph shader - int effectHint = Dali::ShaderEffect::HINT_NONE; - if( hints & Dali::Shader::HINT_OUTPUT_IS_TRANSPARENT ) - { - effectHint |= Dali::ShaderEffect::HINT_BLENDING; - } - - if( hints & Dali::Shader::HINT_REQUIRES_SELF_DEPTH_TEST ) - { - effectHint |= Dali::ShaderEffect::HINT_DEPTH_BUFFER; - } - - if( (hints & Dali::Shader::HINT_MODIFIES_GEOMETRY) == 0x0 ) - { - effectHint |= Dali::ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY; - } - Dali::ShaderEffect::GeometryHints shaderEffectHint = static_cast( effectHint ); - - mSceneObject = new SceneGraph::Shader( shaderEffectHint ); - - // Add to update manager - AddShaderMessage( updateManager, *mSceneObject ); - - // Try to load a precompiled shader binary for the source pair: + // Try to load a pre-compiled shader binary for the source pair: ThreadLocalStorage& tls = ThreadLocalStorage::Get(); ShaderFactory& shaderFactory = tls.GetShaderFactory(); size_t shaderHash; - Internal::ShaderDataPtr shaderData = shaderFactory.Load( vertexSource, fragmentSource, shaderHash ); + mShaderData = shaderFactory.Load( vertexSource, fragmentSource, hints, shaderHash ); // Add shader program to scene-object using a message to the UpdateManager - SetShaderProgramMessage( updateManager, *mSceneObject, shaderData, (hints & Dali::Shader::HINT_MODIFIES_GEOMETRY) != 0x0 ); - eventThreadServices.RegisterObject( this ); + EventThreadServices& eventThreadServices = GetEventThreadServices(); + SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); + SetShaderProgramMessage( updateManager, GetShaderSceneObject(), mShaderData, (hints & Dali::Shader::Hint::MODIFIES_GEOMETRY) != 0x0 ); } Shader::~Shader() @@ -272,7 +217,7 @@ Shader::~Shader() { EventThreadServices& eventThreadServices = GetEventThreadServices(); SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); - RemoveShaderMessage( updateManager, *mSceneObject); + RemoveShaderMessage( updateManager, &GetShaderSceneObject() ); eventThreadServices.UnregisterObject( this ); }