2 * Copyright (c) 2020 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 return borderVisualPtr;
57 BorderVisual::BorderVisual( VisualFactoryCache& factoryCache )
58 : Visual::Base( factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::BORDER ),
59 mBorderColor( Color::TRANSPARENT ),
61 mBorderColorIndex( Property::INVALID_INDEX ),
62 mBorderSizeIndex( Property::INVALID_INDEX ),
63 mAntiAliasing( false )
67 BorderVisual::~BorderVisual()
71 void BorderVisual::DoSetProperties( const Property::Map& propertyMap )
73 for( Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter )
75 KeyValuePair keyValue = propertyMap.GetKeyValue( iter );
76 if( keyValue.first.type == Property::Key::INDEX )
78 DoSetProperty( keyValue.first.indexKey, keyValue.second );
82 if( keyValue.first == COLOR_NAME )
84 DoSetProperty( Toolkit::BorderVisual::Property::COLOR, keyValue.second );
86 else if( keyValue.first == SIZE_NAME )
88 DoSetProperty( Toolkit::BorderVisual::Property::SIZE, keyValue.second );
90 else if( keyValue.first == ANTI_ALIASING )
92 DoSetProperty( Toolkit::BorderVisual::Property::ANTI_ALIASING, keyValue.second );
98 void BorderVisual::DoSetProperty( Dali::Property::Index index,
99 const Dali::Property::Value& value )
103 case Toolkit::BorderVisual::Property::COLOR:
105 if( !value.Get( mBorderColor ) )
107 DALI_LOG_ERROR("BorderVisual: borderColor property has incorrect type\n");
111 case Toolkit::BorderVisual::Property::SIZE:
113 if( !value.Get( mBorderSize ) )
115 DALI_LOG_ERROR("BorderVisual: borderSize property has incorrect type\n");
119 case Toolkit::BorderVisual::Property::ANTI_ALIASING:
121 if( !value.Get( mAntiAliasing ) )
123 DALI_LOG_ERROR("BorderVisual: antiAliasing property has incorrect type\n");
130 void BorderVisual::DoSetOnScene( Actor& actor )
132 InitializeRenderer();
134 mBorderColorIndex = mImpl->mRenderer.RegisterProperty( Toolkit::BorderVisual::Property::COLOR, COLOR_NAME, mBorderColor );
135 if( mBorderColor.a < 1.f || mAntiAliasing )
137 mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
139 mBorderSizeIndex = mImpl->mRenderer.RegisterProperty( Toolkit::BorderVisual::Property::SIZE, SIZE_NAME, mBorderSize );
141 actor.AddRenderer( mImpl->mRenderer );
143 // Border Visual Generated and ready to display
144 ResourceReady( Toolkit::Visual::ResourceStatus::READY );
147 void BorderVisual::DoCreatePropertyMap( Property::Map& map ) const
150 map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::BORDER );
151 map.Insert( Toolkit::BorderVisual::Property::COLOR, mBorderColor );
152 map.Insert( Toolkit::BorderVisual::Property::SIZE, mBorderSize );
153 map.Insert( Toolkit::BorderVisual::Property::ANTI_ALIASING, mAntiAliasing );
156 void BorderVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
161 void BorderVisual::OnSetTransform()
163 if( mImpl->mRenderer )
165 mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
169 void BorderVisual::InitializeRenderer()
171 Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::BORDER_GEOMETRY );
174 geometry = CreateBorderGeometry();
175 mFactoryCache.SaveGeometry( VisualFactoryCache::BORDER_GEOMETRY, geometry );
178 Shader shader = GetBorderShader();
179 mImpl->mRenderer = Renderer::New( geometry, shader );
181 //Register transform properties
182 mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
185 Shader BorderVisual::GetBorderShader()
190 shader = mFactoryCache.GetShader( VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING );
193 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() );
194 mFactoryCache.SaveShader( VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING, shader );
199 shader = mFactoryCache.GetShader( VisualFactoryCache::BORDER_SHADER );
202 shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + SHADER_BORDER_VISUAL_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_BORDER_VISUAL_SHADER_FRAG.data() );
203 mFactoryCache.SaveShader( VisualFactoryCache::BORDER_SHADER, shader );
211 * Vertices and triangles of the border geometry:
213 * vertex position = aPosition*uSize.xy + aDrift*uBorderSize;
226 Geometry BorderVisual::CreateBorderGeometry()
228 const float halfWidth = 0.5f;
229 const float halfHeight = 0.5f;
230 struct BorderVertex { Vector2 position; Vector2 drift;};
231 BorderVertex borderVertexData[16] =
233 { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f) },
234 { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 0.f) },
235 { Vector2(halfWidth, -halfHeight), Vector2(-1.f, 0.f) },
236 { Vector2(halfWidth, -halfHeight), Vector2(0.f, 0.f) },
238 { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 1.f) },
239 { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 1.f) },
240 { Vector2(halfWidth, -halfHeight), Vector2(-1.f, 1.f) },
241 { Vector2(halfWidth, -halfHeight), Vector2(0.f, 1.f) },
243 { Vector2(-halfWidth, halfHeight), Vector2(0.f, -1.f) },
244 { Vector2(-halfWidth, halfHeight), Vector2(1.f, -1.f) },
245 { Vector2(halfWidth, halfHeight), Vector2(-1.f, -1.f) },
246 { Vector2(halfWidth, halfHeight), Vector2(0.f, -1.f) },
248 { Vector2(-halfWidth, halfHeight), Vector2(0.f, 0.f) },
249 { Vector2(-halfWidth, halfHeight), Vector2(1.f, 0.f) },
250 { Vector2(halfWidth, halfHeight), Vector2(-1.f, 0.f) },
251 { Vector2(halfWidth, halfHeight), Vector2(0.f, 0.f) },
254 Property::Map borderVertexFormat;
255 borderVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
256 borderVertexFormat[DRIFT_ATTRIBUTE_NAME] = Property::VECTOR2;
257 VertexBuffer borderVertices = VertexBuffer::New( borderVertexFormat );
258 borderVertices.SetData( borderVertexData, 16 );
261 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};
263 // Create the geometry object
264 Geometry geometry = Geometry::New();
265 geometry.AddVertexBuffer( borderVertices );
266 geometry.SetIndexBuffer( indexData, sizeof(indexData)/sizeof(indexData[0]) );
267 geometry.SetType( Geometry::TRIANGLE_STRIP );
272 } // namespace Internal
274 } // namespace Toolkit