2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "border-visual.h"
22 #include <dali/integration-api/debug.h>
23 #include <dali/devel-api/rendering/renderer-devel.h>
26 #include <dali-toolkit/public-api/visuals/border-visual-properties.h>
27 #include <dali-toolkit/public-api/visuals/visual-properties.h>
28 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
29 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
30 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
31 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
32 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
45 const char * const POSITION_ATTRIBUTE_NAME("aPosition");
46 const char * const DRIFT_ATTRIBUTE_NAME("aDrift");
47 const char * const INDEX_NAME("indices");
50 BorderVisualPtr BorderVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
52 BorderVisualPtr borderVisualPtr( new BorderVisual( factoryCache ) );
53 borderVisualPtr->SetProperties( properties );
54 borderVisualPtr->Initialize();
55 return borderVisualPtr;
58 BorderVisual::BorderVisual( VisualFactoryCache& factoryCache )
59 : Visual::Base( factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::BORDER ),
60 mBorderColor( Color::TRANSPARENT ),
62 mBorderColorIndex( Property::INVALID_INDEX ),
63 mBorderSizeIndex( Property::INVALID_INDEX ),
64 mAntiAliasing( false )
68 BorderVisual::~BorderVisual()
72 void BorderVisual::DoSetProperties( const Property::Map& propertyMap )
74 for( Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter )
76 KeyValuePair keyValue = propertyMap.GetKeyValue( iter );
77 if( keyValue.first.type == Property::Key::INDEX )
79 DoSetProperty( keyValue.first.indexKey, keyValue.second );
83 if( keyValue.first == COLOR_NAME )
85 DoSetProperty( Toolkit::BorderVisual::Property::COLOR, keyValue.second );
87 else if( keyValue.first == SIZE_NAME )
89 DoSetProperty( Toolkit::BorderVisual::Property::SIZE, keyValue.second );
91 else if( keyValue.first == ANTI_ALIASING )
93 DoSetProperty( Toolkit::BorderVisual::Property::ANTI_ALIASING, keyValue.second );
99 void BorderVisual::DoSetProperty( Dali::Property::Index index,
100 const Dali::Property::Value& value )
104 case Toolkit::BorderVisual::Property::COLOR:
106 if( !value.Get( mBorderColor ) )
108 DALI_LOG_ERROR("BorderVisual: borderColor property has incorrect type\n");
112 case Toolkit::BorderVisual::Property::SIZE:
114 if( !value.Get( mBorderSize ) )
116 DALI_LOG_ERROR("BorderVisual: borderSize property has incorrect type\n");
120 case Toolkit::BorderVisual::Property::ANTI_ALIASING:
122 if( !value.Get( mAntiAliasing ) )
124 DALI_LOG_ERROR("BorderVisual: antiAliasing property has incorrect type\n");
131 void BorderVisual::DoSetOnScene( Actor& actor )
133 mBorderColorIndex = mImpl->mRenderer.RegisterProperty( Toolkit::BorderVisual::Property::COLOR, COLOR_NAME, mBorderColor );
134 if( mBorderColor.a < 1.f || mAntiAliasing )
136 mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
138 mBorderSizeIndex = mImpl->mRenderer.RegisterProperty( Toolkit::BorderVisual::Property::SIZE, SIZE_NAME, mBorderSize );
140 actor.AddRenderer( mImpl->mRenderer );
142 // Border Visual Generated and ready to display
143 ResourceReady( Toolkit::Visual::ResourceStatus::READY );
146 void BorderVisual::DoCreatePropertyMap( Property::Map& map ) const
149 map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::BORDER );
150 map.Insert( Toolkit::BorderVisual::Property::COLOR, mBorderColor );
151 map.Insert( Toolkit::BorderVisual::Property::SIZE, mBorderSize );
152 map.Insert( Toolkit::BorderVisual::Property::ANTI_ALIASING, mAntiAliasing );
155 void BorderVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
160 void BorderVisual::OnSetTransform()
162 if( mImpl->mRenderer )
164 mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
168 void BorderVisual::OnInitialize()
170 Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::BORDER_GEOMETRY );
173 geometry = CreateBorderGeometry();
174 mFactoryCache.SaveGeometry( VisualFactoryCache::BORDER_GEOMETRY, geometry );
177 Shader shader = GetBorderShader();
178 mImpl->mRenderer = Renderer::New( geometry, shader );
180 //Register transform properties
181 mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
184 Shader BorderVisual::GetBorderShader()
189 shader = mFactoryCache.GetShader( VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING );
192 shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + SHADER_BORDER_VISUAL_ANTI_ALIASING_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_BORDER_VISUAL_ANTI_ALIASING_SHADER_FRAG.data() );
193 mFactoryCache.SaveShader( VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING, shader );
198 shader = mFactoryCache.GetShader( VisualFactoryCache::BORDER_SHADER );
201 shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + SHADER_BORDER_VISUAL_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_BORDER_VISUAL_SHADER_FRAG.data() );
202 mFactoryCache.SaveShader( VisualFactoryCache::BORDER_SHADER, shader );
210 * Vertices and triangles of the border geometry:
212 * vertex position = aPosition*uSize.xy + aDrift*uBorderSize;
225 Geometry BorderVisual::CreateBorderGeometry()
227 const float halfWidth = 0.5f;
228 const float halfHeight = 0.5f;
229 struct BorderVertex { Vector2 position; Vector2 drift;};
230 BorderVertex borderVertexData[16] =
232 { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f) },
233 { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 0.f) },
234 { Vector2(halfWidth, -halfHeight), Vector2(-1.f, 0.f) },
235 { Vector2(halfWidth, -halfHeight), Vector2(0.f, 0.f) },
237 { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 1.f) },
238 { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 1.f) },
239 { Vector2(halfWidth, -halfHeight), Vector2(-1.f, 1.f) },
240 { Vector2(halfWidth, -halfHeight), Vector2(0.f, 1.f) },
242 { Vector2(-halfWidth, halfHeight), Vector2(0.f, -1.f) },
243 { Vector2(-halfWidth, halfHeight), Vector2(1.f, -1.f) },
244 { Vector2(halfWidth, halfHeight), Vector2(-1.f, -1.f) },
245 { Vector2(halfWidth, halfHeight), Vector2(0.f, -1.f) },
247 { Vector2(-halfWidth, halfHeight), Vector2(0.f, 0.f) },
248 { Vector2(-halfWidth, halfHeight), Vector2(1.f, 0.f) },
249 { Vector2(halfWidth, halfHeight), Vector2(-1.f, 0.f) },
250 { Vector2(halfWidth, halfHeight), Vector2(0.f, 0.f) },
253 Property::Map borderVertexFormat;
254 borderVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
255 borderVertexFormat[DRIFT_ATTRIBUTE_NAME] = Property::VECTOR2;
256 VertexBuffer borderVertices = VertexBuffer::New( borderVertexFormat );
257 borderVertices.SetData( borderVertexData, 16 );
260 unsigned short indexData[24] = { 1,5,2,6,3,7,7,6,11,10,15,14,14,10,13,9,12,8,8,9,4,5,0,1};
262 // Create the geometry object
263 Geometry geometry = Geometry::New();
264 geometry.AddVertexBuffer( borderVertices );
265 geometry.SetIndexBuffer( indexData, sizeof(indexData)/sizeof(indexData[0]) );
266 geometry.SetType( Geometry::TRIANGLE_STRIP );
271 } // namespace Internal
273 } // namespace Toolkit