2 * Copyright (c) 2022 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/devel-api/rendering/renderer-devel.h>
23 #include <dali/integration-api/debug.h>
26 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
27 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
28 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
29 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
30 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
31 #include <dali-toolkit/public-api/visuals/border-visual-properties.h>
32 #include <dali-toolkit/public-api/visuals/visual-properties.h>
42 const int CUSTOM_PROPERTY_COUNT(7); // 5 transform properties + color,size
44 const char* const POSITION_ATTRIBUTE_NAME("aPosition");
45 const char* const DRIFT_ATTRIBUTE_NAME("aDrift");
46 const char* const INDEX_NAME("indices");
49 BorderVisualPtr BorderVisual::New(VisualFactoryCache& factoryCache, const Property::Map& properties)
51 BorderVisualPtr borderVisualPtr(new BorderVisual(factoryCache));
52 borderVisualPtr->SetProperties(properties);
53 borderVisualPtr->Initialize();
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),
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 mBorderColorIndex = mImpl->mRenderer.RegisterProperty(Toolkit::BorderVisual::Property::COLOR, COLOR_NAME, mBorderColor);
133 if(mBorderColor.a < 1.f || mAntiAliasing)
135 mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
137 mBorderSizeIndex = mImpl->mRenderer.RegisterProperty(Toolkit::BorderVisual::Property::SIZE, SIZE_NAME, mBorderSize);
139 actor.AddRenderer(mImpl->mRenderer);
141 // Border Visual Generated and ready to display
142 ResourceReady(Toolkit::Visual::ResourceStatus::READY);
145 void BorderVisual::DoCreatePropertyMap(Property::Map& map) const
148 map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::BORDER);
149 map.Insert(Toolkit::BorderVisual::Property::COLOR, mBorderColor);
150 map.Insert(Toolkit::BorderVisual::Property::SIZE, mBorderSize);
151 map.Insert(Toolkit::BorderVisual::Property::ANTI_ALIASING, mAntiAliasing);
154 void BorderVisual::DoCreateInstancePropertyMap(Property::Map& map) const
159 void BorderVisual::OnSetTransform()
163 mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
167 void BorderVisual::OnInitialize()
169 Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::BORDER_GEOMETRY);
172 geometry = CreateBorderGeometry();
173 mFactoryCache.SaveGeometry(VisualFactoryCache::BORDER_GEOMETRY, geometry);
176 Shader shader = GetBorderShader();
177 mImpl->mRenderer = Renderer::New(geometry, shader);
178 mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
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;
234 BorderVertex borderVertexData[16] =
236 {Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f)},
237 {Vector2(-halfWidth, -halfHeight), Vector2(1.f, 0.f)},
238 {Vector2(halfWidth, -halfHeight), Vector2(-1.f, 0.f)},
239 {Vector2(halfWidth, -halfHeight), Vector2(0.f, 0.f)},
241 {Vector2(-halfWidth, -halfHeight), Vector2(0.f, 1.f)},
242 {Vector2(-halfWidth, -halfHeight), Vector2(1.f, 1.f)},
243 {Vector2(halfWidth, -halfHeight), Vector2(-1.f, 1.f)},
244 {Vector2(halfWidth, -halfHeight), Vector2(0.f, 1.f)},
246 {Vector2(-halfWidth, halfHeight), Vector2(0.f, -1.f)},
247 {Vector2(-halfWidth, halfHeight), Vector2(1.f, -1.f)},
248 {Vector2(halfWidth, halfHeight), Vector2(-1.f, -1.f)},
249 {Vector2(halfWidth, halfHeight), Vector2(0.f, -1.f)},
251 {Vector2(-halfWidth, halfHeight), Vector2(0.f, 0.f)},
252 {Vector2(-halfWidth, halfHeight), Vector2(1.f, 0.f)},
253 {Vector2(halfWidth, halfHeight), Vector2(-1.f, 0.f)},
254 {Vector2(halfWidth, halfHeight), Vector2(0.f, 0.f)},
257 Property::Map borderVertexFormat;
258 borderVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
259 borderVertexFormat[DRIFT_ATTRIBUTE_NAME] = Property::VECTOR2;
260 VertexBuffer borderVertices = VertexBuffer::New(borderVertexFormat);
261 borderVertices.SetData(borderVertexData, 16);
264 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};
266 // Create the geometry object
267 Geometry geometry = Geometry::New();
268 geometry.AddVertexBuffer(borderVertices);
269 geometry.SetIndexBuffer(indexData, sizeof(indexData) / sizeof(indexData[0]));
270 geometry.SetType(Geometry::TRIANGLE_STRIP);
275 } // namespace Internal
277 } // namespace Toolkit