Merge "Refactoring Animated image visual" into devel/master
authorSeungho BAEK <sbsh.baek@samsung.com>
Tue, 12 Apr 2022 12:48:25 +0000 (12:48 +0000)
committerGerrit Code Review <gerrit@review>
Tue, 12 Apr 2022 12:48:25 +0000 (12:48 +0000)
30 files changed:
automated-tests/resources/MRendererTest.gltf [new file with mode: 0644]
automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-reflection.cpp
automated-tests/src/dali-toolkit/utc-Dali-GlViewDirectRendering.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopup.cpp
dali-scene-loader/internal/gltf2-asset.h
dali-scene-loader/public-api/gltf2-loader.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/internal/controls/gl-view/drawable-view-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/drawable-view-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/gl-view-impl.cpp
dali-toolkit/internal/controls/gl-view/gl-view-impl.h
dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-relayouter.cpp
dali-toolkit/internal/text/text-controller-relayouter.h
dali-toolkit/public-api/controls/gl-view/gl-view.cpp
dali-toolkit/public-api/controls/gl-view/gl-view.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

diff --git a/automated-tests/resources/MRendererTest.gltf b/automated-tests/resources/MRendererTest.gltf
new file mode 100644 (file)
index 0000000..ae3d113
--- /dev/null
@@ -0,0 +1,179 @@
+{\r
+  "scene" : 0,\r
+  "scenes" : [\r
+    {\r
+      "nodes" : [ 0 ]\r
+    }\r
+  ],\r
+\r
+  "nodes" : [\r
+    {\r
+      "mesh" : 0,\r
+      "rotation" : [ 0.0, 0.0, 0.0, 1.0 ],\r
+      "scale": [\r
+          100.0,\r
+          100.0,\r
+          100.0\r
+      ],\r
+      "name": "RootNode"\r
+    }\r
+  ],\r
+\r
+  "meshes" : [\r
+    {\r
+      "primitives" : [ {\r
+        "attributes" : {\r
+          "POSITION" : 1\r
+        },\r
+        "indices" : 0,\r
+        "material": 0\r
+      } ]\r
+    }\r
+  ],\r
+\r
+  "animations": [\r
+    {\r
+      "samplers" : [\r
+        {\r
+          "input" : 2,\r
+          "interpolation" : "LINEAR",\r
+          "output" : 3\r
+        }\r
+      ],\r
+      "channels" : [ {\r
+        "sampler" : 0,\r
+        "target" : {\r
+          "node" : 0,\r
+          "path" : "rotation"\r
+        }\r
+      } ]\r
+    }\r
+  ],\r
+\r
+  "buffers" : [\r
+    {\r
+      "uri" : "simpleTriangle.bin",\r
+      "byteLength" : 44\r
+    },\r
+    {\r
+      "uri" : "animation.bin",\r
+      "byteLength" : 100\r
+    }\r
+  ],\r
+\r
+  "bufferViews" : [\r
+    {\r
+      "buffer" : 0,\r
+      "byteOffset" : 0,\r
+      "byteLength" : 6,\r
+      "target" : 34963\r
+    },\r
+    {\r
+      "buffer" : 0,\r
+      "byteOffset" : 8,\r
+      "byteLength" : 36,\r
+      "target" : 34962\r
+    },\r
+    {\r
+      "buffer" : 1,\r
+      "byteOffset" : 0,\r
+      "byteLength" : 100\r
+    }\r
+  ],\r
+\r
+  "accessors" : [\r
+    {\r
+      "bufferView" : 0,\r
+      "byteOffset" : 0,\r
+      "componentType" : 5123,\r
+      "count" : 3,\r
+      "type" : "SCALAR",\r
+      "max" : [ 2 ],\r
+      "min" : [ 0 ]\r
+    },\r
+    {\r
+      "bufferView" : 1,\r
+      "byteOffset" : 0,\r
+      "componentType" : 5126,\r
+      "count" : 3,\r
+      "type" : "VEC3",\r
+      "max" : [ 1.0, 1.0, 0.0 ],\r
+      "min" : [ 0.0, 0.0, 0.0 ]\r
+    },\r
+    {\r
+      "bufferView" : 2,\r
+      "byteOffset" : 0,\r
+      "componentType" : 5126,\r
+      "count" : 5,\r
+      "type" : "SCALAR",\r
+      "max" : [ 1.0 ],\r
+      "min" : [ 0.0 ]\r
+    },\r
+    {\r
+      "bufferView" : 2,\r
+      "byteOffset" : 20,\r
+      "componentType" : 5126,\r
+      "count" : 5,\r
+      "type" : "VEC4",\r
+      "max" : [ 0.0, 0.0, 1.0, 1.0 ],\r
+      "min" : [ 0.0, 0.0, 0.0, -0.707 ]\r
+    }\r
+  ],\r
+\r
+  "asset" : {\r
+    "generator": "glTF Tools for M-Renderer",\r
+    "version" : "2.0"\r
+  },\r
+\r
+  "materials": [\r
+    {\r
+      "pbrMetallicRoughness":\r
+      {\r
+        "baseColorTexture":\r
+        {\r
+          "index": 0,\r
+          "texCoord": 0\r
+        },\r
+        "metallicFactor": 0,\r
+        "baseColorFactor":\r
+        [\r
+          1,\r
+          1,\r
+          1,\r
+          1\r
+        ],\r
+        "roughnessFactor": 1\r
+      },\r
+      "emissiveFactor":\r
+      [\r
+        0,\r
+        0,\r
+        0\r
+      ],\r
+      "alphaMode": "OPAQUE",\r
+      "doubleSided": false\r
+    }\r
+  ],\r
+\r
+  "textures": [\r
+    {\r
+      "sampler": 0,\r
+      "source": 0\r
+    }\r
+  ],\r
+\r
+  "images": [\r
+    {\r
+      "uri": "AnimatedCube_BaseColor.png"\r
+    }\r
+  ],\r
+\r
+  "samplers": [\r
+    {\r
+      "magFilter": 9729,\r
+      "minFilter": 9986,\r
+      "wrapS": 10497,\r
+      "wrapT": 10497\r
+    }\r
+  ]\r
+}\r
index 3f829dc..47515b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
+#include <dali-test-suite-utils.h>
+#include <string_view>
+#include "dali-scene-loader/public-api/gltf2-loader.h"
+#include "dali-scene-loader/public-api/load-result.h"
 #include "dali-scene-loader/public-api/resource-bundle.h"
 #include "dali-scene-loader/public-api/scene-definition.h"
-#include "dali-scene-loader/public-api/load-result.h"
-#include "dali-scene-loader/public-api/gltf2-loader.h"
 #include "dali-scene-loader/public-api/shader-definition-factory.h"
-#include <dali-test-suite-utils.h>
-#include <string_view>
 
 using namespace Dali;
 using namespace Dali::SceneLoader;
 
 #define DALI_TEST_THROW(expression, exception, predicate) \
-  {\
-    bool daliTestThrowSuccess__ = false;\
-    try\
-    {\
-      do { expression; } while(0);\
-      printf("No exception was thrown.\n");\
-    }\
-    catch (std::decay<exception>::type& ex)\
-    {\
-      daliTestThrowSuccess__ = predicate(ex);\
-    }\
-    catch (...)\
-    {\
-      printf("Wrong type of exception thrown.\n");\
-    }\
-    DALI_TEST_CHECK(daliTestThrowSuccess__);\
+  {                                                       \
+    bool daliTestThrowSuccess__ = false;                  \
+    try                                                   \
+    {                                                     \
+      do                                                  \
+      {                                                   \
+        expression;                                       \
+      } while(0);                                         \
+      printf("No exception was thrown.\n");               \
+    }                                                     \
+    catch(std::decay<exception>::type & ex)               \
+    {                                                     \
+      daliTestThrowSuccess__ = predicate(ex);             \
+    }                                                     \
+    catch(...)                                            \
+    {                                                     \
+      printf("Wrong type of exception thrown.\n");        \
+    }                                                     \
+    DALI_TEST_CHECK(daliTestThrowSuccess__);              \
   }
 
 namespace
 {
 struct Context
 {
-  ResourceBundle resources;
+  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+    return TEST_RESOURCE_DIR "/";
+  };
+
+  ResourceBundle  resources;
   SceneDefinition scene;
 
-  std::vector<AnimationDefinition> animations;
+  std::vector<AnimationDefinition>      animations;
   std::vector<AnimationGroupDefinition> animationGroups;
-  std::vector<CameraParameters> cameras;
-  std::vector<LightParameters> lights;
+  std::vector<CameraParameters>         cameras;
+  std::vector<LightParameters>          lights;
 
-  LoadResult loadResult {
+  LoadResult loadResult{
     resources,
     scene,
     animations,
     animationGroups,
     cameras,
-    lights
-  };
+    lights};
 };
 
 struct ExceptionMessageStartsWith
@@ -77,7 +83,7 @@ struct ExceptionMessageStartsWith
   bool operator()(const std::runtime_error& e)
   {
     const bool success = (0 == strncmp(e.what(), expected.data(), expected.size()));
-    if (!success)
+    if(!success)
     {
       printf("Expected: %s, got: %s.\n", expected.data(), e.what());
     }
@@ -85,7 +91,7 @@ struct ExceptionMessageStartsWith
   }
 };
 
-}
+} // namespace
 
 int UtcDaliGltfLoaderFailedToLoad(void)
 {
@@ -95,8 +101,8 @@ int UtcDaliGltfLoaderFailedToLoad(void)
   sdf.SetResources(ctx.resources);
 
   DALI_TEST_THROW(LoadGltfScene("non-existent.gltf", sdf, ctx.loadResult),
-    std::runtime_error,
-    ExceptionMessageStartsWith{"Failed to load"});
+                  std::runtime_error,
+                  ExceptionMessageStartsWith{"Failed to load"});
 
   DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
@@ -123,8 +129,8 @@ int UtcDaliGltfLoaderFailedToParse(void)
   sdf.SetResources(ctx.resources);
 
   DALI_TEST_THROW(LoadGltfScene(TEST_RESOURCE_DIR "/invalid.gltf", sdf, ctx.loadResult),
-    std::runtime_error,
-    ExceptionMessageStartsWith{"Failed to parse"});
+                  std::runtime_error,
+                  ExceptionMessageStartsWith{"Failed to parse"});
 
   DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
@@ -159,50 +165,46 @@ int UtcDaliGltfLoaderSuccess1(void)
 
   auto& materials = ctx.resources.mMaterials;
   DALI_TEST_EQUAL(2u, materials.size());
-  const MaterialDefinition materialGroundTruth[] {
-    {
-      MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
-        MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS |
-        (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
-      0,
-      Vector4(1.f, .766f, .336f, 1.f),
-      1.f,
-      0.f,
-      {
-        { MaterialDefinition::ALBEDO,
-          { "AnimatedCube_BaseColor.png",
-            SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
-        { MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
-          { "AnimatedCube_MetallicRoughness.png",
-            SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT) } },
-        { MaterialDefinition::NORMAL,
-          { "AnimatedCube_BaseColor.png",
-            SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
-      }
-    },
-    {
-      MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
-        MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
-      0,
-      Vector4(1.f, .766f, .336f, 1.f),
-      1.f,
-      0.f,
-      {
-        { MaterialDefinition::ALBEDO,
-          { "AnimatedCube_BaseColor.png",
-            SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
-        { MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
-          { "AnimatedCube_MetallicRoughness.png",
-            SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT) } },
-        { MaterialDefinition::NORMAL,
-          { "AnimatedCube_BaseColor.png",
-            SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
-      }
-    },
+  const MaterialDefinition materialGroundTruth[]{
+    {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+       MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS |
+       (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
+     0,
+     Vector4(1.f, .766f, .336f, 1.f),
+     1.f,
+     0.f,
+     {
+       {MaterialDefinition::ALBEDO,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+       {MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
+        {"AnimatedCube_MetallicRoughness.png",
+         SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT)}},
+       {MaterialDefinition::NORMAL,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+     }},
+    {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+       MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
+     0,
+     Vector4(1.f, .766f, .336f, 1.f),
+     1.f,
+     0.f,
+     {
+       {MaterialDefinition::ALBEDO,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+       {MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
+        {"AnimatedCube_MetallicRoughness.png",
+         SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT)}},
+       {MaterialDefinition::NORMAL,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+     }},
   };
 
   auto iMaterial = materials.begin();
-  for (auto& m : materialGroundTruth)
+  for(auto& m : materialGroundTruth)
   {
     printf("material %ld\n", iMaterial - materials.begin());
     auto& md = iMaterial->first;
@@ -214,7 +216,7 @@ int UtcDaliGltfLoaderSuccess1(void)
 
     DALI_TEST_EQUAL(md.mTextureStages.size(), m.mTextureStages.size());
     auto iTexture = md.mTextureStages.begin();
-    for (auto& ts: m.mTextureStages)
+    for(auto& ts : m.mTextureStages)
     {
       printf("texture %ld\n", iTexture - md.mTextureStages.begin());
       DALI_TEST_EQUAL(iTexture->mSemantic, ts.mSemantic);
@@ -228,48 +230,47 @@ int UtcDaliGltfLoaderSuccess1(void)
   auto& meshes = ctx.resources.mMeshes;
   DALI_TEST_EQUAL(2u, meshes.size());
 
-  using Blob = MeshDefinition::Blob;
+  using Blob     = MeshDefinition::Blob;
   using Accessor = MeshDefinition::Accessor;
-  const MeshDefinition meshGroundTruth[] {
+  const MeshDefinition meshGroundTruth[]{
     {
       0,
       Geometry::TRIANGLES,
       "AnimatedCube.bin",
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
     },
     {
       0,
       Geometry::TRIANGLES,
       "AnimatedCube.bin",
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
     },
   };
 
   auto iMesh = meshes.begin();
-  for (auto& m : meshGroundTruth)
+  for(auto& m : meshGroundTruth)
   {
     printf("mesh %ld\n", iMesh - meshes.begin());
 
     auto& md = iMesh->first;
     DALI_TEST_EQUAL(md.mFlags, m.mFlags);
     DALI_TEST_EQUAL(md.mPrimitiveType, m.mPrimitiveType);
-    for (auto mp: {
-      &MeshDefinition::mIndices,
-      &MeshDefinition::mPositions,
-      &MeshDefinition::mNormals,
-      &MeshDefinition::mTexCoords,
-      &MeshDefinition::mTangents,
-      &MeshDefinition::mJoints0,
-      &MeshDefinition::mWeights0
-    })
+    for(auto mp : {
+          &MeshDefinition::mIndices,
+          &MeshDefinition::mPositions,
+          &MeshDefinition::mNormals,
+          &MeshDefinition::mTexCoords,
+          &MeshDefinition::mTangents,
+          &MeshDefinition::mJoints0,
+          &MeshDefinition::mWeights0})
     {
       DALI_TEST_EQUAL((md.*mp).IsDefined(), (m.*mp).IsDefined());
       DALI_TEST_EQUAL((md.*mp).mBlob.IsDefined(), (m.*mp).mBlob.IsDefined());
@@ -296,24 +297,25 @@ int UtcDaliGltfLoaderSuccessShort(void)
   TestApplication app;
 
   const std::string resourcePath = TEST_RESOURCE_DIR "/";
-  auto pathProvider = [resourcePath](ResourceType::Value) {
+  auto              pathProvider = [resourcePath](ResourceType::Value) {
     return resourcePath;
   };
 
   Customization::Choices choices;
-  for (auto modelName : {
-    "2CylinderEngine",
-    "AnimatedMorphCube",
-    "AnimatedMorphSphere",
-    "AnimatedTriangle",
-    "BoxAnimated",
-    "CesiumMan",
-    "CesiumMilkTruck",
-    "EnvironmentTest",
-    "MetalRoughSpheres",
-    "MorphPrimitivesTest",
-    "SimpleSparseAccessor",
-  })
+  for(auto modelName : {
+        "2CylinderEngine",
+        "AnimatedMorphCube",
+        "AnimatedMorphSphere",
+        "AnimatedTriangle",
+        "BoxAnimated",
+        "CesiumMan",
+        "CesiumMilkTruck",
+        "EnvironmentTest",
+        "MetalRoughSpheres",
+        "MorphPrimitivesTest",
+        "MRendererTest",
+        "SimpleSparseAccessor",
+      })
   {
     Context ctx;
 
@@ -329,17 +331,17 @@ int UtcDaliGltfLoaderSuccessShort(void)
     DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
 
     auto& scene = ctx.scene;
-    for (auto iRoot : scene.GetRoots())
+    for(auto iRoot : scene.GetRoots())
     {
-      struct Visitor: NodeDefinition::IVisitor
+      struct Visitor : NodeDefinition::IVisitor
       {
-        struct ResourceReceiver: IResourceReceiver
+        struct ResourceReceiver : IResourceReceiver
         {
           std::vector<bool> mCounts;
 
           void Register(ResourceType::Value type, Index id) override
           {
-            if (type == ResourceType::Mesh)
+            if(type == ResourceType::Mesh)
             {
               mCounts[id] = true;
             }
@@ -348,21 +350,22 @@ int UtcDaliGltfLoaderSuccessShort(void)
 
         void Start(NodeDefinition& n) override
         {
-          if (n.mRenderable)
+          if(n.mRenderable)
           {
             n.mRenderable->RegisterResources(receiver);
           }
         }
 
         void Finish(NodeDefinition& n) override
-        {}
+        {
+        }
       } visitor;
       visitor.receiver.mCounts.resize(resources.mMeshes.size(), false);
 
       scene.Visit(iRoot, choices, visitor);
-      for (uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
+      for(uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
       {
-        if (visitor.receiver.mCounts[i0])
+        if(visitor.receiver.mCounts[i0])
         {
           auto raw = resources.mMeshes[i0].first.LoadRaw(resourcePath);
           DALI_TEST_CHECK(!raw.mAttribs.empty());
@@ -376,3 +379,59 @@ int UtcDaliGltfLoaderSuccessShort(void)
 
   END_TEST;
 }
+
+int UtcDaliGltfLoaderMRendererTest(void)
+{
+  Context ctx;
+
+  ShaderDefinitionFactory sdf;
+  sdf.SetResources(ctx.resources);
+  auto& resources = ctx.resources;
+  resources.mEnvironmentMaps.push_back({});
+
+  LoadGltfScene(TEST_RESOURCE_DIR "/MRendererTest.gltf", sdf, ctx.loadResult);
+
+  auto& scene = ctx.scene;
+  auto& roots = scene.GetRoots();
+  DALI_TEST_EQUAL(roots.size(), 1u);
+  DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "RootNode");
+  DALI_TEST_EQUAL(scene.GetNode(roots[0])->mScale, Vector3(1.0f, 1.0f, 1.0f));
+
+  DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
+
+  ViewProjection viewProjection;
+  Transforms     xforms{
+    MatrixStack{},
+    viewProjection};
+  NodeDefinition::CreateParams nodeParams{
+    resources,
+    xforms,
+  };
+
+  Customization::Choices choices;
+
+  TestApplication app;
+
+  Actor root = Actor::New();
+  SetActorCentered(root);
+  for(auto iRoot : roots)
+  {
+    auto resourceRefs = resources.CreateRefCounter();
+    scene.CountResourceRefs(iRoot, choices, resourceRefs);
+    resources.CountEnvironmentReferences(resourceRefs);
+    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
+    {
+      scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
+      scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
+      scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+      root.Add(actor);
+    }
+  }
+
+  DALI_TEST_EQUAL(root.GetChildCount(), 1u);
+  DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::NAME).Get<std::string>(), "RootNode");
+  DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3(1.0f, 1.0f, 1.0f));
+
+  END_TEST;
+}
index 641a9df..1dbbf90 100755 (executable)
@@ -79,6 +79,7 @@ SET(TC_SOURCES
   utc-Dali-DragAndDropDetector.cpp
   utc-Dali-NPatchUtilities.cpp
   utc-Dali-GlView.cpp
+  utc-Dali-GlViewDirectRendering.cpp
 )
 
 # List of test harness files (Won't get parsed for test cases)
index cc7fac4..a1f8405 100644 (file)
@@ -997,10 +997,17 @@ public:
       {
         name            = uniform.name.substr(0, iter);
         auto arrayCount = std::stoi(uniform.name.substr(iter + 1));
+        iter            = uniform.name.find("]");
+        std::string suffix;
+        if(iter != std::string::npos && iter + 1 != uniform.name.length())
+        {
+          suffix = uniform.name.substr(iter + 1); // If there is a suffix, it means its an element of an array of struct
+        }
+
         for(int i = 0; i < arrayCount; ++i)
         {
           std::stringstream nss;
-          nss << name << "[" << i << "]";
+          nss << name << "[" << i << "]" << suffix;
           GetUniformLocation(program, nss.str().c_str()); // Generate a GL loc per element
         }
       }
index 5b3da8c..6cb90ba 100644 (file)
@@ -147,8 +147,6 @@ TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t p
   for(const auto& data : mCustomUniforms)
   {
     fprintf(stderr, "\ncustom uniforms: %s\n", data.name.c_str());
-    mDefaultUniformBlock.members.emplace_back();
-    auto& item = mDefaultUniformBlock.members.back();
 
     auto iter        = data.name.find("[", 0);
     int  numElements = 1;
@@ -161,26 +159,60 @@ TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t p
       {
         numElements = 1;
       }
-
-      item.name         = baseName;
-      item.binding      = 0;
-      item.bufferIndex  = 0;
-      item.uniformClass = Graphics::UniformClass::UNIFORM;
-      item.type         = data.type;
-      item.numElements  = numElements;
-
-      for(int i = 0; i < numElements; ++i)
+      iter = data.name.find("]");
+      std::string suffix;
+      if(iter != std::string::npos && iter + 1 != data.name.length())
       {
-        std::stringstream elementNameStream;
-        elementNameStream << baseName << "[" << i << "]";
+        suffix = data.name.substr(iter + 1); // If there is a suffix, it means it is an element of an array of struct
+      }
 
-        item.locations.push_back(gl.GetUniformLocation(programId, elementNameStream.str().c_str()));
-        item.offsets.push_back(offset);
-        offset += GetSizeForType(data.type);
+      if(!suffix.empty())
+      {
+        // Write multiple items
+        for(int i = 0; i < numElements; ++i)
+        {
+          std::stringstream elementNameStream;
+          elementNameStream << baseName << "[" << i << "]" << suffix;
+          mDefaultUniformBlock.members.emplace_back();
+          auto& item   = mDefaultUniformBlock.members.back();
+          item.name    = elementNameStream.str();
+          item.binding = 0;
+          item.offsets.push_back(offset);
+          item.locations.push_back(gl.GetUniformLocation(programId, elementNameStream.str().c_str()));
+          item.bufferIndex  = 0;
+          item.uniformClass = Graphics::UniformClass::UNIFORM;
+          item.type         = data.type;
+          offset += GetSizeForType(data.type);
+        }
+      }
+      else
+      {
+        // Write 1 item with multiple elements
+        mDefaultUniformBlock.members.emplace_back();
+        auto& item = mDefaultUniformBlock.members.back();
+
+        item.name         = baseName;
+        item.binding      = 0;
+        item.bufferIndex  = 0;
+        item.uniformClass = Graphics::UniformClass::UNIFORM;
+        item.type         = data.type;
+        item.numElements  = numElements;
+
+        for(int i = 0; i < numElements; ++i)
+        {
+          std::stringstream elementNameStream;
+          elementNameStream << baseName << "[" << i << "]";
+          item.locations.push_back(gl.GetUniformLocation(programId, elementNameStream.str().c_str()));
+          item.offsets.push_back(offset);
+          offset += GetSizeForType(data.type);
+        }
       }
     }
     else
     {
+      // Write 1 item with 1 element
+      mDefaultUniformBlock.members.emplace_back();
+      auto& item   = mDefaultUniformBlock.members.back();
       item.name    = data.name;
       item.binding = 0;
       item.offsets.push_back(offset);
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-GlViewDirectRendering.cpp b/automated-tests/src/dali-toolkit/utc-Dali-GlViewDirectRendering.cpp
new file mode 100644 (file)
index 0000000..82e3be9
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <thread>
+
+#include <dali-toolkit-test-suite-utils.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+// Positive test case for a method
+int UtcDaliGlViewDirectRenderingNew(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliGlViewDirectRenderingNew");
+  GlView view = GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGBA8888);
+  DALI_TEST_CHECK(view);
+
+  auto mode1 = view.GetBackendMode();
+
+  DALI_TEST_EQUALS(mode1, GlView::BackendMode::DIRECT_RENDERING, TEST_LOCATION);
+
+  GlView view2 = GlView::New(GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING, GlView::ColorFormat::RGBA8888);
+  DALI_TEST_CHECK(view2);
+
+  auto mode2 = view2.GetBackendMode();
+  DALI_TEST_EQUALS(mode2, GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingNewN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliGlViewDirectRenderingNewN");
+  // Invalid backend mode
+  GlView view = GlView::New(GlView::BackendMode(11111), GlView::ColorFormat::RGBA8888);
+  DALI_TEST_CHECK(!view);
+
+  END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliGlViewDirectRenderingDownCast(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliGlViewDirectRenderingDownCast");
+
+  GlView     view = GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+  BaseHandle handle(view);
+
+  Toolkit::GlView view2 = Toolkit::GlView::DownCast(handle);
+  DALI_TEST_CHECK(view);
+  DALI_TEST_CHECK(view2);
+  DALI_TEST_CHECK(view == view2);
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingCopyAndAssignment(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingCopyAndAssignment");
+
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+  DALI_TEST_CHECK(view);
+
+  GlView copy(view);
+  DALI_TEST_CHECK(view == copy);
+
+  GlView assign;
+  DALI_TEST_CHECK(!assign);
+
+  assign = copy;
+  DALI_TEST_CHECK(assign == view);
+
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingMoveAssignment(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingMoveAssignment");
+
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+  DALI_TEST_EQUALS(1, view.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+  GlView moved;
+  moved = std::move(view);
+  DALI_TEST_CHECK(moved);
+  DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+  DALI_TEST_CHECK(!view);
+
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingSetGraphicsConfigGles20N(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingSetGraphicsConfigGles20");
+  GlView view;
+  try
+  {
+    view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+    DALI_TEST_CHECK(false);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(true);
+  }
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingSetGraphicsConfigGles30(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingSetGraphicsConfigGles30");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  try
+  {
+    view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_3_0);
+    DALI_TEST_CHECK(true);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false);
+  }
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingRenderingMode(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingRenderingMode");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  view.SetRenderingMode(GlView::RenderingMode::ON_DEMAND);
+
+  GlView::RenderingMode mode = view.GetRenderingMode();
+
+  DALI_TEST_EQUALS(GlView::RenderingMode::ON_DEMAND, mode, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingOnSizeSet(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingOnSizeSet");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  application.GetScene().Add(view);
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 size(200.0f, 300.0f, 0.0f);
+  view.SetProperty(Actor::Property::SIZE, size);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(view.GetCurrentProperty<Vector3>(Actor::Property::SIZE), size, TEST_LOCATION);
+
+  END_TEST;
+}
+
+namespace DirectRenderingCode
+{
+
+// Internal callback function
+void glInit(void)
+{
+}
+
+int glRenderFrame(void)
+{
+  static unsigned int retFlag = 0;
+  return retFlag++;
+}
+
+void glTerminate(void)
+{
+}
+
+void resizeCB(Vector2 size)
+{
+}
+
+}
+
+int UtcDaliGlViewDirectRenderingRegisterGlCallbacksN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingRegisterGlCallbacksN");
+  GlView view;
+
+  try
+  {
+    view.RegisterGlCallbacks(Dali::MakeCallback(DirectRenderingCode::glInit), Dali::MakeCallback(DirectRenderingCode::glRenderFrame), Dali::MakeCallback(DirectRenderingCode::glTerminate));
+    DALI_TEST_CHECK(false);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(true);
+  }
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingSetResizeCallbackN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingSetResizeCallback");
+  GlView view;
+
+  try
+  {
+    view.SetResizeCallback(Dali::MakeCallback(DirectRenderingCode::resizeCB));
+    DALI_TEST_CHECK(false);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(true);
+  }
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingRenderOnce(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingRenderOnce");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  try
+  {
+    view.RenderOnce();
+    DALI_TEST_CHECK(true);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false);
+  }
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingWindowVisibilityChanged(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingWindowVisibilityChanged");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+  application.GetScene().Add(view);
+  view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
+  view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+  view.RegisterGlCallbacks(Dali::MakeCallback(DirectRenderingCode::glInit), Dali::MakeCallback(DirectRenderingCode::glRenderFrame), Dali::MakeCallback(DirectRenderingCode::glTerminate));
+  view.SetResizeCallback(Dali::MakeCallback(DirectRenderingCode::resizeCB));
+
+  application.SendNotification();
+  application.Render();
+
+  Window window = DevelWindow::Get(view);
+  window.Hide();
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(true);
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingOnScene(void)
+{
+  ToolkitTestApplication application;
+
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  //Onscene
+  application.GetScene().Add(view);
+  view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
+  view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+  view.RegisterGlCallbacks(Dali::MakeCallback(DirectRenderingCode::glInit), Dali::MakeCallback(DirectRenderingCode::glRenderFrame), Dali::MakeCallback(DirectRenderingCode::glTerminate));
+
+  application.SendNotification();
+  application.Render();
+
+  //Offscene
+  application.GetScene().Remove(view);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(true);
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingControlVisibilityChanged(void)
+{
+  ToolkitTestApplication application;
+
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+  application.GetScene().Add(view);
+
+  application.SendNotification();
+  application.Render();
+
+  view.SetProperty(Actor::Property::VISIBLE, false);
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK(view.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == false);
+
+  view.SetProperty(Actor::Property::VISIBLE, true);
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK(view.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == true);
+
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingResize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingResize");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  application.GetScene().Add(view);
+  view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+  view.RegisterGlCallbacks(Dali::MakeCallback(DirectRenderingCode::glInit), Dali::MakeCallback(DirectRenderingCode::glRenderFrame), Dali::MakeCallback(DirectRenderingCode::glTerminate));
+  view.SetResizeCallback(Dali::MakeCallback(DirectRenderingCode::resizeCB));
+  view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  view.SetProperty(Actor::Property::SIZE, Vector2(360.0f, 360.0f));
+
+  application.SendNotification();
+  application.Render();
+
+  //To GlViewRenderThread can recognize Resize signal the main thread have to sleep.
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(true);
+  END_TEST;
+}
+
+int UtcDaliGlViewDirectRenderingTerminateCallback(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliGlViewDirectRenderingTerminateCallback");
+  GlView view = Toolkit::GlView::New(GlView::BackendMode::DIRECT_RENDERING, GlView::ColorFormat::RGB888);
+
+  application.GetScene().Add(view);
+  view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+  view.RegisterGlCallbacks(Dali::MakeCallback(DirectRenderingCode::glInit), Dali::MakeCallback(DirectRenderingCode::glRenderFrame), Dali::MakeCallback(DirectRenderingCode::glTerminate));
+  view.SetResizeCallback(Dali::MakeCallback(DirectRenderingCode::resizeCB));
+  view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  view.SetProperty(Actor::Property::SIZE, Vector2(360.0f, 360.0f));
+
+  application.SendNotification();
+  application.Render();
+
+
+
+  //To GlViewRenderThread can recognize Resize signal the main thread have to sleep.
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(true);
+  END_TEST;
+}
\ No newline at end of file
index 9db4289..476da78 100644 (file)
@@ -691,6 +691,14 @@ int UtcDaliTextEditorSetPropertyP(void)
   editor.SetProperty(TextEditor::Property::HORIZONTAL_ALIGNMENT, "END");
   DALI_TEST_EQUALS(editor.GetProperty<std::string>(TextEditor::Property::HORIZONTAL_ALIGNMENT), "END", TEST_LOCATION);
 
+  // Check that the Alignment properties can be correctly set
+  editor.SetProperty(DevelTextEditor::Property::VERTICAL_ALIGNMENT, "BOTTOM");
+  DALI_TEST_EQUALS(editor.GetProperty<std::string>(DevelTextEditor::Property::VERTICAL_ALIGNMENT), "BOTTOM", TEST_LOCATION);
+  editor.SetProperty(DevelTextEditor::Property::VERTICAL_ALIGNMENT, "CENTER");
+  DALI_TEST_EQUALS(editor.GetProperty<std::string>(DevelTextEditor::Property::VERTICAL_ALIGNMENT), "CENTER", TEST_LOCATION);
+  editor.SetProperty(DevelTextEditor::Property::VERTICAL_ALIGNMENT, "TOP");
+  DALI_TEST_EQUALS(editor.GetProperty<std::string>(DevelTextEditor::Property::VERTICAL_ALIGNMENT), "TOP", TEST_LOCATION);
+
   // Check scroll properties.
   editor.SetProperty(TextEditor::Property::SCROLL_THRESHOLD, 1.f);
   DALI_TEST_EQUALS(editor.GetProperty<float>(TextEditor::Property::SCROLL_THRESHOLD), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
index f8ee78d..c256b7a 100644 (file)
@@ -238,6 +238,7 @@ int UtcDaliToolkitTextSelectionPopupIconProperties(void)
   popup.SetProperty(TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE, "POPUP_PASTE_BUTTON_ICON_IMAGE");
   popup.SetProperty(TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE, "POPUP_SELECT_BUTTON_ICON_IMAGE");
   popup.SetProperty(TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE, "POPUP_SELECT_ALL_BUTTON_ICON_IMAGE");
+  popup.SetProperty(TextSelectionPopup::Property::POPUP_PRESSED_IMAGE, "POPUP_PRESSED_IMAGE");
 
   DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE).Get<std::string>(), "POPUP_CLIPBOARD_BUTTON_ICON_IMAGE", TEST_LOCATION);
   DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE).Get<std::string>(), "POPUP_CUT_BUTTON_ICON_IMAGE", TEST_LOCATION);
@@ -245,6 +246,7 @@ int UtcDaliToolkitTextSelectionPopupIconProperties(void)
   DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE).Get<std::string>(), "POPUP_PASTE_BUTTON_ICON_IMAGE", TEST_LOCATION);
   DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE).Get<std::string>(), "POPUP_SELECT_BUTTON_ICON_IMAGE", TEST_LOCATION);
   DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE).Get<std::string>(), "POPUP_SELECT_ALL_BUTTON_ICON_IMAGE", TEST_LOCATION);
+  DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_PRESSED_IMAGE).Get<std::string>(), "POPUP_PRESSED_IMAGE", TEST_LOCATION);
 
   END_TEST;
 }
@@ -273,3 +275,35 @@ int UtcDaliToolkitTextSelectionPopupSizeProperties(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextSelectionPopupDurationProperties(void)
+{
+  ToolkitTestApplication application;
+  TextSelectionPopup     popup = TextSelectionPopup::New(nullptr);
+
+  const float popupFadeInDuration = 5.0f;
+  const float popupFadeOutDuration = 10.0f;
+  popup.SetProperty(TextSelectionPopup::Property::POPUP_FADE_IN_DURATION, popupFadeInDuration);
+  popup.SetProperty(TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION, popupFadeOutDuration);
+
+  DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_FADE_IN_DURATION).Get<float>(), popupFadeInDuration, TEST_LOCATION);
+  DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION).Get<float>(), popupFadeOutDuration, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSelectionPopupColorProperties(void)
+{
+  ToolkitTestApplication application;
+  TextSelectionPopup     popup = TextSelectionPopup::New(nullptr);
+
+  popup.SetProperty(TextSelectionPopup::Property::POPUP_DIVIDER_COLOR, Color::RED);
+  popup.SetProperty(TextSelectionPopup::Property::POPUP_ICON_COLOR, Color::BLUE);
+  popup.SetProperty(TextSelectionPopup::Property::POPUP_PRESSED_COLOR, Color::BLACK);
+
+  DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_DIVIDER_COLOR).Get<Vector4>(), Color::RED, TEST_LOCATION);
+  DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_ICON_COLOR).Get<Vector4>(), Color::BLUE, TEST_LOCATION);
+  DALI_TEST_EQUALS(popup.GetProperty(TextSelectionPopup::Property::POPUP_PRESSED_COLOR).Get<Vector4>(), Color::BLACK, TEST_LOCATION);
+
+  END_TEST;
+}
\ No newline at end of file
index 1ec67e2..f5bd6b9 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE_LOADER_GLTF2_ASSET_H_
 #define DALI_SCENE_LOADER_GLTF2_ASSET_H_
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -93,6 +93,7 @@ private:
 
 struct Asset
 {
+  std::string_view mGenerator;
   std::string_view mVersion;
 };
 
index 18923cf..923d0e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -43,6 +43,11 @@ const std::string ORIENTATION_PROPERTY("orientation");
 const std::string SCALE_PROPERTY("scale");
 const std::string BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight");
 
+const std::string MRENDERER_MODEL_IDENTIFICATION("M-Renderer");
+
+const std::string ROOT_NODE_NAME("RootNode");
+const Vector3     SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f);
+
 const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{
   Geometry::POINTS,
   Geometry::LINES,
@@ -692,7 +697,7 @@ void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams)
   }
 }
 
-void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx)
+void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx, bool isMRendererModel)
 {
   auto& output    = cctx.mOutput;
   auto& scene     = output.mScene;
@@ -715,6 +720,11 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con
       nodeDef->mPosition    = node.mTranslation;
       nodeDef->mOrientation = node.mRotation;
       nodeDef->mScale       = node.mScale;
+
+      if(isMRendererModel && node.mName == ROOT_NODE_NAME && node.mScale == SCALE_TO_ADJUST)
+      {
+        nodeDef->mScale *= 0.01f;
+      }
     }
 
     return nodeDef;
@@ -774,11 +784,11 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con
 
   for(auto& n : node.mChildren)
   {
-    ConvertNode(*n, n.GetIndex(), idx, cctx);
+    ConvertNode(*n, n.GetIndex(), idx, cctx, isMRendererModel);
   }
 }
 
-void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
+void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx, bool isMRendererModel)
 {
   auto& outScene = cctx.mOutput.mScene;
   Index rootIdx  = outScene.GetNodeCount();
@@ -788,7 +798,7 @@ void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
       break;
 
     case 1:
-      ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx);
+      ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx, isMRendererModel);
       outScene.AddRootNode(rootIdx);
       break;
 
@@ -802,25 +812,25 @@ void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
 
       for(auto& n : scene.mNodes)
       {
-        ConvertNode(*n, n.GetIndex(), rootIdx, cctx);
+        ConvertNode(*n, n.GetIndex(), rootIdx, cctx, isMRendererModel);
       }
       break;
     }
   }
 }
 
-void ConvertNodes(const gt::Document& doc, ConversionContext& cctx)
+void ConvertNodes(const gt::Document& doc, ConversionContext& cctx, bool isMRendererModel)
 {
-  ConvertSceneNodes(*doc.mScene, cctx);
+  ConvertSceneNodes(*doc.mScene, cctx, isMRendererModel);
 
   for(uint32_t i = 0, i1 = doc.mScene.GetIndex(); i < i1; ++i)
   {
-    ConvertSceneNodes(doc.mScenes[i], cctx);
+    ConvertSceneNodes(doc.mScenes[i], cctx, isMRendererModel);
   }
 
   for(uint32_t i = doc.mScene.GetIndex() + 1; i < doc.mScenes.size(); ++i)
   {
-    ConvertSceneNodes(doc.mScenes[i], cctx);
+    ConvertSceneNodes(doc.mScenes[i], cctx, isMRendererModel);
   }
 }
 
@@ -1155,10 +1165,23 @@ void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactor
 
   gt::Document doc;
 
-  auto& rootObj        = js::Cast<json_object_s>(*root);
-  auto  jsAsset        = js::FindObjectChild("asset", rootObj);
-  auto  jsAssetVersion = js::FindObjectChild("version", js::Cast<json_object_s>(*jsAsset));
-  doc.mAsset.mVersion  = js::Read::StringView(*jsAssetVersion);
+  auto& rootObj = js::Cast<json_object_s>(*root);
+  auto  jsAsset = js::FindObjectChild("asset", rootObj);
+
+  auto jsAssetVersion = js::FindObjectChild("version", js::Cast<json_object_s>(*jsAsset));
+  if(jsAssetVersion)
+  {
+    doc.mAsset.mVersion = js::Read::StringView(*jsAssetVersion);
+  }
+
+  bool isMRendererModel(false);
+  auto jsAssetGenerator = js::FindObjectChild("generator", js::Cast<json_object_s>(*jsAsset));
+  if(jsAssetGenerator)
+  {
+    doc.mAsset.mGenerator = js::Read::StringView(*jsAssetGenerator);
+    isMRendererModel      = (doc.mAsset.mGenerator.find(MRENDERER_MODEL_IDENTIFICATION) != std::string_view::npos);
+  }
+
 
   gt::SetRefReaderObject(doc);
   DOCUMENT_READER.Read(rootObj, doc);
@@ -1168,7 +1191,7 @@ void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactor
 
   ConvertMaterials(doc, cctx);
   ConvertMeshes(doc, cctx);
-  ConvertNodes(doc, cctx);
+  ConvertNodes(doc, cctx, isMRendererModel);
   ConvertAnimations(doc, cctx);
 
   ProcessSkins(doc, cctx);
index b990dc7..4645576 100644 (file)
@@ -310,6 +310,14 @@ enum Type
    * @note If the value is less than 1, the lines could to be overlapped.
    */
   RELATIVE_LINE_SIZE,
+
+  /**
+   * @brief The line vertical alignment.
+   * @details Name "verticalAlignment", type Property::STRING or type VerticalAlignment::Type (Property::INTEGER).
+   *          Values "TOP", "CENTER", "BOTTOM", default TOP.
+   * @note Return type is Property::STRING
+   */
+  VERTICAL_ALIGNMENT,
 };
 
 } // namespace Property
diff --git a/dali-toolkit/internal/controls/gl-view/drawable-view-impl.cpp b/dali-toolkit/internal/controls/gl-view/drawable-view-impl.cpp
new file mode 100644 (file)
index 0000000..9b94546
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/gl-view/drawable-view-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/rendering/renderer.h>
+
+namespace Dali::Toolkit::Internal
+{
+Dali::Toolkit::GlView DrawableView::New()
+{
+  auto* impl   = new DrawableView();
+  Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
+  impl->Initialize();
+  return handle;
+}
+
+DrawableView::DrawableView()
+: Dali::Toolkit::Internal::GlViewImpl( GlView::BackendMode::DIRECT_RENDERING ),
+  mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
+  mDepth(false),
+  mStencil(false),
+  mMSAA(0)
+{
+  mRenderCallback = RenderCallback::New( this, &DrawableView::OnRenderCallback);
+}
+
+DrawableView::~DrawableView() = default;
+
+void DrawableView::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+  mOnInitCallback.reset( initCallback );
+  mOnRenderCallback.reset(renderFrameCallback );
+  mOnTerminateCallback. reset( terminateCallback );
+}
+
+void DrawableView::SetResizeCallback(CallbackBase* resizeCallback)
+{
+  mOnResizeCallback.reset( resizeCallback );
+}
+
+bool DrawableView::SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version)
+{
+  DALI_LOG_ERROR( "DrawableView::SetGraphicsConfig() is currently not implemented");
+
+  return true;
+}
+
+void DrawableView::SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode)
+{
+  mRenderingMode    = mode;
+  Renderer renderer = Self().GetRendererAt(0);
+
+  if(mRenderingMode == Dali::Toolkit::GlView::RenderingMode::ON_DEMAND)
+  {
+    renderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
+  }
+  else
+  {
+    renderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
+  }
+}
+
+Dali::Toolkit::GlView::RenderingMode DrawableView::GetRenderingMode() const
+{
+  return mRenderingMode;
+}
+
+void DrawableView::RenderOnce()
+{
+  // Ignored.
+  // TODO: without rendering on the separate thread the RenderOnce won't
+  // work as expected. Potential implementation of threading may enable that
+  // feature.
+}
+
+void DrawableView::OnInitialize()
+{
+  AddRenderer();
+
+  // Adding VisibilityChange Signal.
+  Actor self = Self();
+  Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &DrawableView::OnControlVisibilityChanged);
+}
+
+void DrawableView::OnSizeSet(const Vector3& targetSize)
+{
+  Control::OnSizeSet(targetSize);
+
+  mSurfaceSize = targetSize;
+
+  // If the callbacks are set then schedule execution of resize callback
+  if(mRenderCallback && mOnResizeCallback)
+  {
+    mSurfaceResized = true;
+  }
+}
+
+void DrawableView::OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type)
+{
+  // Ignored due to lack dedicated rendering thread
+}
+
+void DrawableView::OnWindowVisibilityChanged(Window window, bool visible)
+{
+  // Ignored due to lack dedicated rendering thread
+}
+
+void DrawableView::OnSceneConnection(int depth)
+{
+  Control::OnSceneConnection(depth);
+
+  Actor  self   = Self();
+  Window window = DevelWindow::Get(self);
+
+  // Despite OnWindowVisibilityChanged() is ignored it still should follow
+  // the designed behaviour of GlView so signal is connected regardless
+  if(window)
+  {
+    DevelWindow::VisibilityChangedSignal(window).Connect(this, &DrawableView::OnWindowVisibilityChanged);
+  }
+}
+
+void DrawableView::OnSceneDisconnection()
+{
+  Control::OnSceneDisconnection();
+}
+
+void DrawableView::AddRenderer()
+{
+  Actor    self     = Self();
+  Renderer renderer = Renderer::New( *mRenderCallback );
+  self.AddRenderer(renderer);
+}
+
+bool DrawableView::OnRenderCallback( const RenderCallbackInput& renderCallbackInput )
+{
+  // Init state
+  if( mCurrentViewState == ViewState::INIT )
+  {
+    if(mOnInitCallback)
+    {
+      CallbackBase::Execute(*mOnInitCallback);
+    }
+    mCurrentViewState = ViewState::RENDER;
+  }
+
+  int renderFrameResult = 0;
+  if( mCurrentViewState == ViewState::RENDER )
+  {
+    // The mSurfaceResized is set by another thread so atomic check must be provided
+    bool expected{ true };
+    if(mSurfaceResized.compare_exchange_weak( expected, false,
+                                             std::memory_order_release,
+                                             std::memory_order_relaxed
+                                             ) && mOnResizeCallback)
+    {
+      CallbackBase::Execute(*mOnResizeCallback, static_cast<int>(mSurfaceSize.x), static_cast<int>(mSurfaceSize.y));
+    }
+
+    if(mOnRenderCallback)
+    {
+      renderFrameResult = CallbackBase::ExecuteReturn<int>(*mOnRenderCallback);
+      if(renderFrameResult)
+      {
+        // TODO: may be utilized for RenderOnce feature
+      }
+    }
+  }
+
+  // The terminate callback isn't easy to implement for DR. The NativeImage backend
+  // calls it when the GlView is being destroyed. For DrawableView it means that
+  // the RenderCallback won't be executed (as it is a part of graphics pipeline).
+  // We don't have currenty no way to know whether the View will be destroyed and
+  // to execute last native draw command in the pipeline.
+  //
+  // else if( mCurrentViewState == ViewState::TERMINATE )
+  // {
+  //    CallbackBase::Execute(*mOnTerminateCallback);
+  // }
+
+  return true;
+}
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/gl-view/drawable-view-impl.h b/dali-toolkit/internal/controls/gl-view/drawable-view-impl.h
new file mode 100644 (file)
index 0000000..c61832a
--- /dev/null
@@ -0,0 +1,168 @@
+#ifndef DALI_TOOLKIT_INTERNAL_DRAWABLE_VIEW_H
+#define DALI_TOOLKIT_INTERNAL_DRAWABLE_VIEW_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/public-api/adaptor-framework/window.h>
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/shader.h>
+#include <dali/public-api/signals/render-callback.h>
+#include "gl-view-interface-impl.h"
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
+
+namespace Dali::Toolkit
+{
+class GlView;
+
+namespace Internal
+{
+class DrawableView : public Dali::Toolkit::Internal::GlViewImpl
+{
+protected:
+  virtual ~DrawableView();
+
+public:
+  /**
+   * @copydoc Dali::Toolkit::GlView::New()
+   */
+  static Dali::Toolkit::GlView New();
+
+  /**
+   * Construct a new GlView.
+   */
+  DrawableView();
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::RegisterGlCallbacks()
+   */
+  void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback) override;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::SetResizeCallback()
+   */
+  void SetResizeCallback(CallbackBase* resizeCallback) override;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::SetGraphicsConfig()
+   */
+  bool SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version) override;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::SetRenderingMode()
+   */
+  void SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode) override;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::GetRenderingMode()
+   */
+  Dali::Toolkit::GlView::RenderingMode GetRenderingMode() const override;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::RenderOnce()
+   */
+  void RenderOnce();
+
+private: // From Control
+  /**
+   * @copydoc Toolkit::Control::OnInitialize()
+   */
+  virtual void OnInitialize() override;
+
+  /**
+   * @copydoc Toolkit::Control::OnSceneConnection()
+   */
+  void OnSceneConnection(int depth) override;
+
+  /**
+   * @copydoc Toolkit::Control::OnSceneDisconnection()
+   */
+  void OnSceneDisconnection() override;
+
+  /**
+   * @copydoc Toolkit::Control::OnSizeSet()
+   */
+  void OnSizeSet(const Vector3& targetSize) override;
+
+private:
+  // Undefined copy constructor and assignment operators
+  DrawableView(const DrawableView& GlView);
+  DrawableView& operator=(const DrawableView& GlView);
+
+  /**
+   * Callback when the visibility of the GlView is changed
+   */
+  void OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type);
+
+  /**
+   * Callback when the visibility of the window is changed
+   */
+  void OnWindowVisibilityChanged(Dali::Window window, bool visible);
+
+  /**
+   * Adds renderer to Actor.
+   */
+  void AddRenderer();
+
+private:
+
+  bool OnRenderCallback( const RenderCallbackInput& renderCallbackInput );
+
+private:
+  Dali::Toolkit::GlView::RenderingMode mRenderingMode;
+
+  bool mDepth;
+  bool mStencil;
+  int  mMSAA;
+
+  std::unique_ptr<RenderCallback> mRenderCallback;
+
+  /*
+   * Used within RenderCallback to handle the current render state
+   */
+  enum class ViewState
+  {
+    INIT,
+    RENDER,
+    TERMINATE
+  };
+
+  ViewState mCurrentViewState{ViewState::INIT}; ///< state within RenderCallback
+
+  // These callbacks are stored for GLView API compatibility
+  std::unique_ptr<CallbackBase> mOnInitCallback;
+  std::unique_ptr<CallbackBase> mOnRenderCallback;
+  std::unique_ptr<CallbackBase> mOnTerminateCallback;
+  std::unique_ptr<CallbackBase> mOnResizeCallback;
+
+  std::atomic_bool mSurfaceResized{false}; ///< Flag to invoke surface resize callback
+
+  Size mSurfaceSize{}; ///< Surface size
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_DRAWABLE_VIEW_H
index b37189a..2eaf78c 100644 (file)
@@ -40,14 +40,14 @@ namespace Internal
 {
 Dali::Toolkit::GlView GlView::New(Dali::Toolkit::GlView::ColorFormat colorFormat)
 {
-  GlView*               impl   = new GlView(colorFormat);
+  auto* impl   = new Dali::Toolkit::Internal::GlView(colorFormat);
   Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
   impl->Initialize();
   return handle;
 }
 
 GlView::GlView(Dali::Toolkit::GlView::ColorFormat colorFormat)
-: Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
+: Dali::Toolkit::Internal::GlViewImpl( Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING ),
   mRenderThread(nullptr),
   mNativeImageQueue(nullptr),
   mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
index 2dcb0b1..306a53b 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/gl-view/gl-view-render-thread.h>
+#include <dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
 
-namespace Dali
-{
-namespace Toolkit
+
+namespace Dali::Toolkit
 {
 class GlView;
 
 namespace Internal
 {
-class GlView : public Dali::Toolkit::Internal::Control
+class GlView : public Dali::Toolkit::Internal::GlViewImpl
 {
 protected:
   virtual ~GlView();
@@ -57,32 +57,32 @@ public:
   /**
    * @copydoc Dali::Toolkit::GlView::RegisterGlCallbacks()
    */
-  void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+  void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback) override;
 
   /**
    * @copydoc Dali::Toolkit::GlView::SetResizeCallback()
    */
-  void SetResizeCallback(CallbackBase* resizeCallback);
+  void SetResizeCallback(CallbackBase* resizeCallback) override;
 
   /**
-   * @copydoc Dali::Toolkit::GlView::SetGraphisConfig()
+   * @copydoc Dali::Toolkit::GlView::SetGraphicsConfig()
    */
-  bool SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version);
+  bool SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version) override;
 
   /**
    * @copydoc Dali::Toolkit::GlView::SetRenderingMode()
    */
-  void SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode);
+  void SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode) override;
 
   /**
    * @copydoc Dali::Toolkit::GlView::GetRenderingMode()
    */
-  Dali::Toolkit::GlView::RenderingMode GetRenderingMode() const;
+  Dali::Toolkit::GlView::RenderingMode GetRenderingMode() const override;
 
   /**
    * @copydoc Dali::Toolkit::GlView::RenderOnce()
    */
-  void RenderOnce();
+  void RenderOnce() override;
 
 private: // From Control
   /**
@@ -155,22 +155,6 @@ private:
 
 } // namespace Internal
 
-inline Dali::Toolkit::Internal::GlView& GetImpl(Dali::Toolkit::GlView& handle)
-{
-  DALI_ASSERT_ALWAYS(handle);
-  Dali::RefObject& impl = handle.GetImplementation();
-  return static_cast<Dali::Toolkit::Internal::GlView&>(impl);
-}
-
-inline const Dali::Toolkit::Internal::GlView& GetImpl(const Dali::Toolkit::GlView& handle)
-{
-  DALI_ASSERT_ALWAYS(handle);
-  const Dali::RefObject& impl = handle.GetImplementation();
-  return static_cast<const Dali::Toolkit::Internal::GlView&>(impl);
-}
-
-} // namespace Toolkit
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_GL_VIEW_H
diff --git a/dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h b/dali-toolkit/internal/controls/gl-view/gl-view-interface-impl.h
new file mode 100644 (file)
index 0000000..5547789
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef DALI_TOOLKIT_INTERNAL_GL_VIEW_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_GL_VIEW_IMPL_H
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/public-api/adaptor-framework/window.h>
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/shader.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/gl-view-render-thread.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
+
+namespace Dali::Toolkit
+{
+class GlView;
+
+namespace Internal
+{
+class GlViewImpl : public Dali::Toolkit::Internal::Control
+{
+protected:
+
+  virtual ~GlViewImpl() = default;
+
+public:
+
+  /**
+   * Construct a new GlView.
+   */
+  explicit GlViewImpl( GlView::BackendMode backendMode ) :
+    Control(ControlBehaviour(0u | ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
+    mBackendMode(backendMode)
+  {
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::RegisterGlCallbacks()
+   */
+  virtual void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback) = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::SetResizeCallback()
+   */
+  virtual void SetResizeCallback(CallbackBase* resizeCallback) = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::SetGraphisConfig()
+   */
+  virtual bool SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version) = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::SetRenderingMode()
+   */
+  virtual void SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode) = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::GetRenderingMode()
+   */
+  virtual Dali::Toolkit::GlView::RenderingMode GetRenderingMode() const = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::GetBackendMode()
+   */
+  [[nodiscard]] Dali::Toolkit::GlView::BackendMode GetBackendMode() const
+  {
+    return mBackendMode;
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::GlView::RenderOnce()
+   */
+  virtual void RenderOnce() = 0;
+
+private: // From Control
+  /**
+   * @copydoc Toolkit::Control::OnInitialize()
+   */
+  virtual void OnInitialize() override = 0;
+
+  /**
+   * @copydoc Toolkit::Control::OnSceneConnection()
+   */
+  virtual void OnSceneConnection(int depth) override = 0;
+
+  /**
+   * @copydoc Toolkit::Control::OnSceneDisconnection()
+   */
+  virtual void OnSceneDisconnection() override = 0;
+
+protected:
+
+  GlView::BackendMode mBackendMode { GlView::BackendMode::DEFAULT }; ///< Implementation backend mode (DirectRendering, EGL image)
+};
+
+} // namespace Internal
+
+inline Dali::Toolkit::Internal::GlViewImpl& GetImpl(Dali::Toolkit::GlView& handle)
+{
+  DALI_ASSERT_ALWAYS(handle);
+  Dali::RefObject& impl = handle.GetImplementation();
+  return static_cast<Dali::Toolkit::Internal::GlViewImpl&>(impl);
+}
+
+inline const Dali::Toolkit::Internal::GlViewImpl& GetImpl(const Dali::Toolkit::GlView& handle)
+{
+  DALI_ASSERT_ALWAYS(handle);
+  const Dali::RefObject& impl = handle.GetImplementation();
+  return static_cast<const Dali::Toolkit::Internal::GlViewImpl&>(impl);
+}
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_GL_VIEW_IMPL_H
index 42153dc..b44029c 100644 (file)
@@ -159,6 +159,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "strikethrough",
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "inputStrikethrough",                   MAP,       INPUT_STRIKETHROUGH                 )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "characterSpacing",                     FLOAT,     CHARACTER_SPACING                   )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "relativeLineSize",                     FLOAT,     RELATIVE_LINE_SIZE                  )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "verticalAlignment",                    STRING,    VERTICAL_ALIGNMENT                  )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",     SIGNAL_INPUT_STYLE_CHANGED    )
index 5ea2cf1..361607a 100644 (file)
@@ -126,6 +126,16 @@ void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Pr
       }
       break;
     }
+    case Toolkit::DevelTextEditor::Property::VERTICAL_ALIGNMENT:
+    {
+      Toolkit::Text::VerticalAlignment::Type alignment(static_cast<Text::VerticalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
+      if(Text::GetVerticalAlignmentEnumeration(value, alignment))
+      {
+        impl.mController->SetVerticalAlignment(alignment);
+        DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
+      }
+      break;
+    }
     case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
     {
       const float threshold = value.Get<float>();
@@ -786,6 +796,16 @@ Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor tex
       }
       break;
     }
+    case Toolkit::DevelTextEditor::Property::VERTICAL_ALIGNMENT:
+    {
+      const char* name = Text::GetVerticalAlignmentString(impl.mController->GetVerticalAlignment());
+
+      if(name)
+      {
+        value = std::string(name);
+      }
+      break;
+    }
     case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
     {
       value = impl.mDecorator->GetScrollThreshold();
index 5d41058..ffa258d 100644 (file)
@@ -38,6 +38,7 @@
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.h>
 #include <dali-toolkit/internal/helpers/color-conversion.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
@@ -149,104 +150,8 @@ void TextSelectionPopup::SetProperty(BaseObject* object, Property::Index index,
 
   if(selectionPopup)
   {
-    TextSelectionPopup& impl(GetImpl(selectionPopup));
-
-    switch(index)
-    {
-      case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
-      {
-        impl.SetDimensionToCustomise(POPUP_MAXIMUM_SIZE, value.Get<Vector2>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
-      {
-        impl.SetDimensionToCustomise(OPTION_MAXIMUM_SIZE, value.Get<Vector2>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
-      {
-        impl.SetDimensionToCustomise(OPTION_MINIMUM_SIZE, value.Get<Vector2>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
-      {
-        impl.SetDimensionToCustomise(OPTION_DIVIDER_SIZE, value.Get<Vector2>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_PADDING:
-      {
-        Vector4 padding(value.Get<Vector4>());
-        impl.SetOptionDividerPadding(Padding(padding.x, padding.y, padding.z, padding.w));
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
-      {
-        impl.SetButtonImage(Toolkit::TextSelectionPopup::CLIPBOARD, value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
-      {
-        impl.SetButtonImage(Toolkit::TextSelectionPopup::CUT, value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
-      {
-        impl.SetButtonImage(Toolkit::TextSelectionPopup::COPY, value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
-      {
-        impl.SetButtonImage(Toolkit::TextSelectionPopup::PASTE, value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
-      {
-        impl.SetButtonImage(Toolkit::TextSelectionPopup::SELECT, value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
-      {
-        impl.SetButtonImage(Toolkit::TextSelectionPopup::SELECT_ALL, value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_DIVIDER_COLOR:
-      {
-        impl.mDividerColor = value.Get<Vector4>();
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_ICON_COLOR:
-      {
-        impl.mIconColor = value.Get<Vector4>();
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_COLOR:
-      {
-        impl.mPressedColor = value.Get<Vector4>();
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_IMAGE:
-      {
-        impl.SetPressedImage(value.Get<std::string>());
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
-      {
-        impl.mFadeInDuration = value.Get<float>();
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
-      {
-        impl.mFadeOutDuration = value.Get<float>();
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER:
-      {
-        Property::Map map = value.Get<Property::Map>();
-        impl.CreateBackgroundBorder(map);
-        break;
-      }
-    } // switch
-  }   // TextSelectionPopup
+    PropertyHandler::SetProperty(selectionPopup, index, value);
+  }
 }
 
 Property::Value TextSelectionPopup::GetProperty(BaseObject* object, Property::Index index)
@@ -257,93 +162,7 @@ Property::Value TextSelectionPopup::GetProperty(BaseObject* object, Property::In
 
   if(selectionPopup)
   {
-    TextSelectionPopup& impl(GetImpl(selectionPopup));
-
-    switch(index)
-    {
-      case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
-      {
-        value = impl.GetDimensionToCustomise(POPUP_MAXIMUM_SIZE);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
-      {
-        value = impl.GetDimensionToCustomise(OPTION_MAXIMUM_SIZE);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
-      {
-        value = impl.GetDimensionToCustomise(OPTION_MINIMUM_SIZE);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
-      {
-        value = impl.GetDimensionToCustomise(OPTION_DIVIDER_SIZE);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_PADDING:
-      {
-        Padding padding = impl.GetOptionDividerPadding();
-        value           = Vector4(padding.left, padding.right, padding.top, padding.bottom);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
-      {
-        value = impl.GetButtonImage(Toolkit::TextSelectionPopup::CLIPBOARD);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
-      {
-        value = impl.GetButtonImage(Toolkit::TextSelectionPopup::CUT);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
-      {
-        value = impl.GetButtonImage(Toolkit::TextSelectionPopup::COPY);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
-      {
-        value = impl.GetButtonImage(Toolkit::TextSelectionPopup::PASTE);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
-      {
-        value = impl.GetButtonImage(Toolkit::TextSelectionPopup::SELECT);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
-      {
-        value = impl.GetButtonImage(Toolkit::TextSelectionPopup::SELECT_ALL);
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_IMAGE:
-      {
-        value = impl.GetPressedImage();
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
-      {
-        value = impl.mFadeInDuration;
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
-      {
-        value = impl.mFadeOutDuration;
-        break;
-      }
-      case Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER:
-      {
-        Property::Map         map;
-        Toolkit::Visual::Base visual = DevelControl::GetVisual(impl, Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER);
-        if(visual)
-        {
-          visual.CreatePropertyMap(map);
-        }
-        value = map;
-        break;
-      }
-    } // switch
+    value = PropertyHandler::GetProperty(selectionPopup, index);
   }
   return value;
 }
index 41686ee..db51100 100644 (file)
@@ -273,6 +273,8 @@ private: // Implementation
   virtual ~TextSelectionPopup();
 
 protected:
+  struct PropertyHandler;
+
   class TextSelectionPopupAccessible : public DevelControl::ControlAccessible
   {
   public:
diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.cpp b/dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.cpp
new file mode 100644 (file)
index 0000000..fe6e93f
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.h>
+#include <dali/integration-api/debug.h>
+
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gLogFilter;
+#endif
+
+namespace Dali::Toolkit::Internal
+{
+void TextSelectionPopup::PropertyHandler::SetProperty(Toolkit::TextSelectionPopup selectionPopup, Property::Index index, const Property::Value& value)
+{
+  TextSelectionPopup& impl(GetImpl(selectionPopup));
+
+  switch(index)
+  {
+    case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
+    {
+      impl.SetDimensionToCustomise(POPUP_MAXIMUM_SIZE, value.Get<Vector2>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
+    {
+      impl.SetDimensionToCustomise(OPTION_MAXIMUM_SIZE, value.Get<Vector2>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
+    {
+      impl.SetDimensionToCustomise(OPTION_MINIMUM_SIZE, value.Get<Vector2>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
+    {
+      impl.SetDimensionToCustomise(OPTION_DIVIDER_SIZE, value.Get<Vector2>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_PADDING:
+    {
+      Vector4 padding(value.Get<Vector4>());
+      impl.SetOptionDividerPadding(Padding(padding.x, padding.y, padding.z, padding.w));
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
+    {
+      impl.SetButtonImage(Toolkit::TextSelectionPopup::CLIPBOARD, value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
+    {
+      impl.SetButtonImage(Toolkit::TextSelectionPopup::CUT, value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
+    {
+      impl.SetButtonImage(Toolkit::TextSelectionPopup::COPY, value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
+    {
+      impl.SetButtonImage(Toolkit::TextSelectionPopup::PASTE, value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
+    {
+      impl.SetButtonImage(Toolkit::TextSelectionPopup::SELECT, value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
+    {
+      impl.SetButtonImage(Toolkit::TextSelectionPopup::SELECT_ALL, value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_DIVIDER_COLOR:
+    {
+      impl.mDividerColor = value.Get<Vector4>();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_ICON_COLOR:
+    {
+      impl.mIconColor = value.Get<Vector4>();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_COLOR:
+    {
+      impl.mPressedColor = value.Get<Vector4>();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_IMAGE:
+    {
+      impl.SetPressedImage(value.Get<std::string>());
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
+    {
+      impl.mFadeInDuration = value.Get<float>();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
+    {
+      impl.mFadeOutDuration = value.Get<float>();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER:
+    {
+      Property::Map map = value.Get<Property::Map>();
+      impl.CreateBackgroundBorder(map);
+      break;
+    }
+  }
+}
+
+Property::Value TextSelectionPopup::PropertyHandler::GetProperty(Toolkit::TextSelectionPopup selectionPopup, Property::Index index)
+{
+  Property::Value value;
+  TextSelectionPopup& impl(GetImpl(selectionPopup));
+
+  switch(index)
+  {
+    case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
+    {
+      value = impl.GetDimensionToCustomise(POPUP_MAXIMUM_SIZE);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
+    {
+      value = impl.GetDimensionToCustomise(OPTION_MAXIMUM_SIZE);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
+    {
+      value = impl.GetDimensionToCustomise(OPTION_MINIMUM_SIZE);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
+    {
+      value = impl.GetDimensionToCustomise(OPTION_DIVIDER_SIZE);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_PADDING:
+    {
+      Padding padding = impl.GetOptionDividerPadding();
+      value           = Vector4(padding.left, padding.right, padding.top, padding.bottom);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
+    {
+      value = impl.GetButtonImage(Toolkit::TextSelectionPopup::CLIPBOARD);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
+    {
+      value = impl.GetButtonImage(Toolkit::TextSelectionPopup::CUT);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
+    {
+      value = impl.GetButtonImage(Toolkit::TextSelectionPopup::COPY);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
+    {
+      value = impl.GetButtonImage(Toolkit::TextSelectionPopup::PASTE);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
+    {
+      value = impl.GetButtonImage(Toolkit::TextSelectionPopup::SELECT);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
+    {
+      value = impl.GetButtonImage(Toolkit::TextSelectionPopup::SELECT_ALL);
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_DIVIDER_COLOR:
+    {
+      value = impl.mDividerColor;
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_ICON_COLOR:
+    {
+      value = impl.mIconColor;
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_COLOR:
+    {
+      value = impl.mPressedColor;
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_IMAGE:
+    {
+      value = impl.GetPressedImage();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
+    {
+      value = impl.mFadeInDuration;
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
+    {
+      value = impl.mFadeOutDuration;
+      break;
+    }
+    case Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER:
+    {
+      Property::Map         map;
+      Toolkit::Visual::Base visual = DevelControl::GetVisual(impl, Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER);
+      if(visual)
+      {
+        visual.CreatePropertyMap(map);
+      }
+      value = map;
+      break;
+    }
+  }
+
+  return value;
+}
+
+} // namespace Dali::Toolkit::Internal
diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.h b/dali-toolkit/internal/controls/text-controls/text-selection-popup-property-handler.h
new file mode 100644 (file)
index 0000000..805e3d8
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_PROPERTY_HANDLER_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_PROPERTY_HANDLER_H
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h>
+
+namespace Dali::Toolkit::Internal
+{
+/**
+ * Class to manage properties for the TextSelectionPopup
+ */
+struct TextSelectionPopup::PropertyHandler
+{
+  /**
+   * Set properties on the text selection popup
+   *
+   * @param[in] selectionPopup The handle for the text selection popup
+   * @param[in] index The property index of the property to set
+   * @param[in] value The value to set
+   */
+  static void SetProperty(Toolkit::TextSelectionPopup selectionPopup, Property::Index index, const Property::Value& value);
+
+  /**
+   * Get properties from the text selection popup
+   *
+   * @param[in] selectionPopup The handle for the text selection popup
+   * @param[in] index The property index of the property to set
+   * @return the value
+   */
+  static Property::Value GetProperty(Toolkit::TextSelectionPopup selectionPopup, Property::Index index);
+};
+
+} // namespace Dali::Toolkit::Internal
+
+#endif //DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_PROPERTY_HANDLER_H
index 355667e..15640b7 100644 (file)
@@ -111,12 +111,14 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/controls/text-controls/text-field-property-handler.cpp
    ${toolkit_src_dir}/controls/text-controls/text-label-impl.cpp
    ${toolkit_src_dir}/controls/text-controls/text-selection-popup-impl.cpp
+   ${toolkit_src_dir}/controls/text-controls/text-selection-popup-property-handler.cpp
    ${toolkit_src_dir}/controls/text-controls/text-selection-toolbar-impl.cpp
    ${toolkit_src_dir}/controls/tool-bar/tool-bar-impl.cpp
    ${toolkit_src_dir}/controls/tooltip/tooltip.cpp
    ${toolkit_src_dir}/controls/video-view/video-view-impl.cpp
    ${toolkit_src_dir}/controls/web-view/web-view-impl.cpp
    ${toolkit_src_dir}/controls/camera-view/camera-view-impl.cpp
+   ${toolkit_src_dir}/controls/gl-view/drawable-view-impl.cpp
    ${toolkit_src_dir}/controls/gl-view/gl-view-impl.cpp
    ${toolkit_src_dir}/controls/gl-view/gl-view-render-thread.cpp
    ${toolkit_src_dir}/accessibility-manager/accessibility-manager-impl.cpp
index c24a5cf..46d83dd 100644 (file)
@@ -362,6 +362,27 @@ void ChangeTextControllerState(Controller::Impl& impl, EventData::State newState
   }
 }
 
+void UpdateCursorPositionForAlignment(Controller::Impl& impl, bool needFullAlignment)
+{
+  EventData* eventData = impl.mEventData;
+
+  // Set the flag to redo the alignment operation
+  impl.mOperationsPending = static_cast<Controller::OperationsMask>(impl.mOperationsPending | Controller::OperationsMask::ALIGN);
+
+  if(eventData)
+  {
+    // Note: mUpdateAlignment is currently only needed for horizontal alignment
+    eventData->mUpdateAlignment = needFullAlignment;
+
+    // Update the cursor if it's in editing mode
+    if(EventData::IsEditingState(eventData->mState))
+    {
+      impl.ChangeState(EventData::EDITING);
+      eventData->mUpdateCursorPosition = true;
+    }
+  }
+}
+
 } // unnamed Namespace
 
 EventData::EventData(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
@@ -1440,6 +1461,10 @@ void Controller::Impl::ScrollToMakePositionVisible(const Vector2& position, floa
     {
       mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY;
     }
+    else if(mModel->mLogicalModel->mText.Count() == 0u)
+    {
+      Relayouter::CalculateVerticalOffset(*this, mModel->mVisualModel->mControlSize);
+    }
   }
 }
 
@@ -1802,22 +1827,7 @@ void Controller::Impl::SetHorizontalAlignment(Text::HorizontalAlignment::Type al
   {
     // Set the alignment.
     mModel->mHorizontalAlignment = alignment;
-
-    // Set the flag to redo the alignment operation.
-    mOperationsPending = static_cast<OperationsMask>(mOperationsPending | ALIGN);
-
-    if(mEventData)
-    {
-      mEventData->mUpdateAlignment = true;
-
-      // Update the cursor if it's in editing mode
-      if(EventData::IsEditingState(mEventData->mState))
-      {
-        ChangeState(EventData::EDITING);
-        mEventData->mUpdateCursorPosition = true;
-      }
-    }
-
+    UpdateCursorPositionForAlignment(*this, true);
     RequestRelayout();
   }
 }
@@ -1828,7 +1838,7 @@ void Controller::Impl::SetVerticalAlignment(VerticalAlignment::Type alignment)
   {
     // Set the alignment.
     mModel->mVerticalAlignment = alignment;
-    mOperationsPending         = static_cast<OperationsMask>(mOperationsPending | ALIGN);
+    UpdateCursorPositionForAlignment(*this, false);
     RequestRelayout();
   }
 }
index 6f4763e..ebab609 100644 (file)
@@ -447,7 +447,19 @@ Controller::UpdateTextType Controller::Relayouter::Relayout(Controller& controll
   if(!isEditable || !controller.IsMultiLineEnabled())
   {
     // After doing the text layout, the vertical offset to place the actor in the desired position can be calculated.
-    CalculateVerticalOffset(controller, size);
+    CalculateVerticalOffset(impl, size);
+  }
+  else // TextEditor
+  {
+    // If layoutSize is bigger than size, vertical align has no meaning.
+    if(layoutSize.y < size.y)
+    {
+      CalculateVerticalOffset(impl, size);
+      if(impl.mEventData)
+      {
+        impl.mEventData->mScrollAfterDelete = false;
+      }
+    }
   }
 
   if(isEditable)
@@ -769,9 +781,8 @@ void Controller::Relayouter::DoRelayoutHorizontalAlignment(Controller::Impl&
   }
 }
 
-void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, const Size& controlSize)
+void Controller::Relayouter::CalculateVerticalOffset(Controller::Impl& impl, const Size& controlSize)
 {
-  Controller::Impl& impl                  = *controller.mImpl;
   ModelPtr&         model                 = impl.mModel;
   VisualModelPtr&   visualModel           = model->mVisualModel;
   Size              layoutSize            = model->mVisualModel->GetLayoutSize();
index c0ab806..a98ed53 100644 (file)
@@ -97,10 +97,10 @@ struct Controller::Relayouter
   /**
    * @brief Called by the Controller to calculate the veritcal offset give the control size.
    *
-   * @param[in] controller A reference to the controller class
+   * @param[in] impl A reference to the controller impl class
    * @param[in] controlSize The control size
    */
-  static void CalculateVerticalOffset(Controller& controller, const Size& controlSize);
+  static void CalculateVerticalOffset(Controller::Impl& impl, const Size& controlSize);
 
   /**
   * @brief Calculates the layout size of control according to @p requestedControllerSize and @p requestedOperationsMask
index 958d031..91939c0 100644 (file)
 #include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/drawable-view-impl.h>
 #include <dali-toolkit/internal/controls/gl-view/gl-view-impl.h>
 
-namespace Dali
+namespace Dali::Toolkit
 {
-namespace Toolkit
-{
-GlView::GlView()
-{
-}
+
+GlView::GlView() = default;
 
 GlView::GlView(const GlView& GlView) = default;
 
@@ -37,18 +35,38 @@ GlView& GlView::operator=(const GlView& GlView) = default;
 
 GlView& GlView::operator=(GlView&& rhs) = default;
 
-GlView::~GlView()
+GlView::~GlView() = default;
+
+GlView GlView::New(ColorFormat colorFormat)
 {
+  // This function is backward compatible and always returns
+  // backend based on NativeImage.
+  return Internal::GlView::New( colorFormat );
 }
 
-GlView GlView::New(ColorFormat colorFormat)
+GlView GlView::New(BackendMode backendMode, ColorFormat colorFormat)
 {
-  return Internal::GlView::New(colorFormat);
+  switch(backendMode)
+  {
+    case BackendMode::DIRECT_RENDERING:
+    {
+      return Internal::DrawableView::New();
+    }
+    case BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING:
+    {
+      return Internal::GlView::New(colorFormat);
+    }
+    default:
+    {
+      DALI_ASSERT_ALWAYS("Invalid BackendMode");
+    }
+  }
+  return {};
 }
 
 GlView GlView::DownCast(BaseHandle handle)
 {
-  return Control::DownCast<GlView, Internal::GlView>(handle);
+  return Control::DownCast<GlView, Internal::GlViewImpl>(handle);
 }
 
 void GlView::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
@@ -76,12 +94,17 @@ Dali::Toolkit::GlView::RenderingMode GlView::GetRenderingMode() const
   return Dali::Toolkit::GetImpl(*this).GetRenderingMode();
 }
 
+Dali::Toolkit::GlView::BackendMode GlView::GetBackendMode() const
+{
+  return Dali::Toolkit::GetImpl(*this).GetBackendMode();
+}
+
 void GlView::RenderOnce()
 {
   Dali::Toolkit::GetImpl(*this).RenderOnce();
 }
 
-GlView::GlView(Internal::GlView& implementation)
+GlView::GlView(Internal::GlViewImpl& implementation)
 : Control(implementation)
 {
 }
@@ -89,9 +112,7 @@ GlView::GlView(Internal::GlView& implementation)
 GlView::GlView(Dali::Internal::CustomActor* internal)
 : Control(internal)
 {
-  VerifyCustomActorPointer<Internal::GlView>(internal);
+  VerifyCustomActorPointer<Internal::GlViewImpl>(internal);
 }
 
-} // namespace Toolkit
-
 } // namespace Dali
index 57c3201..099b00f 100644 (file)
@@ -26,7 +26,7 @@ namespace Toolkit
 {
 namespace Internal DALI_INTERNAL
 {
-class GlView;
+class GlViewImpl;
 }
 
 /**
@@ -36,10 +36,42 @@ class GlView;
  * GlView creates a GL context, a GL surface and a render thread.
  * The render thread invokes user's callbacks.
  *
+ * @SINCE_2_0.45
  */
 class DALI_TOOLKIT_API GlView : public Dali::Toolkit::Control
 {
 public:
+
+  /**
+   * @brief Implementation backend mode
+   *
+   * @SINCE_2_1.18
+   */
+  enum class BackendMode
+  {
+    /**
+     * DIRECT_RENDERING mode executes GL code within DALi graphics
+     * pipeline. When Renderer is about to be drawn, the callback
+     * will be executed and the custom code "injected" into the pipeline.
+     * This allows rendering directly to the surface rather than offscreen.
+     */
+    DIRECT_RENDERING = 0,
+
+    /**
+     * EGL_IMAGE_OFFSCREEN_RENDERING mode executes GL code in own thread
+     * and renders to the offscreen NativeImage (EGL) buffer. This backend
+     * will render in parallel but has higher memory footprint and may suffer
+     * performance issues due to using EGL image.
+     */
+    EGL_IMAGE_OFFSCREEN_RENDERING,
+
+    /**
+     * The default mode is set to EGL_IMAGE_OFFSCREEN_RENDERING for backwards
+     * compatibility.
+     */
+    DEFAULT = EGL_IMAGE_OFFSCREEN_RENDERING
+  };
+
   /**
    * @brief Enumeration for rendering mode
    *
@@ -47,6 +79,8 @@ public:
    * It has two options.
    * One of them is continuous mode. It is rendered continuously.
    * The other is on demand mode. It is rendered by application.
+   *
+   * @SINCE_2_0.45
    */
   enum class RenderingMode
   {
@@ -58,6 +92,8 @@ public:
    * @brief Enumeration for Graphics API version
    *
    * This Enumeration is used to set a GLES version for EGL configuration.
+   *
+   * @SINCE_2_0.45
    */
   enum class GraphicsApiVersion
   {
@@ -69,6 +105,8 @@ public:
    * @brief Enumeration for color buffer format
    *
    * This Enumeration is used to set a color buffer format of GlView
+   *
+   * @SINCE_2_0.45
    */
   enum class ColorFormat
   {
@@ -78,13 +116,34 @@ public:
 
   /**
    * @brief Creates a GlView control.
+   *
+   * @note This function always creates the GlView with NativeImage backend.
+   *
    * @param[in] colorFormat the format of the color buffer.
    * @return A handle to a GlView control
+   *
+   * @SINCE_2_0.45
    */
   static GlView New(ColorFormat colorFormat);
 
   /**
+   * @brief Creates a GlView control.
+   *
+   * The new GlView will be created with specified backend.
+   * The colorFormat is ignored for DIRECT_RENDERING backend.
+   *
+   * @param[in] colorFormat the format of the color buffer.
+   * @param[in] backendMode the backend used by the GlView
+   * @return A handle to a GlView control
+   *
+   * @SINCE_2_1.18
+   */
+  static GlView New(BackendMode backendMode, ColorFormat colorFormat);
+
+  /**
    * @brief Creates an uninitialized GlView.
+   *
+   * @SINCE_2_0.45
    */
   GlView();
 
@@ -92,6 +151,8 @@ public:
    * @brief Destructor.
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   *
+   * @SINCE_2_0.45
    */
   ~GlView();
 
@@ -99,6 +160,8 @@ public:
    * @brief Copy constructor.
    *
    * @param[in] GlView GlView to copy. The copied GlView will point at the same implementation
+   *
+   * @SINCE_2_0.45
    */
   GlView(const GlView& GlView);
 
@@ -106,6 +169,8 @@ public:
    * @brief Move constructor
    *
    * @param[in] rhs A reference to the moved handle
+   *
+   * @SINCE_2_0.45
    */
   GlView(GlView&& rhs);
 
@@ -114,6 +179,8 @@ public:
    *
    * @param[in] GlView The GlView to assign from
    * @return A reference to this
+   *
+   * @SINCE_2_0.45
    */
   GlView& operator=(const GlView& GlView);
 
@@ -122,6 +189,8 @@ public:
    *
    * @param[in] rhs A reference to the moved handle
    * @return A reference to this
+   *
+   * @SINCE_2_0.45
    */
   GlView& operator=(GlView&& rhs);
 
@@ -133,6 +202,8 @@ public:
    *
    * @param[in] handle Handle to an object
    * @return Handle to a GlView or an uninitialized handle
+   *
+   * @SINCE_2_0.45
    */
   static GlView DownCast(BaseHandle handle);
 
@@ -164,6 +235,8 @@ public:
    * @note Ownership of the callbacks is passed onto this class.
    * <b>You can't call Dali APIs in your callbacks because it is invoked in GlView's own render thread.</b>
    * And this must be called before adding GlView to the scene.
+   *
+   * @SINCE_2_0.45
    */
   void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
 
@@ -182,6 +255,8 @@ public:
    * @note Ownership of the callback is passed onto this class.
    * <b>You can't call Dali APIs in your callback because it is invoked in GlView's own render thread.</b>
    * And this must be called before adding GlView to the scene.
+   *
+   * @SINCE_2_0.45
    */
   void SetResizeCallback(CallbackBase* resizeCallback);
 
@@ -192,13 +267,24 @@ public:
    *
    * @note The default Rendering mode is CONTINUOUS.
    * If ON_DEMAND mode is set, it is rendered by RenderOnce()
+   *
+   * @SINCE_2_0.45
    */
   void SetRenderingMode(RenderingMode mode);
 
   /**
    * @brief Gets the rendering mode.
+   *
+   * @SINCE_2_0.45
+   */
+  [[nodiscard]] RenderingMode GetRenderingMode() const;
+
+  /**
+   * @brief Gets the backend mode.
+   *
+   * @SINCE_2_1.18
    */
-  RenderingMode GetRenderingMode() const;
+  [[nodiscard]] BackendMode GetBackendMode() const;
 
   /**
    * @brief Sets egl configuration for GlView
@@ -208,12 +294,16 @@ public:
    * @param[in] msaa the expected sampling number per pixel.
    * @param[in] version the graphics API version
    * @return True if the config exists, false otherwise.
+   *
+   * @SINCE_2_0.45
    */
   bool SetGraphicsConfig(bool depth, bool stencil, int msaa, GraphicsApiVersion version);
 
   /**
    * @brief Renders once more even if GL render functions are not added to idler.
    * @note Will not work if the window is hidden or GL render functions are added to idler
+   *
+   * @SINCE_2_0.45
    */
   void RenderOnce();
 
@@ -222,12 +312,16 @@ public: // Not intended for application developers
   /**
    * @brief Creates a handle using the Toolkit::Internal implementation.
    * @param[in] implementation The GlView implementation
+   *
+   * @SINCE_2_0.45
    */
-  DALI_INTERNAL GlView(Internal::GlView& implementation);
+  DALI_INTERNAL GlView(Internal::GlViewImpl& implementation);
 
   /**
    * @brief Allows the creation of this GlView from an Internal::CustomActor pointer.
    * @param[in] internal A pointer to the internal CustomActor
+   *
+   * @SINCE_2_0.45
    */
   DALI_INTERNAL GlView(Dali::Internal::CustomActor* internal);
   /// @endcond
index 7b27bbf..6f9e75d 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 16;
+const unsigned int TOOLKIT_MICRO_VERSION = 17;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 6e1ab5c..01aa94e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.1.16
+Version:    2.1.17
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT