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(2); // 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 if(mBorderColorIndex == Property::INVALID_INDEX)
134 mBorderColorIndex = mImpl->mRenderer.RegisterUniqueProperty(Toolkit::BorderVisual::Property::COLOR, COLOR_NAME, mBorderColor);
136 if(mBorderColor.a < 1.f || mAntiAliasing)
138 mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
140 if(mBorderSizeIndex == Property::INVALID_INDEX)
142 mBorderSizeIndex = mImpl->mRenderer.RegisterUniqueProperty(Toolkit::BorderVisual::Property::SIZE, SIZE_NAME, mBorderSize);
145 actor.AddRenderer(mImpl->mRenderer);
147 // Border Visual Generated and ready to display
148 ResourceReady(Toolkit::Visual::ResourceStatus::READY);
151 void BorderVisual::DoCreatePropertyMap(Property::Map& map) const
154 map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::BORDER);
155 map.Insert(Toolkit::BorderVisual::Property::COLOR, mBorderColor);
156 map.Insert(Toolkit::BorderVisual::Property::SIZE, mBorderSize);
157 map.Insert(Toolkit::BorderVisual::Property::ANTI_ALIASING, mAntiAliasing);
160 void BorderVisual::DoCreateInstancePropertyMap(Property::Map& map) const
165 void BorderVisual::OnSetTransform()
169 mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
173 void BorderVisual::OnInitialize()
175 Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::BORDER_GEOMETRY);
178 geometry = CreateBorderGeometry();
179 mFactoryCache.SaveGeometry(VisualFactoryCache::BORDER_GEOMETRY, geometry);
182 Shader shader = GetBorderShader();
183 mImpl->mRenderer = VisualRenderer::New(geometry, shader);
184 mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
186 //Register transform properties
187 mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
190 Shader BorderVisual::GetBorderShader()
195 shader = mFactoryCache.GetShader(VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING);
198 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());
199 mFactoryCache.SaveShader(VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING, shader);
204 shader = mFactoryCache.GetShader(VisualFactoryCache::BORDER_SHADER);
207 shader = Shader::New(Dali::Shader::GetVertexShaderPrefix() + SHADER_BORDER_VISUAL_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_BORDER_VISUAL_SHADER_FRAG.data());
208 mFactoryCache.SaveShader(VisualFactoryCache::BORDER_SHADER, shader);
216 * Vertices and triangles of the border geometry:
218 * vertex position = aPosition*uSize.xy + aDrift*uBorderSize;
231 Geometry BorderVisual::CreateBorderGeometry()
233 const float halfWidth = 0.5f;
234 const float halfHeight = 0.5f;
240 BorderVertex borderVertexData[16] =
242 {Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f)},
243 {Vector2(-halfWidth, -halfHeight), Vector2(1.f, 0.f)},
244 {Vector2(halfWidth, -halfHeight), Vector2(-1.f, 0.f)},
245 {Vector2(halfWidth, -halfHeight), Vector2(0.f, 0.f)},
247 {Vector2(-halfWidth, -halfHeight), Vector2(0.f, 1.f)},
248 {Vector2(-halfWidth, -halfHeight), Vector2(1.f, 1.f)},
249 {Vector2(halfWidth, -halfHeight), Vector2(-1.f, 1.f)},
250 {Vector2(halfWidth, -halfHeight), Vector2(0.f, 1.f)},
252 {Vector2(-halfWidth, halfHeight), Vector2(0.f, -1.f)},
253 {Vector2(-halfWidth, halfHeight), Vector2(1.f, -1.f)},
254 {Vector2(halfWidth, halfHeight), Vector2(-1.f, -1.f)},
255 {Vector2(halfWidth, halfHeight), Vector2(0.f, -1.f)},
257 {Vector2(-halfWidth, halfHeight), Vector2(0.f, 0.f)},
258 {Vector2(-halfWidth, halfHeight), Vector2(1.f, 0.f)},
259 {Vector2(halfWidth, halfHeight), Vector2(-1.f, 0.f)},
260 {Vector2(halfWidth, halfHeight), Vector2(0.f, 0.f)},
263 Property::Map borderVertexFormat;
264 borderVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
265 borderVertexFormat[DRIFT_ATTRIBUTE_NAME] = Property::VECTOR2;
266 VertexBuffer borderVertices = VertexBuffer::New(borderVertexFormat);
267 borderVertices.SetData(borderVertexData, 16);
270 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};
272 // Create the geometry object
273 Geometry geometry = Geometry::New();
274 geometry.AddVertexBuffer(borderVertices);
275 geometry.SetIndexBuffer(indexData, sizeof(indexData) / sizeof(indexData[0]));
276 geometry.SetType(Geometry::TRIANGLE_STRIP);
281 } // namespace Internal
283 } // namespace Toolkit