Make sure that global variables are initialized lazily in scene3d. 33/290133/2
authorhuayong.xu <huayong.xu@samsung.com>
Mon, 20 Mar 2023 11:08:48 +0000 (19:08 +0800)
committerhuayong.xu <huayong.xu@samsung.com>
Mon, 20 Mar 2023 11:17:06 +0000 (19:17 +0800)
Change-Id: Iad6bb2e4f10c18141a8a0c2f92eaf2d5b68abd9d

dali-scene3d/internal/loader/gltf2-asset.cpp
dali-scene3d/internal/loader/gltf2-util.cpp
dali-scene3d/internal/loader/json-util.cpp
dali-scene3d/public-api/loader/alpha-function-helper.cpp
dali-scene3d/public-api/loader/material-definition.cpp
dali-scene3d/public-api/loader/parse-renderer-state.cpp
dali-scene3d/public-api/loader/scene-definition.cpp

index a747405..a6ac398 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2022 Samsung Electronics Co., Ltd.
+* Copyright (c) 2023 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.
@@ -39,53 +39,73 @@ constexpr uint32_t ACCESSOR_TYPE_ELEMENT_COUNT[]{
   16,
   static_cast<uint32_t>(-1)};
 
-const std::map<std::string_view, AccessorType::Type> ACCESSOR_TYPES{
-  ENUM_STRING_MAPPING(AccessorType, SCALAR),
-  ENUM_STRING_MAPPING(AccessorType, VEC2),
-  ENUM_STRING_MAPPING(AccessorType, VEC3),
-  ENUM_STRING_MAPPING(AccessorType, VEC4),
-  ENUM_STRING_MAPPING(AccessorType, MAT2),
-  ENUM_STRING_MAPPING(AccessorType, MAT3),
-  ENUM_STRING_MAPPING(AccessorType, MAT4),
-};
-
-const std::map<std::string_view, AlphaMode::Type> ALPHA_MODE_TYPES{
-  ENUM_STRING_MAPPING(AlphaMode::Type, OPAQUE),
-  ENUM_STRING_MAPPING(AlphaMode::Type, MASK),
-  ENUM_STRING_MAPPING(AlphaMode::Type, BLEND),
-};
-
-const std::map<std::string_view, Attribute::Type> ATTRIBUTE_TYPES{
-  ENUM_STRING_MAPPING(Attribute::Type, POSITION),
-  ENUM_STRING_MAPPING(Attribute::Type, NORMAL),
-  ENUM_STRING_MAPPING(Attribute::Type, TANGENT),
-  ENUM_STRING_MAPPING(Attribute::Type, TEXCOORD_0),
-  ENUM_STRING_MAPPING(Attribute::Type, TEXCOORD_1),
-  ENUM_STRING_MAPPING(Attribute::Type, COLOR_0),
-  ENUM_STRING_MAPPING(Attribute::Type, JOINTS_0),
-  ENUM_STRING_MAPPING(Attribute::Type, WEIGHTS_0),
-};
-
-const std::map<std::string_view, Animation::Sampler::Interpolation::Type> ANIMATION_SAMPLER_INTERPOLATION{
-  ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, STEP),
-  ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, LINEAR),
-  ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, CUBICSPLINE),
-};
-
-const std::map<std::string_view, Animation::Channel::Target::Type> ANIMATION_CHANNEL_TARGET_PATH_TYPES{
-  ENUM_STRING_MAPPING(Animation::Channel::Target::Type, TRANSLATION),
-  ENUM_STRING_MAPPING(Animation::Channel::Target::Type, ROTATION),
-  ENUM_STRING_MAPPING(Animation::Channel::Target::Type, SCALE),
-  ENUM_STRING_MAPPING(Animation::Channel::Target::Type, WEIGHTS),
-};
+const std::map<std::string_view, AccessorType::Type>& GetAccessorTypes()
+{
+  static const std::map<std::string_view, AccessorType::Type> ACCESSOR_TYPES{
+    ENUM_STRING_MAPPING(AccessorType, SCALAR),
+    ENUM_STRING_MAPPING(AccessorType, VEC2),
+    ENUM_STRING_MAPPING(AccessorType, VEC3),
+    ENUM_STRING_MAPPING(AccessorType, VEC4),
+    ENUM_STRING_MAPPING(AccessorType, MAT2),
+    ENUM_STRING_MAPPING(AccessorType, MAT3),
+    ENUM_STRING_MAPPING(AccessorType, MAT4),
+  };
+  return ACCESSOR_TYPES;
+}
+
+const std::map<std::string_view, AlphaMode::Type>& GetAlphaModeTypes()
+{
+  static const std::map<std::string_view, AlphaMode::Type> ALPHA_MODE_TYPES{
+    ENUM_STRING_MAPPING(AlphaMode::Type, OPAQUE),
+    ENUM_STRING_MAPPING(AlphaMode::Type, MASK),
+    ENUM_STRING_MAPPING(AlphaMode::Type, BLEND),
+  };
+  return ALPHA_MODE_TYPES;
+}
+
+const std::map<std::string_view, Attribute::Type>& GetAttributeTypes()
+{
+  static const std::map<std::string_view, Attribute::Type> ATTRIBUTE_TYPES{
+    ENUM_STRING_MAPPING(Attribute::Type, POSITION),
+    ENUM_STRING_MAPPING(Attribute::Type, NORMAL),
+    ENUM_STRING_MAPPING(Attribute::Type, TANGENT),
+    ENUM_STRING_MAPPING(Attribute::Type, TEXCOORD_0),
+    ENUM_STRING_MAPPING(Attribute::Type, TEXCOORD_1),
+    ENUM_STRING_MAPPING(Attribute::Type, COLOR_0),
+    ENUM_STRING_MAPPING(Attribute::Type, JOINTS_0),
+    ENUM_STRING_MAPPING(Attribute::Type, WEIGHTS_0),
+  };
+  return ATTRIBUTE_TYPES;
+}
+
+const std::map<std::string_view, Animation::Sampler::Interpolation::Type>& GetAnimationSamplerInterpolation()
+{
+  static const std::map<std::string_view, Animation::Sampler::Interpolation::Type> ANIMATION_SAMPLER_INTERPOLATION{
+    ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, STEP),
+    ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, LINEAR),
+    ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, CUBICSPLINE),
+  };
+  return ANIMATION_SAMPLER_INTERPOLATION;
+}
+
+const std::map<std::string_view, Animation::Channel::Target::Type>& GetAnimationChannelTargetPathTypes()
+{
+  static const std::map<std::string_view, Animation::Channel::Target::Type> ANIMATION_CHANNEL_TARGET_PATH_TYPES{
+    ENUM_STRING_MAPPING(Animation::Channel::Target::Type, TRANSLATION),
+    ENUM_STRING_MAPPING(Animation::Channel::Target::Type, ROTATION),
+    ENUM_STRING_MAPPING(Animation::Channel::Target::Type, SCALE),
+    ENUM_STRING_MAPPING(Animation::Channel::Target::Type, WEIGHTS),
+  };
+  return ANIMATION_CHANNEL_TARGET_PATH_TYPES;
+}
 
 } // namespace
 
-ENUM_TYPE_FROM_STRING(AccessorType, ACCESSOR_TYPES)
-ENUM_TYPE_FROM_STRING(AlphaMode, ALPHA_MODE_TYPES)
-ENUM_TYPE_FROM_STRING(Attribute, ATTRIBUTE_TYPES)
-ENUM_TYPE_FROM_STRING(Animation::Sampler::Interpolation, ANIMATION_SAMPLER_INTERPOLATION)
-ENUM_TYPE_FROM_STRING(Animation::Channel::Target, ANIMATION_CHANNEL_TARGET_PATH_TYPES)
+ENUM_TYPE_FROM_STRING(AccessorType, GetAccessorTypes())
+ENUM_TYPE_FROM_STRING(AlphaMode, GetAlphaModeTypes())
+ENUM_TYPE_FROM_STRING(Attribute, GetAttributeTypes())
+ENUM_TYPE_FROM_STRING(Animation::Sampler::Interpolation, GetAnimationSamplerInterpolation())
+ENUM_TYPE_FROM_STRING(Animation::Channel::Target, GetAnimationChannelTargetPathTypes())
 
 bool Component::IsUnsigned(Type t)
 {
index b01c8ba..f255b3d 100644 (file)
@@ -80,32 +80,54 @@ void ApplyAccessorMinMax(const gltf2::Accessor& accessor, float* values)
   MeshDefinition::Blob::ApplyMinMax(accessor.mMin, accessor.mMax, accessor.mCount, values);
 }
 
-const auto BUFFER_READER = std::move(json::Reader<gltf2::Buffer>()
+const json::Reader<gltf2::Buffer>& GetBufferReader()
+{
+  static const auto BUFFER_READER = std::move(json::Reader<gltf2::Buffer>()
                                        .Register(*json::MakeProperty("byteLength", json::Read::Number<uint32_t>, &gltf2::Buffer::mByteLength))
                                        .Register(*json::MakeProperty("uri", json::Read::StringView, &gltf2::Buffer::mUri)));
+  return BUFFER_READER;
+}
 
-const auto BUFFER_VIEW_READER = std::move(json::Reader<gltf2::BufferView>()
+const json::Reader<gltf2::BufferView>& GetBufferViewReader()
+{
+  static const auto BUFFER_VIEW_READER = std::move(json::Reader<gltf2::BufferView>()
                                             .Register(*json::MakeProperty("buffer", gltf2::RefReader<gltf2::Document>::Read<gltf2::Buffer, &gltf2::Document::mBuffers>, &gltf2::BufferView::mBuffer))
                                             .Register(*json::MakeProperty("byteOffset", json::Read::Number<uint32_t>, &gltf2::BufferView::mByteOffset))
                                             .Register(*json::MakeProperty("byteLength", json::Read::Number<uint32_t>, &gltf2::BufferView::mByteLength))
                                             .Register(*json::MakeProperty("byteStride", json::Read::Number<uint32_t>, &gltf2::BufferView::mByteStride))
                                             .Register(*json::MakeProperty("target", json::Read::Number<uint32_t>, &gltf2::BufferView::mTarget)));
+  return BUFFER_VIEW_READER;
+}
 
-const auto BUFFER_VIEW_CLIENT_READER = std::move(json::Reader<gltf2::BufferViewClient>()
+const json::Reader<gltf2::BufferViewClient>& GetBufferViewClientReader()
+{
+  static const auto BUFFER_VIEW_CLIENT_READER = std::move(json::Reader<gltf2::BufferViewClient>()
                                                    .Register(*json::MakeProperty("bufferView", gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>, &gltf2::BufferViewClient::mBufferView))
                                                    .Register(*json::MakeProperty("byteOffset", json::Read::Number<uint32_t>, &gltf2::BufferViewClient::mByteOffset)));
+  return BUFFER_VIEW_CLIENT_READER;
+}
 
-const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(json::Reader<gltf2::ComponentTypedBufferViewClient>()
+const json::Reader<gltf2::ComponentTypedBufferViewClient>& GetComponentTypedBufferViewClientReader()
+{
+  static const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(json::Reader<gltf2::ComponentTypedBufferViewClient>()
                                                                    .Register(*new json::Property<gltf2::ComponentTypedBufferViewClient, gltf2::Ref<gltf2::BufferView>>("bufferView", gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>, &gltf2::ComponentTypedBufferViewClient::mBufferView))
                                                                    .Register(*new json::Property<gltf2::ComponentTypedBufferViewClient, uint32_t>("byteOffset", json::Read::Number<uint32_t>, &gltf2::ComponentTypedBufferViewClient::mByteOffset))
                                                                    .Register(*json::MakeProperty("componentType", json::Read::Enum<gltf2::Component::Type>, &gltf2::ComponentTypedBufferViewClient::mComponentType)));
+  return COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER;
+}
 
-const auto ACCESSOR_SPARSE_READER = std::move(json::Reader<gltf2::Accessor::Sparse>()
+const json::Reader<gltf2::Accessor::Sparse>& GetAccessorSparseReader()
+{
+  static const auto ACCESSOR_SPARSE_READER = std::move(json::Reader<gltf2::Accessor::Sparse>()
                                                 .Register(*json::MakeProperty("count", json::Read::Number<uint32_t>, &gltf2::Accessor::Sparse::mCount))
                                                 .Register(*json::MakeProperty("indices", json::ObjectReader<gltf2::ComponentTypedBufferViewClient>::Read, &gltf2::Accessor::Sparse::mIndices))
                                                 .Register(*json::MakeProperty("values", json::ObjectReader<gltf2::BufferViewClient>::Read, &gltf2::Accessor::Sparse::mValues)));
+  return ACCESSOR_SPARSE_READER;
+}
 
-const auto ACCESSOR_READER = std::move(json::Reader<gltf2::Accessor>()
+const json::Reader<gltf2::Accessor>& GetAccessorReader()
+{
+  static const auto ACCESSOR_READER = std::move(json::Reader<gltf2::Accessor>()
                                          .Register(*new json::Property<gltf2::Accessor, gltf2::Ref<gltf2::BufferView>>("bufferView",
                                                                                                                        gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>,
                                                                                                                        &gltf2::Accessor::mBufferView))
@@ -122,50 +144,86 @@ const auto ACCESSOR_READER = std::move(json::Reader<gltf2::Accessor>()
                                          .Register(*json::MakeProperty("min", json::Read::Array<float, json::Read::Number>, &gltf2::Accessor::mMin))
                                          .Register(*json::MakeProperty("max", json::Read::Array<float, json::Read::Number>, &gltf2::Accessor::mMax))
                                          .Register(*new json::Property<gltf2::Accessor, gltf2::Accessor::Sparse>("sparse", json::ObjectReader<gltf2::Accessor::Sparse>::Read, &gltf2::Accessor::SetSparse)));
+  return ACCESSOR_READER;
+}
 
-const auto IMAGE_READER = std::move(json::Reader<gltf2::Image>()
+const json::Reader<gltf2::Image>& GetImageReader()
+{
+  static const auto IMAGE_READER = std::move(json::Reader<gltf2::Image>()
                                       .Register(*new json::Property<gltf2::Image, std::string_view>("name", json::Read::StringView, &gltf2::Material::mName))
                                       .Register(*json::MakeProperty("uri", json::Read::StringView, &gltf2::Image::mUri))
                                       .Register(*json::MakeProperty("mimeType", json::Read::StringView, &gltf2::Image::mMimeType))
                                       .Register(*json::MakeProperty("bufferView", gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>, &gltf2::Image::mBufferView)));
+  return IMAGE_READER;
+}
 
-const auto SAMPLER_READER = std::move(json::Reader<gltf2::Sampler>()
+const json::Reader<gltf2::Sampler>& GetSamplerReader()
+{
+  static const auto SAMPLER_READER = std::move(json::Reader<gltf2::Sampler>()
                                         .Register(*json::MakeProperty("minFilter", json::Read::Enum<gltf2::Filter::Type>, &gltf2::Sampler::mMinFilter))
                                         .Register(*json::MakeProperty("magFilter", json::Read::Enum<gltf2::Filter::Type>, &gltf2::Sampler::mMagFilter))
                                         .Register(*json::MakeProperty("wrapS", json::Read::Enum<gltf2::Wrap::Type>, &gltf2::Sampler::mWrapS))
                                         .Register(*json::MakeProperty("wrapT", json::Read::Enum<gltf2::Wrap::Type>, &gltf2::Sampler::mWrapT)));
+  return SAMPLER_READER;
+}
 
-const auto TEXURE_READER = std::move(json::Reader<gltf2::Texture>()
+const json::Reader<gltf2::Texture>& GetTextureReader()
+{
+  static const auto TEXURE_READER = std::move(json::Reader<gltf2::Texture>()
                                        .Register(*json::MakeProperty("source", gltf2::RefReader<gltf2::Document>::Read<gltf2::Image, &gltf2::Document::mImages>, &gltf2::Texture::mSource))
                                        .Register(*json::MakeProperty("sampler", gltf2::RefReader<gltf2::Document>::Read<gltf2::Sampler, &gltf2::Document::mSamplers>, &gltf2::Texture::mSampler)));
+  return TEXURE_READER;
+}
 
-const auto TEXURE_INFO_READER = std::move(json::Reader<gltf2::TextureInfo>()
+const json::Reader<gltf2::TextureInfo>& GetTextureInfoReader()
+{
+  static const auto TEXURE_INFO_READER = std::move(json::Reader<gltf2::TextureInfo>()
                                             .Register(*json::MakeProperty("index", gltf2::RefReader<gltf2::Document>::Read<gltf2::Texture, &gltf2::Document::mTextures>, &gltf2::TextureInfo::mTexture))
                                             .Register(*json::MakeProperty("texCoord", json::Read::Number<uint32_t>, &gltf2::TextureInfo::mTexCoord))
                                             .Register(*json::MakeProperty("scale", json::Read::Number<float>, &gltf2::TextureInfo::mScale))
                                             .Register(*json::MakeProperty("strength", json::Read::Number<float>, &gltf2::TextureInfo::mStrength)));
+  return TEXURE_INFO_READER;
+}
 
-const auto MATERIAL_PBR_READER = std::move(json::Reader<gltf2::Material::Pbr>()
+const json::Reader<gltf2::Material::Pbr>& GetMaterialPbrReader()
+{
+  static const auto MATERIAL_PBR_READER = std::move(json::Reader<gltf2::Material::Pbr>()
                                              .Register(*json::MakeProperty("baseColorFactor", gltf2::ReadDaliVector<Vector4>, &gltf2::Material::Pbr::mBaseColorFactor))
                                              .Register(*json::MakeProperty("baseColorTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::Pbr::mBaseColorTexture))
                                              .Register(*json::MakeProperty("metallicFactor", json::Read::Number<float>, &gltf2::Material::Pbr::mMetallicFactor))
                                              .Register(*json::MakeProperty("roughnessFactor", json::Read::Number<float>, &gltf2::Material::Pbr::mRoughnessFactor))
                                              .Register(*json::MakeProperty("metallicRoughnessTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::Pbr::mMetallicRoughnessTexture)));
+  return MATERIAL_PBR_READER;
+}
 
-const auto MATERIAL_SPECULAR_READER = std::move(json::Reader<gltf2::MaterialSpecular>()
+const json::Reader<gltf2::MaterialSpecular>& GetMaterialSpecularReader()
+{
+  static const auto MATERIAL_SPECULAR_READER = std::move(json::Reader<gltf2::MaterialSpecular>()
                                                   .Register(*json::MakeProperty("specularFactor", json::Read::Number<float>, &gltf2::MaterialSpecular::mSpecularFactor))
                                                   .Register(*json::MakeProperty("specularTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::MaterialSpecular::mSpecularTexture))
                                                   .Register(*json::MakeProperty("specularColorFactor", gltf2::ReadDaliVector<Vector3>, &gltf2::MaterialSpecular::mSpecularColorFactor))
                                                   .Register(*json::MakeProperty("specularColorTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::MaterialSpecular::mSpecularColorTexture)));
+  return MATERIAL_SPECULAR_READER;
+}
 
-const auto MATERIAL_IOR_READER = std::move(json::Reader<gltf2::MaterialIor>()
+const json::Reader<gltf2::MaterialIor>& GetMaterialIorReader()
+{
+  static const auto MATERIAL_IOR_READER = std::move(json::Reader<gltf2::MaterialIor>()
                                              .Register(*json::MakeProperty("ior", json::Read::Number<float>, &gltf2::MaterialIor::mIor)));
+  return MATERIAL_IOR_READER;
+}
 
-const auto MATERIAL_EXTENSION_READER = std::move(json::Reader<gltf2::MaterialExtensions>()
+const json::Reader<gltf2::MaterialExtensions>& GetMaterialExtensionsReader()
+{
+  static const auto MATERIAL_EXTENSION_READER = std::move(json::Reader<gltf2::MaterialExtensions>()
                                                    .Register(*json::MakeProperty("KHR_materials_ior", json::ObjectReader<gltf2::MaterialIor>::Read, &gltf2::MaterialExtensions::mMaterialIor))
                                                    .Register(*json::MakeProperty("KHR_materials_specular", json::ObjectReader<gltf2::MaterialSpecular>::Read, &gltf2::MaterialExtensions::mMaterialSpecular)));
+  return MATERIAL_EXTENSION_READER;
+}
 
-const auto MATERIAL_READER = std::move(json::Reader<gltf2::Material>()
+const json::Reader<gltf2::Material>& GetMaterialReader()
+{
+  static const auto MATERIAL_READER = std::move(json::Reader<gltf2::Material>()
                                          .Register(*new json::Property<gltf2::Material, std::string_view>("name", json::Read::StringView, &gltf2::Material::mName))
                                          .Register(*json::MakeProperty("pbrMetallicRoughness", json::ObjectReader<gltf2::Material::Pbr>::Read, &gltf2::Material::mPbrMetallicRoughness))
                                          .Register(*json::MakeProperty("normalTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::mNormalTexture))
@@ -176,6 +234,8 @@ const auto MATERIAL_READER = std::move(json::Reader<gltf2::Material>()
                                          .Register(*json::MakeProperty("alphaCutoff", json::Read::Number<float>, &gltf2::Material::mAlphaCutoff))
                                          .Register(*json::MakeProperty("doubleSided", json::Read::Boolean, &gltf2::Material::mDoubleSided))
                                          .Register(*json::MakeProperty("extensions", json::ObjectReader<gltf2::MaterialExtensions>::Read, &gltf2::Material::mMaterialExtensions)));
+  return MATERIAL_READER;
+}
 
 std::map<gltf2::Attribute::Type, gltf2::Ref<gltf2::Accessor>> ReadMeshPrimitiveAttributes(const json_value_s& j)
 {
@@ -209,21 +269,31 @@ std::vector<std::map<gltf2::Attribute::Type, gltf2::Ref<gltf2::Accessor>>> ReadM
   return result;
 }
 
-const auto MESH_PRIMITIVE_READER = std::move(json::Reader<gltf2::Mesh::Primitive>()
+const json::Reader<gltf2::Mesh::Primitive>& GetMeshPrimitiveReader()
+{
+  static const auto MESH_PRIMITIVE_READER = std::move(json::Reader<gltf2::Mesh::Primitive>()
                                                .Register(*json::MakeProperty("attributes", ReadMeshPrimitiveAttributes, &gltf2::Mesh::Primitive::mAttributes))
                                                .Register(*json::MakeProperty("indices", gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>, &gltf2::Mesh::Primitive::mIndices))
                                                .Register(*json::MakeProperty("material", gltf2::RefReader<gltf2::Document>::Read<gltf2::Material, &gltf2::Document::mMaterials>, &gltf2::Mesh::Primitive::mMaterial))
                                                .Register(*json::MakeProperty("mode", json::Read::Enum<gltf2::Mesh::Primitive::Mode>, &gltf2::Mesh::Primitive::mMode))
                                                .Register(*json::MakeProperty("targets", ReadMeshPrimitiveTargets, &gltf2::Mesh::Primitive::mTargets)));
+  return MESH_PRIMITIVE_READER;
+}
 
-const auto MESH_READER = std::move(json::Reader<gltf2::Mesh>()
+const json::Reader<gltf2::Mesh>& GetMeshReader()
+{
+  static const auto MESH_READER = std::move(json::Reader<gltf2::Mesh>()
                                      .Register(*new json::Property<gltf2::Mesh, std::string_view>("name", json::Read::StringView, &gltf2::Mesh::mName))
                                      .Register(*json::MakeProperty("primitives",
                                                                    json::Read::Array<gltf2::Mesh::Primitive, json::ObjectReader<gltf2::Mesh::Primitive>::Read>,
                                                                    &gltf2::Mesh::mPrimitives))
                                      .Register(*json::MakeProperty("weights", json::Read::Array<float, json::Read::Number>, &gltf2::Mesh::mWeights)));
+  return MESH_READER;
+}
 
-const auto SKIN_READER = std::move(json::Reader<gltf2::Skin>()
+const json::Reader<gltf2::Skin>& GetSkinReader()
+{
+  static const auto SKIN_READER = std::move(json::Reader<gltf2::Skin>()
                                      .Register(*new json::Property<gltf2::Skin, std::string_view>("name", json::Read::StringView, &gltf2::Skin::mName))
                                      .Register(*json::MakeProperty("inverseBindMatrices",
                                                                    gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>,
@@ -234,26 +304,42 @@ const auto SKIN_READER = std::move(json::Reader<gltf2::Skin>()
                                      .Register(*json::MakeProperty("joints",
                                                                    json::Read::Array<gltf2::Ref<gltf2::Node>, gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>>,
                                                                    &gltf2::Skin::mJoints)));
+  return SKIN_READER;
+}
 
-const auto CAMERA_PERSPECTIVE_READER = std::move(json::Reader<gltf2::Camera::Perspective>()
+const json::Reader<gltf2::Camera::Perspective>& GetCameraPerspectiveReader()
+{
+  static const auto CAMERA_PERSPECTIVE_READER = std::move(json::Reader<gltf2::Camera::Perspective>()
                                                    .Register(*json::MakeProperty("aspectRatio", json::Read::Number<float>, &gltf2::Camera::Perspective::mAspectRatio))
                                                    .Register(*json::MakeProperty("yfov", json::Read::Number<float>, &gltf2::Camera::Perspective::mYFov))
                                                    .Register(*json::MakeProperty("zfar", json::Read::Number<float>, &gltf2::Camera::Perspective::mZFar))
                                                    .Register(*json::MakeProperty("znear", json::Read::Number<float>, &gltf2::Camera::Perspective::mZNear))); // TODO: infinite perspective projection, where znear is omitted
+  return CAMERA_PERSPECTIVE_READER;
+}
 
-const auto CAMERA_ORTHOGRAPHIC_READER = std::move(json::Reader<gltf2::Camera::Orthographic>()
+const json::Reader<gltf2::Camera::Orthographic>& GetCameraOrthographicReader()
+{
+  static const auto CAMERA_ORTHOGRAPHIC_READER = std::move(json::Reader<gltf2::Camera::Orthographic>()
                                                     .Register(*json::MakeProperty("xmag", json::Read::Number<float>, &gltf2::Camera::Orthographic::mXMag))
                                                     .Register(*json::MakeProperty("ymag", json::Read::Number<float>, &gltf2::Camera::Orthographic::mYMag))
                                                     .Register(*json::MakeProperty("zfar", json::Read::Number<float>, &gltf2::Camera::Orthographic::mZFar))
                                                     .Register(*json::MakeProperty("znear", json::Read::Number<float>, &gltf2::Camera::Orthographic::mZNear)));
+  return CAMERA_ORTHOGRAPHIC_READER;
+}
 
-const auto CAMERA_READER = std::move(json::Reader<gltf2::Camera>()
+const json::Reader<gltf2::Camera>& GetCameraReader()
+{
+  static const auto CAMERA_READER = std::move(json::Reader<gltf2::Camera>()
                                        .Register(*new json::Property<gltf2::Camera, std::string_view>("name", json::Read::StringView, &gltf2::Camera::mName))
                                        .Register(*json::MakeProperty("type", json::Read::StringView, &gltf2::Camera::mType))
                                        .Register(*json::MakeProperty("perspective", json::ObjectReader<gltf2::Camera::Perspective>::Read, &gltf2::Camera::mPerspective))
                                        .Register(*json::MakeProperty("orthographic", json::ObjectReader<gltf2::Camera::Orthographic>::Read, &gltf2::Camera::mOrthographic)));
+  return CAMERA_READER;
+}
 
-const auto NODE_READER = std::move(json::Reader<gltf2::Node>()
+const json::Reader<gltf2::Node>& GetNodeReader()
+{
+  static const auto NODE_READER = std::move(json::Reader<gltf2::Node>()
                                      .Register(*new json::Property<gltf2::Node, std::string_view>("name", json::Read::StringView, &gltf2::Node::mName))
                                      .Register(*json::MakeProperty("translation", gltf2::ReadDaliVector<Vector3>, &gltf2::Node::mTranslation))
                                      .Register(*json::MakeProperty("rotation", gltf2::ReadQuaternion, &gltf2::Node::mRotation))
@@ -263,21 +349,37 @@ const auto NODE_READER = std::move(json::Reader<gltf2::Node>()
                                      .Register(*json::MakeProperty("children", json::Read::Array<gltf2::Ref<gltf2::Node>, gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>>, &gltf2::Node::mChildren))
                                      .Register(*json::MakeProperty("mesh", gltf2::RefReader<gltf2::Document>::Read<gltf2::Mesh, &gltf2::Document::mMeshes>, &gltf2::Node::mMesh))
                                      .Register(*json::MakeProperty("skin", gltf2::RefReader<gltf2::Document>::Read<gltf2::Skin, &gltf2::Document::mSkins>, &gltf2::Node::mSkin)));
+  return NODE_READER;
+}
 
-const auto ANIMATION_SAMPLER_READER = std::move(json::Reader<gltf2::Animation::Sampler>()
+const json::Reader<gltf2::Animation::Sampler>& GetAnimationSamplerReader()
+{
+  static const auto ANIMATION_SAMPLER_READER = std::move(json::Reader<gltf2::Animation::Sampler>()
                                                   .Register(*json::MakeProperty("input", gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>, &gltf2::Animation::Sampler::mInput))
                                                   .Register(*json::MakeProperty("output", gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>, &gltf2::Animation::Sampler::mOutput))
                                                   .Register(*json::MakeProperty("interpolation", gltf2::ReadStringEnum<gltf2::Animation::Sampler::Interpolation>, &gltf2::Animation::Sampler::mInterpolation)));
+  return ANIMATION_SAMPLER_READER;
+}
 
-const auto ANIMATION_TARGET_READER = std::move(json::Reader<gltf2::Animation::Channel::Target>()
+const json::Reader<gltf2::Animation::Channel::Target>& GetAnimationChannelTargetReader()
+{
+  static const auto ANIMATION_TARGET_READER = std::move(json::Reader<gltf2::Animation::Channel::Target>()
                                                  .Register(*json::MakeProperty("node", gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>, &gltf2::Animation::Channel::Target::mNode))
                                                  .Register(*json::MakeProperty("path", gltf2::ReadStringEnum<gltf2::Animation::Channel::Target>, &gltf2::Animation::Channel::Target::mPath)));
+  return ANIMATION_TARGET_READER;
+}
 
-const auto ANIMATION_CHANNEL_READER = std::move(json::Reader<gltf2::Animation::Channel>()
+const json::Reader<gltf2::Animation::Channel>& GetAnimationChannelReader()
+{
+  static const auto ANIMATION_CHANNEL_READER = std::move(json::Reader<gltf2::Animation::Channel>()
                                                   .Register(*json::MakeProperty("target", json::ObjectReader<gltf2::Animation::Channel::Target>::Read, &gltf2::Animation::Channel::mTarget))
                                                   .Register(*json::MakeProperty("sampler", gltf2::RefReader<gltf2::Animation>::Read<gltf2::Animation::Sampler, &gltf2::Animation::mSamplers>, &gltf2::Animation::Channel::mSampler)));
+  return ANIMATION_CHANNEL_READER;
+}
 
-const auto ANIMATION_READER = std::move(json::Reader<gltf2::Animation>()
+const json::Reader<gltf2::Animation>& GetAnimationReader()
+{
+  static const auto ANIMATION_READER = std::move(json::Reader<gltf2::Animation>()
                                           .Register(*new json::Property<gltf2::Animation, std::string_view>("name", json::Read::StringView, &gltf2::Animation::mName))
                                           .Register(*json::MakeProperty("samplers",
                                                                         json::Read::Array<gltf2::Animation::Sampler, json::ObjectReader<gltf2::Animation::Sampler>::Read>,
@@ -285,14 +387,22 @@ const auto ANIMATION_READER = std::move(json::Reader<gltf2::Animation>()
                                           .Register(*json::MakeProperty("channels",
                                                                         json::Read::Array<gltf2::Animation::Channel, json::ObjectReader<gltf2::Animation::Channel>::Read>,
                                                                         &gltf2::Animation::mChannels)));
+  return ANIMATION_READER;
+}
 
-const auto SCENE_READER = std::move(json::Reader<gltf2::Scene>()
+const json::Reader<gltf2::Scene>& GetSceneReader()
+{
+  static const auto SCENE_READER = std::move(json::Reader<gltf2::Scene>()
                                       .Register(*new json::Property<gltf2::Scene, std::string_view>("name", json::Read::StringView, &gltf2::Scene::mName))
                                       .Register(*json::MakeProperty("nodes",
                                                                     json::Read::Array<gltf2::Ref<gltf2::Node>, gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>>,
                                                                     &gltf2::Scene::mNodes)));
+  return SCENE_READER;
+}
 
-const auto DOCUMENT_READER = std::move(json::Reader<gltf2::Document>()
+const json::Reader<gltf2::Document>& GetDocumentReader()
+{
+  static const auto DOCUMENT_READER = std::move(json::Reader<gltf2::Document>()
                                          .Register(*json::MakeProperty("buffers",
                                                                        json::Read::Array<gltf2::Buffer, json::ObjectReader<gltf2::Buffer>::Read>,
                                                                        &gltf2::Document::mBuffers))
@@ -333,6 +443,8 @@ const auto DOCUMENT_READER = std::move(json::Reader<gltf2::Document>()
                                                                        json::Read::Array<gltf2::Scene, json::ObjectReader<gltf2::Scene>::Read>,
                                                                        &gltf2::Document::mScenes))
                                          .Register(*json::MakeProperty("scene", gltf2::RefReader<gltf2::Document>::Read<gltf2::Scene, &gltf2::Document::mScenes>, &gltf2::Document::mScene)));
+  return DOCUMENT_READER;
+}
 
 void ConvertBuffer(const gltf2::Buffer& buffer, decltype(ResourceBundle::mBuffers)& outBuffers, const std::string& resourcePath)
 {
@@ -1186,33 +1298,33 @@ void ProduceShaders(ShaderDefinitionFactory& shaderFactory, Dali::Scene3D::Loade
 
 void SetObjectReaders()
 {
-  json::SetObjectReader(BUFFER_READER);
-  json::SetObjectReader(BUFFER_VIEW_READER);
-  json::SetObjectReader(BUFFER_VIEW_CLIENT_READER);
-  json::SetObjectReader(COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER);
-  json::SetObjectReader(ACCESSOR_SPARSE_READER);
-  json::SetObjectReader(ACCESSOR_READER);
-  json::SetObjectReader(IMAGE_READER);
-  json::SetObjectReader(SAMPLER_READER);
-  json::SetObjectReader(TEXURE_READER);
-  json::SetObjectReader(TEXURE_INFO_READER);
-  json::SetObjectReader(MATERIAL_PBR_READER);
-  json::SetObjectReader(MATERIAL_SPECULAR_READER);
-  json::SetObjectReader(MATERIAL_IOR_READER);
-  json::SetObjectReader(MATERIAL_EXTENSION_READER);
-  json::SetObjectReader(MATERIAL_READER);
-  json::SetObjectReader(MESH_PRIMITIVE_READER);
-  json::SetObjectReader(MESH_READER);
-  json::SetObjectReader(SKIN_READER);
-  json::SetObjectReader(CAMERA_PERSPECTIVE_READER);
-  json::SetObjectReader(CAMERA_ORTHOGRAPHIC_READER);
-  json::SetObjectReader(CAMERA_READER);
-  json::SetObjectReader(NODE_READER);
-  json::SetObjectReader(ANIMATION_SAMPLER_READER);
-  json::SetObjectReader(ANIMATION_TARGET_READER);
-  json::SetObjectReader(ANIMATION_CHANNEL_READER);
-  json::SetObjectReader(ANIMATION_READER);
-  json::SetObjectReader(SCENE_READER);
+  json::SetObjectReader(GetBufferReader());
+  json::SetObjectReader(GetBufferViewReader());
+  json::SetObjectReader(GetBufferViewClientReader());
+  json::SetObjectReader(GetComponentTypedBufferViewClientReader());
+  json::SetObjectReader(GetAccessorSparseReader());
+  json::SetObjectReader(GetAccessorReader());
+  json::SetObjectReader(GetImageReader());
+  json::SetObjectReader(GetSamplerReader());
+  json::SetObjectReader(GetTextureReader());
+  json::SetObjectReader(GetTextureInfoReader());
+  json::SetObjectReader(GetMaterialPbrReader());
+  json::SetObjectReader(GetMaterialSpecularReader());
+  json::SetObjectReader(GetMaterialIorReader());
+  json::SetObjectReader(GetMaterialExtensionsReader());
+  json::SetObjectReader(GetMaterialReader());
+  json::SetObjectReader(GetMeshPrimitiveReader());
+  json::SetObjectReader(GetMeshReader());
+  json::SetObjectReader(GetSkinReader());
+  json::SetObjectReader(GetCameraPerspectiveReader());
+  json::SetObjectReader(GetCameraOrthographicReader());
+  json::SetObjectReader(GetCameraReader());
+  json::SetObjectReader(GetNodeReader());
+  json::SetObjectReader(GetAnimationSamplerReader());
+  json::SetObjectReader(GetAnimationChannelTargetReader());
+  json::SetObjectReader(GetAnimationChannelReader());
+  json::SetObjectReader(GetAnimationReader());
+  json::SetObjectReader(GetSceneReader());
 }
 
 void SetDefaultEnvironmentMap(const gltf2::Document& document, ConversionContext& context)
@@ -1246,7 +1358,7 @@ const std::string_view GetRendererModelIdentification()
 
 void ReadDocument(const json_object_s& jsonObject, gltf2::Document& document)
 {
-  DOCUMENT_READER.Read(jsonObject, document);
+  GetDocumentReader().Read(jsonObject, document);
 }
 
 void ReadDocumentFromParsedData(const json_object_s& jsonObject, gltf2::Document& document)
index ec6e95f..88cfad7 100644 (file)
@@ -121,43 +121,47 @@ bool ReadQuadHelper(const TreeNode* tn, const std::array<T*, 4>& quad)
   return true;
 }
 
-const std::map<std::string, Property::Value (*)(const TreeNode*)> kTypeIds{
-  // NONE
-  {"boolean", [](const TreeNode* tn) {
-     return ReadPrimitiveHelper<bool>(tn, ReadBool);
-   }},
-  {"float", [](const TreeNode* tn) {
-     return ReadPrimitiveHelper<float>(tn, ReadFloat);
-   }},
-  {"integer", [](const TreeNode* tn) {
-     return ReadPrimitiveHelper<int>(tn, ReadInt);
-   }},
-  {"vector2", ReadVectorHelper<Vector2>},
-  {"vector3", ReadVectorHelper<Vector3>},
-  {"vector4", ReadVectorHelper<Vector4>},
-  {"matrix3", ReadVectorHelper<Matrix3>},
-  {"matrix", ReadVectorHelper<Matrix>},
-  {"rectangle", [](const TreeNode* tn) {
-     Rect<int> value;
-     if(ReadQuadHelper<int>(tn, {&value.x, &value.y, &value.width, &value.height}))
-     {
-       return Property::Value(value);
-     }
-     return Property::Value();
-   }},
-  {"rotation", ReadRotationHelper},
-  // STRING - not particularly animatable
-  // ARRAY - not particularly animatable
-  // MAP - not particularly animatable
-  {"extents", [](const TreeNode* tn) {
-     Extents value;
-     if(ReadQuadHelper<uint16_t>(tn, {&value.start, &value.end, &value.top, &value.bottom}))
-     {
-       return Property::Value(value);
-     }
-     return Property::Value();
-   }},
-};
+const std::map<std::string_view, Property::Value (*)(const TreeNode*)>& GetTypeIds()
+{
+  static const std::map<std::string_view, Property::Value (*)(const TreeNode*)> kTypeIds{
+    // NONE
+    {"boolean", [](const TreeNode* tn) {
+       return ReadPrimitiveHelper<bool>(tn, ReadBool);
+     }},
+    {"float", [](const TreeNode* tn) {
+       return ReadPrimitiveHelper<float>(tn, ReadFloat);
+     }},
+    {"integer", [](const TreeNode* tn) {
+       return ReadPrimitiveHelper<int>(tn, ReadInt);
+     }},
+    {"vector2", ReadVectorHelper<Vector2>},
+    {"vector3", ReadVectorHelper<Vector3>},
+    {"vector4", ReadVectorHelper<Vector4>},
+    {"matrix3", ReadVectorHelper<Matrix3>},
+    {"matrix", ReadVectorHelper<Matrix>},
+    {"rectangle", [](const TreeNode* tn) {
+       Rect<int> value;
+       if(ReadQuadHelper<int>(tn, {&value.x, &value.y, &value.width, &value.height}))
+       {
+         return Property::Value(value);
+       }
+       return Property::Value();
+     }},
+    {"rotation", ReadRotationHelper},
+    // STRING - not particularly animatable
+    // ARRAY - not particularly animatable
+    // MAP - not particularly animatable
+    {"extents", [](const TreeNode* tn) {
+       Extents value;
+       if(ReadQuadHelper<uint16_t>(tn, {&value.start, &value.end, &value.top, &value.bottom}))
+       {
+         return Property::Value(value);
+       }
+       return Property::Value();
+     }},
+  };
+  return kTypeIds;
+}
 
 Property::Value (*const kArrayPropertyProcessors[])(const TreeNode*){
   ReadVectorHelper<Matrix>,
@@ -469,8 +473,8 @@ Property::Value ReadPropertyValue(const Toolkit::TreeNode& tn)
     auto jsonType = tn.GetChild("type");
     if(jsonType && jsonType->GetType() == TreeNode::STRING)
     {
-      auto iFind = kTypeIds.find(jsonType->GetString());
-      if(iFind != kTypeIds.end())
+      auto iFind = GetTypeIds().find(jsonType->GetString());
+      if(iFind != GetTypeIds().end())
       {
         propValue = iFind->second(tn.GetChild("value"));
       }
index 2aecc50..9c82704 100644 (file)
@@ -29,22 +29,26 @@ namespace
 #define DALI_ALPHA_FUNCTION_ENTRY(x) { #x, AlphaFunction::x }
 // clang-format on
 
-std::unordered_map<std::string, AlphaFunction> sFunctions{
-  DALI_ALPHA_FUNCTION_ENTRY(DEFAULT),
-  DALI_ALPHA_FUNCTION_ENTRY(LINEAR),
-  DALI_ALPHA_FUNCTION_ENTRY(REVERSE),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_SQUARE),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_SQUARE),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_IN),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_OUT),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_SINE),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_SINE),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_OUT_SINE),
-  DALI_ALPHA_FUNCTION_ENTRY(BOUNCE),
-  DALI_ALPHA_FUNCTION_ENTRY(SIN),
-  DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_BACK),
-};
+std::unordered_map<std::string, AlphaFunction>& GetFunctions()
+{
+  static std::unordered_map<std::string, AlphaFunction> sFunctions{
+    DALI_ALPHA_FUNCTION_ENTRY(DEFAULT),
+    DALI_ALPHA_FUNCTION_ENTRY(LINEAR),
+    DALI_ALPHA_FUNCTION_ENTRY(REVERSE),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_SQUARE),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_SQUARE),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_IN),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_OUT),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_SINE),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_SINE),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_OUT_SINE),
+    DALI_ALPHA_FUNCTION_ENTRY(BOUNCE),
+    DALI_ALPHA_FUNCTION_ENTRY(SIN),
+    DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_BACK),
+  };
+  return sFunctions;
+}
 
 #undef DALI_ALPHA_FUNCTION_ENTRY
 
@@ -52,8 +56,8 @@ std::unordered_map<std::string, AlphaFunction> sFunctions{
 
 AlphaFunction GetAlphaFunction(const std::string& name, bool* found)
 {
-  auto iFind   = sFunctions.find(name);
-  bool success = iFind != sFunctions.end();
+  auto iFind   = GetFunctions().find(name);
+  bool success = iFind != GetFunctions().end();
   if(found)
   {
     *found = success;
@@ -63,7 +67,7 @@ AlphaFunction GetAlphaFunction(const std::string& name, bool* found)
 
 void RegisterAlphaFunction(const std::string& name, AlphaFunction alphaFn)
 {
-  DALI_ASSERT_ALWAYS(sFunctions.insert({name, alphaFn}).second &&
+  DALI_ASSERT_ALWAYS(GetFunctions().insert({name, alphaFn}).second &&
                      "Function with given key already exists.");
 }
 
index ac6b73a..f69ff72 100644 (file)
@@ -65,7 +65,11 @@ constexpr WrapMode::Type WRAP_MODES_TO_DALI[]{
   WrapMode::CLAMP_TO_EDGE,
   WrapMode::MIRRORED_REPEAT};
 
-const SamplerFlags::Type SINGLE_VALUE_SAMPLER = SamplerFlags::Encode(FilterMode::NEAREST, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
+const SamplerFlags::Type GetSingleValueSampler()
+{
+  static const SamplerFlags::Type SINGLE_VALUE_SAMPLER = SamplerFlags::Encode(FilterMode::NEAREST, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
+  return SINGLE_VALUE_SAMPLER;
+}
 
 static constexpr std::string_view EMBEDDED_DATA_PREFIX               = "data:";
 static constexpr std::string_view EMBEDDED_DATA_IMAGE_MEDIA_TYPE     = "image/";
@@ -206,7 +210,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
     {
       const auto bufferSize = 4;
       uint8_t*   buffer     = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff, 0xff}; // normal of (0, 0, 1), roughness of 1
-      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER});
+      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
     }
   }
   else
@@ -240,7 +244,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
       buffer[0] = static_cast<uint8_t>(mColor.r * 255.f);
       buffer[1] = static_cast<uint8_t>(mColor.g * 255.f);
       buffer[2] = static_cast<uint8_t>(mColor.b * 255.f);
-      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, format, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER});
+      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, format, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
     }
 
     // If we have transparency, or an image based albedo map, we will have to continue with separate metallicRoughness + normal.
@@ -256,7 +260,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
       // glTF2 uses B & G, so we might as well just set all components to 1.0.
       const auto bufferSize = 4;
       uint8_t*   buffer     = new uint8_t[bufferSize]{0xff, 0xff, 0xff, 0xff};
-      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER});
+      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
     }
 
     if(checkStage(NORMAL))
@@ -270,13 +274,13 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
       {
         const auto bufferSize = 3;
         uint8_t*   buffer     = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff}; // normal of (0, 0, 1)
-        raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER});
+        raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
       }
       else // single-value normal-roughness
       {
         const auto bufferSize = 4;
         uint8_t*   buffer     = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff, 0xff}; // normal of (0, 0, 1), roughness of 1.0
-        raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER});
+        raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
       }
     }
   }
index 30b4d44..63b7d58 100644 (file)
@@ -28,112 +28,129 @@ namespace RendererState
 {
 namespace
 {
-std::map<std::string_view, Type> COMPARISONS{
-#define DECL_COMPARISON(x) {#x, Comparison::x}
-  DECL_COMPARISON(NEVER),
-  DECL_COMPARISON(ALWAYS),
-  DECL_COMPARISON(LESS),
-  DECL_COMPARISON(GREATER),
-  DECL_COMPARISON(EQUAL),
-  DECL_COMPARISON(NOT_EQUAL),
-  DECL_COMPARISON(LESS_EQUAL),
-  DECL_COMPARISON(GREATER_EQUAL),
-#undef DECL_COMPARISON
-};
+const std::map<std::string_view, Type>& GetComparisons()
+{
+  static const std::map<std::string_view, Type> COMPARISONS{
+  #define DECL_COMPARISON(x) {#x, Comparison::x}
+    DECL_COMPARISON(NEVER),
+    DECL_COMPARISON(ALWAYS),
+    DECL_COMPARISON(LESS),
+    DECL_COMPARISON(GREATER),
+    DECL_COMPARISON(EQUAL),
+    DECL_COMPARISON(NOT_EQUAL),
+    DECL_COMPARISON(LESS_EQUAL),
+    DECL_COMPARISON(GREATER_EQUAL),
+  #undef DECL_COMPARISON
+  };
+  return COMPARISONS;
+}
 
 Type InterpretComparison(const std::string_view& str)
 {
   Type value = 0x0;
-  auto iFind = COMPARISONS.find(str);
-  if(iFind != COMPARISONS.end())
+  auto iFind = GetComparisons().find(str);
+  if(iFind != GetComparisons().end())
   {
     value = iFind->second;
   }
   return value;
 }
 
-std::map<std::string_view, Type> BLEND_FACTORS{
-#define DECL_BLEND_FACTOR(x) {#x, Dali::Scene3D::Loader::BlendFactor::x}
-  DECL_BLEND_FACTOR(ZERO),
-  DECL_BLEND_FACTOR(ONE),
-  DECL_BLEND_FACTOR(SRC_COLOR),
-  DECL_BLEND_FACTOR(ONE_MINUS_SRC_COLOR),
-  DECL_BLEND_FACTOR(SRC_ALPHA),
-  DECL_BLEND_FACTOR(ONE_MINUS_SRC_ALPHA),
-  DECL_BLEND_FACTOR(DST_ALPHA),
-  DECL_BLEND_FACTOR(ONE_MINUS_DST_ALPHA),
-  DECL_BLEND_FACTOR(DST_COLOR),
-  DECL_BLEND_FACTOR(ONE_MINUS_DST_COLOR),
-  DECL_BLEND_FACTOR(SRC_ALPHA_SATURATE),
-  DECL_BLEND_FACTOR(CONSTANT_COLOR),
-  DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_COLOR),
-  DECL_BLEND_FACTOR(CONSTANT_ALPHA),
-  DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_ALPHA),
-#undef DECL_BLEND_FACTOR
-};
+const std::map<std::string_view, Type>& GetBlendFactors()
+{
+  static const std::map<std::string_view, Type> BLEND_FACTORS{
+  #define DECL_BLEND_FACTOR(x) {#x, Dali::Scene3D::Loader::BlendFactor::x}
+    DECL_BLEND_FACTOR(ZERO),
+    DECL_BLEND_FACTOR(ONE),
+    DECL_BLEND_FACTOR(SRC_COLOR),
+    DECL_BLEND_FACTOR(ONE_MINUS_SRC_COLOR),
+    DECL_BLEND_FACTOR(SRC_ALPHA),
+    DECL_BLEND_FACTOR(ONE_MINUS_SRC_ALPHA),
+    DECL_BLEND_FACTOR(DST_ALPHA),
+    DECL_BLEND_FACTOR(ONE_MINUS_DST_ALPHA),
+    DECL_BLEND_FACTOR(DST_COLOR),
+    DECL_BLEND_FACTOR(ONE_MINUS_DST_COLOR),
+    DECL_BLEND_FACTOR(SRC_ALPHA_SATURATE),
+    DECL_BLEND_FACTOR(CONSTANT_COLOR),
+    DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_COLOR),
+    DECL_BLEND_FACTOR(CONSTANT_ALPHA),
+    DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_ALPHA),
+  #undef DECL_BLEND_FACTOR
+  };
+  return BLEND_FACTORS;
+}
 
 Type InterpretBlendFactor(const std::string_view& str, uint8_t item)
 {
   Type value = 0x0;
-  auto iFind = BLEND_FACTORS.find(str);
-  if(iFind != BLEND_FACTORS.end())
+  auto iFind = GetBlendFactors().find(str);
+  if(iFind != GetBlendFactors().end())
   {
     value = iFind->second << (BLEND_FACTOR_BASE_SHIFT + BLEND_FACTOR_ITEM_BITS * item);
   }
   return value;
 }
 
-std::map<std::string_view, Type> BUFFER_MODES{
-#define DECL_BUFFER_MODE(x) {#x, BufferMode::x}
-  DECL_BUFFER_MODE(NONE),
-  DECL_BUFFER_MODE(AUTO),
-  DECL_BUFFER_MODE(COLOR),
-  DECL_BUFFER_MODE(STENCIL),
-  DECL_BUFFER_MODE(COLOR_STENCIL),
-};
+const std::map<std::string_view, Type>& GetBufferModes()
+{
+  static const std::map<std::string_view, Type> BUFFER_MODES{
+  #define DECL_BUFFER_MODE(x) {#x, BufferMode::x}
+    DECL_BUFFER_MODE(NONE),
+    DECL_BUFFER_MODE(AUTO),
+    DECL_BUFFER_MODE(COLOR),
+    DECL_BUFFER_MODE(STENCIL),
+    DECL_BUFFER_MODE(COLOR_STENCIL),
+  #undef DECL_BUFFER_MODE
+  };
+  return BUFFER_MODES;
+}
 
 Type InterpretBufferMode(const std::string_view& str)
 {
   Type value = 0x0;
-  auto iFind = BUFFER_MODES.find(str);
-  if(iFind != BUFFER_MODES.end())
+  auto iFind = GetBufferModes().find(str);
+  if(iFind != GetBufferModes().end())
   {
     value = iFind->second << BUFFER_MODE_SHIFT;
   }
   return value;
 }
 
-std::map<std::string_view, Type (*)(const std::string_view&)> RENDERER_STATE_PROCESSORS{
-  {"DEPTH_WRITE", [](const std::string_view&) -> Type { return DEPTH_WRITE; }},
-  {"DEPTH_TEST", [](const std::string_view&) -> Type { return DEPTH_TEST; }},
-  {"CULL_FRONT", [](const std::string_view&) -> Type { return CULL_FRONT; }},
-  {"CULL_BACK", [](const std::string_view&) -> Type { return CULL_BACK; }},
-  {"ALPHA_BLEND", [](const std::string_view&) -> Type { return ALPHA_BLEND; }},
-  {"DEPTH_FUNC", [](const std::string_view& arg) -> Type {
-     Type value = (arg[0] == ':') ? (InterpretComparison(std::string_view(arg.data() + 1, arg.size() - 1)) << DEPTH_FUNCTION_SHIFT) : 0x0;
-     return value;
-   }},
-  {"BLEND_SRC_RGB", [](const std::string_view& arg) -> Type {
-     Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 0) : 0x0;
-     return value;
-   }},
-  {"BLEND_DST_RGB", [](const std::string_view& arg) -> Type {
-     Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 1) : 0x0;
-     return value;
-   }},
-  {"BLEND_SRC_ALPHA", [](const std::string_view& arg) -> Type {
-     Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 2) : 0x0;
-     return value;
-   }},
-  {"BLEND_DST_ALPHA", [](const std::string_view& arg) -> Type {
-     Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 3) : 0x0;
-     return value;
-   }},
-  {"BUFFER_MODE", [](const std::string_view& arg) -> Type {
-     Type value = (arg[0] == ':') ? InterpretBufferMode(std::string_view(arg.data() + 1, arg.size() - 1)) : 0x0;
-     return value;
-   }},
-};
+const std::map<std::string_view, Type (*)(const std::string_view&)>& GetRendererStateProcessors()
+{
+  static const std::map<std::string_view, Type (*)(const std::string_view&)> RENDERER_STATE_PROCESSORS{
+    {"DEPTH_WRITE", [](const std::string_view&) -> Type { return DEPTH_WRITE; }},
+    {"DEPTH_TEST", [](const std::string_view&) -> Type { return DEPTH_TEST; }},
+    {"CULL_FRONT", [](const std::string_view&) -> Type { return CULL_FRONT; }},
+    {"CULL_BACK", [](const std::string_view&) -> Type { return CULL_BACK; }},
+    {"ALPHA_BLEND", [](const std::string_view&) -> Type { return ALPHA_BLEND; }},
+    {"DEPTH_FUNC", [](const std::string_view& arg) -> Type {
+       Type value = (arg[0] == ':') ? (InterpretComparison(std::string_view(arg.data() + 1, arg.size() - 1)) << DEPTH_FUNCTION_SHIFT) : 0x0;
+       return value;
+     }},
+    {"BLEND_SRC_RGB", [](const std::string_view& arg) -> Type {
+       Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 0) : 0x0;
+       return value;
+     }},
+    {"BLEND_DST_RGB", [](const std::string_view& arg) -> Type {
+       Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 1) : 0x0;
+       return value;
+     }},
+    {"BLEND_SRC_ALPHA", [](const std::string_view& arg) -> Type {
+       Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 2) : 0x0;
+       return value;
+     }},
+    {"BLEND_DST_ALPHA", [](const std::string_view& arg) -> Type {
+       Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 3) : 0x0;
+       return value;
+     }},
+    {"BUFFER_MODE", [](const std::string_view& arg) -> Type {
+       Type value = (arg[0] == ':') ? InterpretBufferMode(std::string_view(arg.data() + 1, arg.size() - 1)) : 0x0;
+       return value;
+     }},
+  };
+  return RENDERER_STATE_PROCESSORS;
+}
 
 } // namespace
 
@@ -150,8 +167,8 @@ Type Parse(const char* string, size_t length, StringCallback onError)
   {
     auto iNextToken = std::find(string, iEnd, '|');
     auto iColon     = std::find(string, iNextToken, ':');
-    auto i          = RENDERER_STATE_PROCESSORS.find(std::string_view(string, iColon - string));
-    if(i != RENDERER_STATE_PROCESSORS.end() && size_t(std::distance(string, iNextToken)) >= i->first.size())
+    auto i          = GetRendererStateProcessors().find(std::string_view(string, iColon - string));
+    if(i != GetRendererStateProcessors().end() && size_t(std::distance(string, iNextToken)) >= i->first.size())
     {
       value |= i->second(std::string_view(string + i->first.size(), iNextToken - iColon));
     }
index f8377c3..4c9fc70 100644 (file)
@@ -45,48 +45,52 @@ namespace
 {
 const char* JOINT_MATRIX{"jointMatrix"};
 
-const std::map<Property::Type, Constraint (*)(Actor&, Property::Index)> sConstraintFactory = {
-  {Property::Type::BOOLEAN,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<bool>(a, i, [](bool& current, const PropertyInputContainer& inputs) {
-       current = inputs[0]->GetBoolean();
-     });
-   }},
-  {Property::Type::INTEGER,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<int>(a, i, [](int& current, const PropertyInputContainer& inputs) {
-       current = inputs[0]->GetInteger();
-     });
-   }},
-  {Property::Type::FLOAT,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<float>(a, i, EqualToConstraint());
-   }},
-  {Property::Type::VECTOR2,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<Vector2>(a, i, EqualToConstraint());
-   }},
-  {Property::Type::VECTOR3,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<Vector3>(a, i, EqualToConstraint());
-   }},
-  {Property::Type::VECTOR4,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<Vector4>(a, i, EqualToConstraint());
-   }},
-  {Property::Type::MATRIX,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<Matrix>(a, i, EqualToConstraint());
-   }},
-  {Property::Type::MATRIX3,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<Matrix3>(a, i, EqualToConstraint());
-   }},
-  {Property::Type::ROTATION,
-   [](Actor& a, Property::Index i) {
-     return Constraint::New<Quaternion>(a, i, EqualToConstraint());
-   }},
-};
+const std::map<Property::Type, Constraint (*)(Actor&, Property::Index)>& GetConstraintFactory()
+{
+  static const std::map<Property::Type, Constraint (*)(Actor&, Property::Index)> sConstraintFactory = {
+    {Property::Type::BOOLEAN,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<bool>(a, i, [](bool& current, const PropertyInputContainer& inputs) {
+         current = inputs[0]->GetBoolean();
+       });
+     }},
+    {Property::Type::INTEGER,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<int>(a, i, [](int& current, const PropertyInputContainer& inputs) {
+         current = inputs[0]->GetInteger();
+       });
+     }},
+    {Property::Type::FLOAT,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<float>(a, i, EqualToConstraint());
+     }},
+    {Property::Type::VECTOR2,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<Vector2>(a, i, EqualToConstraint());
+     }},
+    {Property::Type::VECTOR3,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<Vector3>(a, i, EqualToConstraint());
+     }},
+    {Property::Type::VECTOR4,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<Vector4>(a, i, EqualToConstraint());
+     }},
+    {Property::Type::MATRIX,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<Matrix>(a, i, EqualToConstraint());
+     }},
+    {Property::Type::MATRIX3,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<Matrix3>(a, i, EqualToConstraint());
+     }},
+    {Property::Type::ROTATION,
+     [](Actor& a, Property::Index i) {
+       return Constraint::New<Quaternion>(a, i, EqualToConstraint());
+     }},
+  };
+  return sConstraintFactory;
+}
 
 struct ResourceReflector : IResourceReflector
 {
@@ -777,8 +781,8 @@ void SceneDefinition::ApplyConstraints(Actor&                           root,
     if(iTarget != Property::INVALID_INDEX)
     {
       auto propertyType = cr.mTarget.GetPropertyType(iTarget);
-      auto iFind        = sConstraintFactory.find(propertyType);
-      if(iFind == sConstraintFactory.end())
+      auto iFind        = GetConstraintFactory().find(propertyType);
+      if(iFind == GetConstraintFactory().end())
       {
         onError(FormatString("node '%s': Property '%s' has unsupported type '%s'; ignored.",
                              sourceName,