[dali_1.9.30] Merge branch 'devel/master' 44/244444/1
authorDavid Steele <david.steele@ws-1747.seri.co.uk>
Fri, 18 Sep 2020 10:35:33 +0000 (11:35 +0100)
committerDavid Steele <david.steele@ws-1747.seri.co.uk>
Fri, 18 Sep 2020 10:35:33 +0000 (11:35 +0100)
Change-Id: Ie458776623bc8eabd38c5d20534e1bc5b596c500

28 files changed:
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Animation.cpp
automated-tests/src/dali/utc-Dali-CustomActor.cpp
automated-tests/src/dali/utc-Dali-Texture.cpp
automated-tests/src/dali/utc-Dali-TextureSet.cpp
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
dali/devel-api/file.list
dali/devel-api/rendering/texture-devel.cpp [new file with mode: 0644]
dali/devel-api/rendering/texture-devel.h [new file with mode: 0644]
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/common/object-impl.cpp
dali/internal/event/common/object-impl.h
dali/internal/event/common/property-helper.h
dali/internal/event/common/type-info-impl.cpp
dali/internal/event/object/default-property-metadata.h
dali/internal/event/rendering/texture-impl.cpp
dali/internal/event/rendering/texture-impl.h
dali/internal/render/gl-resources/context.h
dali/internal/update/animation/scene-graph-animator.h
dali/internal/update/common/property-owner.cpp
dali/internal/update/common/property-owner.h
dali/internal/update/common/uniform-map.h
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/public-api/dali-core-version.cpp
packaging/dali.spec

index f0aef23..0b2a35b 100644 (file)
@@ -1296,6 +1296,8 @@ int UtcDaliActorGetCurrentSizeImmediate(void)
 
   DALI_TEST_CHECK(actor.GetTargetSize() == vector);
 
+  application.GetScene().Add(actor);
+
   // Start the animation
   animation.Play();
 
index 629d3e4..7c229c0 100644 (file)
@@ -2216,9 +2216,91 @@ int UtcDaliAnimationPlayP(void)
   END_TEST;
 }
 
+int UtcDaliAnimationPlayOffSceneP(void)
+{
+  // Test that an animation cannot be played, when the actor is off-stage.
+  // And the property value and the current property value should not be changed in the case.
+
+  TestApplication application;
+
+  Actor   actor = Actor::New();
+  Vector3 basePosition(Vector3::ZERO);
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
+  // Not added to the stage yet!
+
+  // Build the animation
+  float     durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3   targetPosition(100.0f, 100.0f, 100.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+
+  // Start the animation
+  animation.Play();
+
+  bool                 signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 1000.0f) + 1u /*just beyond the animation duration*/);
+
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  // An animation can't be played. The position shouldn't be changed.
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
+
+  // Add to the stage
+  application.GetScene().Add(actor);
+
+  // Start the animation again
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 1000.0f) + 1u /*just beyond the animation duration*/);
+
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), targetPosition, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetProperty<Vector3>(Actor::Property::POSITION), targetPosition, TEST_LOCATION);
+
+  // Reset the position
+  actor[Actor::Property::POSITION] = basePosition;
+
+  application.SendNotification();
+  application.Render();
+
+  // Create an animator again
+  animation.Clear();
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+
+  // Remove from the stage
+  application.GetScene().Remove(actor);
+
+  signalReceived = false;
+
+  // Start the animation again
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 1000.0f) + 1u /*just beyond the animation duration*/);
+
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  // An animation can't be played. The position shouldn't be changed.
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliAnimationPlayOffSceneDiscardP(void)
 {
-  // Test that an animation can be played, when the actor is off-stage.
+  // Test that an animation cannot be played, when the actor is off-stage.
   // When the actor is added to the stage, it should appear at the current position
   // i.e. where it would have been anyway, if on-stage from the beginning.
 
@@ -2249,7 +2331,9 @@ int UtcDaliAnimationPlayOffSceneDiscardP(void)
   // We didn't expect the animation to finish yet
   application.SendNotification();
   finishCheck.CheckSignalNotReceived();
-  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(20, 20, 20), TEST_LOCATION);
+
+  // An animation can't be played. The position shouldn't be changed.
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
 
   // Add to the stage
   application.GetScene().Add(actor);
@@ -2310,7 +2394,7 @@ int UtcDaliAnimationPlayOffSceneDiscardP(void)
 
 int UtcDaliAnimationPlayOffSceneBakeFinalP(void)
 {
-  // Test that an animation can be played, when the actor is off-stage.
+  // Test that an animation cannot be played, when the actor is off-stage.
   // When the actor is added to the stage, it should appear at the current position
   // i.e. where it would have been anyway, if on-stage from the beginning.
 
@@ -2340,7 +2424,9 @@ int UtcDaliAnimationPlayOffSceneBakeFinalP(void)
   // We didn't expect the animation to finish yet
   application.SendNotification();
   finishCheck.CheckSignalNotReceived();
-  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(20, 20, 20), TEST_LOCATION);
+
+  // An animation can't be played. The position shouldn't be changed.
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
 
   // Add to the stage
   application.GetScene().Add(actor);
@@ -2394,7 +2480,7 @@ int UtcDaliAnimationPlayOffSceneBakeFinalP(void)
 
 int UtcDaliAnimationPlayOffSceneBakeP(void)
 {
-  // Test that an animation can be played, when the actor is off-stage.
+  // Test that an animation cannot be played, when the actor is off-stage.
   // When the actor is added to the stage, it should appear at the current position
   // i.e. where it would have been anyway, if on-stage from the beginning.
 
@@ -2425,7 +2511,9 @@ int UtcDaliAnimationPlayOffSceneBakeP(void)
   // We didn't expect the animation to finish yet
   application.SendNotification();
   finishCheck.CheckSignalNotReceived();
-  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(20, 20, 20), TEST_LOCATION);
+
+  // An animation can't be played. The position shouldn't be changed.
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), basePosition, TEST_LOCATION);
 
   // Add to the stage
   application.GetScene().Add(actor);
index 6dd051c..208f563 100644 (file)
@@ -950,6 +950,8 @@ int UtcDaliCustomActorOnSizeAnimation(void)
   Test::TestCustomActor custom = Test::TestCustomActor::New();
   DALI_TEST_EQUALS(0, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
 
+  application.GetScene().Add(custom);
+
   Animation anim = Animation::New(1.0f);
   anim.AnimateTo(Property(custom, Actor::Property::SIZE), Vector3(8.0f, 9.0f, 10.0f));
   anim.Play();
@@ -957,8 +959,8 @@ int UtcDaliCustomActorOnSizeAnimation(void)
   application.SendNotification();
   application.Render(static_cast<unsigned int>(1000.0f));
 
-  DALI_TEST_EQUALS(1, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
-  DALI_TEST_EQUALS("OnSizeAnimation", custom.GetMethodsCalled()[0], TEST_LOCATION);
+  DALI_TEST_EQUALS(2, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
+  DALI_TEST_EQUALS("OnSizeAnimation", custom.GetMethodsCalled()[1], TEST_LOCATION);
   DALI_TEST_EQUALS(8.0f, custom.GetTargetSize().width, TEST_LOCATION);
   DALI_TEST_EQUALS(9.0f, custom.GetTargetSize().height, TEST_LOCATION);
   DALI_TEST_EQUALS(10.0f, custom.GetTargetSize().depth, TEST_LOCATION);
@@ -974,24 +976,26 @@ int UtcDaliCustomActorSizeComponentAnimation(void)
   float                 intialWidth(10.0f);
 
   DALI_TEST_EQUALS(0, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
+
   custom.SetProperty(Actor::Property::SIZE, Vector2(intialWidth, 10.0f)); // First method
+  application.GetScene().Add(custom);
 
   Animation anim = Animation::New(1.0f);
 
-  DALI_TEST_EQUALS(2, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
+  DALI_TEST_EQUALS(3, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
 
   anim.AnimateTo(Property(custom, Actor::Property::SIZE_WIDTH), 20.0f);
 
-  DALI_TEST_EQUALS(2, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
+  DALI_TEST_EQUALS(3, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
 
   anim.Play(); // Triggers second method ( OnSizeAnimation )
 
   application.SendNotification();
   application.Render(static_cast<unsigned int>(1000.0f));
 
-  DALI_TEST_EQUALS(3, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
+  DALI_TEST_EQUALS(4, (int)(custom.GetMethodsCalled().size()), TEST_LOCATION);
 
-  DALI_TEST_EQUALS("OnSizeAnimation", custom.GetMethodsCalled()[2], TEST_LOCATION);
+  DALI_TEST_EQUALS("OnSizeAnimation", custom.GetMethodsCalled()[3], TEST_LOCATION);
 
   END_TEST;
 }
index 60810d1..95cb6c8 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <dali-test-suite-utils.h>
 #include <dali/devel-api/images/pixel-data-devel.h>
+#include <dali/devel-api/rendering/texture-devel.h>
 #include <dali/public-api/dali-core.h>
 #include <test-native-image.h>
 
@@ -940,3 +941,122 @@ int UtcDaliTextureGetHeightNegative(void)
   }
   END_TEST;
 }
+
+int UtcDaliTextureCheckNativeP(void)
+{
+  TestApplication        application;
+  TestNativeImagePointer testNativeImage = TestNativeImage::New(64u, 64u);
+  Texture                nativeTexture   = Texture::New(*testNativeImage);
+
+  DALI_TEST_CHECK(nativeTexture);
+  DALI_TEST_CHECK(DevelTexture::IsNative(nativeTexture));
+  END_TEST;
+}
+
+int UtcDaliTextureCheckNativeN1(void)
+{
+  TestApplication application;
+  unsigned int    width(64);
+  unsigned int    height(64);
+  Texture         texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+
+  DALI_TEST_CHECK(texture);
+  DALI_TEST_CHECK(!DevelTexture::IsNative(texture));
+  END_TEST;
+}
+
+int UtcDaliTextureCheckNativeN2(void)
+{
+  TestApplication application;
+  Texture         texture;
+  try
+  {
+    bool native = DevelTexture::IsNative(texture);
+    DALI_TEST_CHECK(native != native);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(true);
+  }
+  END_TEST;
+}
+
+int UtcDaliTextureApplyFragShaderP1(void)
+{
+  TestApplication        application;
+  TestNativeImagePointer testNativeImage = TestNativeImage::New(64u, 64u);
+  Texture                nativeTexture   = Texture::New(*testNativeImage);
+  DALI_TEST_CHECK(nativeTexture);
+
+  const std::string baseFragShader =
+    "varying mediump vec4 uColor;\n"
+    "void main(){\n"
+    "  gl_FragColor=uColor;\n"
+    "}\n";
+  std::string fragShader = baseFragShader;
+  bool        applied    = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragShader);
+
+  DALI_TEST_CHECK(applied);
+  DALI_TEST_CHECK(baseFragShader.compare(fragShader));
+  DALI_TEST_CHECK(!fragShader.empty());
+  END_TEST;
+}
+
+int UtcDaliTextureApplyFragShaderP2(void)
+{
+  TestApplication        application;
+  TestNativeImagePointer testNativeImage = TestNativeImage::New(64u, 64u);
+  Texture                nativeTexture   = Texture::New(*testNativeImage);
+  DALI_TEST_CHECK(nativeTexture);
+
+  const std::string baseFragShader =
+    "varying mediump vec4 uColor;\n"
+    "varying vec2 vTexCoord;\n"
+    "uniform sampler2D uNative;\n"
+    "void main(){\n"
+    "  gl_FragColor=uColor*texture2D(uNative, vTexCoord);\n"
+    "}\n";
+  std::string fragShader = baseFragShader;
+  bool        applied    = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragShader);
+
+  DALI_TEST_CHECK(applied);
+  DALI_TEST_CHECK(baseFragShader.compare(fragShader));
+  DALI_TEST_CHECK(!fragShader.empty());
+  DALI_TEST_CHECK(fragShader.find("samplerExternalOES") < fragShader.length());
+  END_TEST;
+}
+
+int UtcDaliTextureApplyFragShaderN1(void)
+{
+  TestApplication        application;
+  TestNativeImagePointer testNativeImage = TestNativeImage::New(64u, 64u);
+  Texture                nativeTexture   = Texture::New(*testNativeImage);
+  DALI_TEST_CHECK(nativeTexture);
+
+  std::string fragShader;
+  bool        applied = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragShader);
+
+  DALI_TEST_CHECK(!applied);
+  DALI_TEST_CHECK(fragShader.empty());
+  END_TEST;
+}
+
+int UtcDaliTextureApplyFragShaderN2(void)
+{
+  TestApplication application;
+  unsigned int    width(64);
+  unsigned int    height(64);
+  Texture         texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+
+  const std::string baseFragShader =
+    "varying mediump vec4 uColor;\n"
+    "void main(){\n"
+    "  gl_FragColor=uColor;\n"
+    "}\n";
+  std::string fragShader = baseFragShader;
+  bool        applied    = DevelTexture::ApplyNativeFragmentShader(texture, fragShader);
+
+  DALI_TEST_CHECK(!applied);
+  DALI_TEST_CHECK(!baseFragShader.compare(fragShader));
+  END_TEST;
+}
index 4e30f15..fa2112a 100644 (file)
@@ -531,3 +531,58 @@ int UtcDaliTextureSetGetTextureCountNegative(void)
   }
   END_TEST;
 }
+
+int UtcDaliTextureSetMultipleTextures(void)
+{
+  TestApplication application;
+
+  Shader     shader     = CreateShader();
+  TextureSet textureSet = CreateTextureSet();
+
+  // Set 2 textures
+  Texture texture1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  textureSet.SetTexture(0u, texture1);
+
+  Texture texture2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  textureSet.SetTexture(1u, texture2);
+
+  Geometry geometry = CreateQuadGeometry();
+  Renderer renderer = Renderer::New(geometry, shader);
+  renderer.SetTextures(textureSet);
+
+  Actor actor = Actor::New();
+  actor.AddRenderer(renderer);
+  actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  const std::vector<GLuint>& boundTextures0 = application.GetGlAbstraction().GetBoundTextures(GL_TEXTURE0);
+  DALI_TEST_CHECK(boundTextures0[boundTextures0.size() - 1] == 1u); // the latest one should be 0.
+
+  const std::vector<GLuint>& boundTextures1 = application.GetGlAbstraction().GetBoundTextures(GL_TEXTURE1);
+  size_t count = boundTextures1.size();
+  DALI_TEST_CHECK(boundTextures1[count - 1] == 2u); // the latest one should be 1.
+
+  // Create a new TextureSet
+  textureSet = CreateTextureSet();
+
+  // Set 1 texture
+  textureSet.SetTexture(0u, texture1);
+
+  renderer.SetTextures(textureSet);
+
+  application.SendNotification();
+  application.Render();
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  DALI_TEST_CHECK(gl.GetActiveTextureUnit() == GL_TEXTURE0);
+
+  DALI_TEST_CHECK(boundTextures0[boundTextures0.size() - 1] == 1u);
+  DALI_TEST_CHECK(boundTextures1.size() == count);  // The bound texture count of GL_TEXTURE1 should not be changed.
+
+  END_TEST;
+}
index c971314..fd7f134 100644 (file)
@@ -1393,6 +1393,8 @@ int UtcDaliTypeRegistryAnimatablePropertyComponentRegistrationP(void)
   unsigned int customActorIndices = indices.Size();
   DALI_TEST_EQUALS(actorIndices + 3u, customActorIndices, TEST_LOCATION); // Custom property + registered property
 
+  application.GetScene().Add(customActor);
+
   // Attempt to animate component property, it should not crash
   Animation animation = Animation::New(1.0f);
   animation.AnimateTo(Property(customActor, animatablePropertyComponentIndex1), 200.0f);
@@ -1416,6 +1418,7 @@ int UtcDaliTypeRegistryAnimatablePropertyComponentRegistrationVector2AnimateByP(
   BaseHandle handle = typeInfo.CreateInstance();
   DALI_TEST_CHECK(handle);
   Actor customActor = Actor::DownCast(handle);
+  application.GetScene().Add(customActor);
   DALI_TEST_CHECK(customActor);
 
   const unsigned int index           = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX;
@@ -1469,6 +1472,7 @@ int UtcDaliTypeRegistryAnimatablePropertyComponentRegistrationVector3AnimateByP(
   BaseHandle handle = typeInfo.CreateInstance();
   DALI_TEST_CHECK(handle);
   Actor customActor = Actor::DownCast(handle);
+  application.GetScene().Add(customActor);
   DALI_TEST_CHECK(customActor);
 
   const unsigned int index           = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX;
@@ -1528,6 +1532,7 @@ int UtcDaliTypeRegistryAnimatablePropertyComponentRegistrationVector4AnimateByP(
   BaseHandle handle = typeInfo.CreateInstance();
   DALI_TEST_CHECK(handle);
   Actor customActor = Actor::DownCast(handle);
+  application.GetScene().Add(customActor);
   DALI_TEST_CHECK(customActor);
 
   const unsigned int index           = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX;
index dc872d3..a6dba21 100644 (file)
@@ -30,6 +30,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/object/csharp-type-registry.cpp
   ${devel_api_src_dir}/rendering/frame-buffer-devel.cpp
   ${devel_api_src_dir}/rendering/renderer-devel.cpp
+  ${devel_api_src_dir}/rendering/texture-devel.cpp
   ${devel_api_src_dir}/scripting/scripting.cpp
   ${devel_api_src_dir}/signals/signal-delegate.cpp
   ${devel_api_src_dir}/threading/conditional-wait.cpp
@@ -107,6 +108,7 @@ SET( devel_api_core_object_header_files
 SET( devel_api_core_rendering_header_files
   ${devel_api_src_dir}/rendering/frame-buffer-devel.h
   ${devel_api_src_dir}/rendering/renderer-devel.h
+  ${devel_api_src_dir}/rendering/texture-devel.h
 )
 
 
diff --git a/dali/devel-api/rendering/texture-devel.cpp b/dali/devel-api/rendering/texture-devel.cpp
new file mode 100644 (file)
index 0000000..d56cae6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 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/devel-api/rendering/texture-devel.h>
+#include <dali/internal/event/rendering/texture-impl.h>
+
+namespace Dali
+{
+namespace DevelTexture
+{
+bool IsNative(Dali::Texture texture)
+{
+  auto& impl = GetImplementation(texture);
+  return impl.IsNative();
+}
+
+bool ApplyNativeFragmentShader(Dali::Texture texture, std::string& shader)
+{
+  auto& impl = GetImplementation(texture);
+  return impl.ApplyNativeFragmentShader(shader);
+}
+
+} // namespace DevelTexture
+} // namespace Dali
diff --git a/dali/devel-api/rendering/texture-devel.h b/dali/devel-api/rendering/texture-devel.h
new file mode 100644 (file)
index 0000000..0204a41
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef DALI_TEXTURE_DEVEL_H
+#define DALI_TEXTURE_DEVEL_H
+
+/*
+ * Copyright (c) 2020 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/rendering/texture.h>
+
+namespace Dali
+{
+namespace DevelTexture
+{
+/**
+ * @brief Function to determine if a texture is backed by a native image.
+ *
+ * @return True if the texture is a native image.
+ */
+bool DALI_CORE_API IsNative(Dali::Texture texture);
+
+/**
+ * @brief Converts shader for native image.
+ *
+ * Applies any specific native shader prefix and sampler code to the
+ * given shader.
+ *
+ * @param[in] texture The texture the shader will apply to
+ * @param[in] shader The fragment shader code to modify
+ * @return True if the shader code was modified
+ */
+bool DALI_CORE_API ApplyNativeFragmentShader(Dali::Texture texture, std::string& shader);
+
+} // namespace DevelTexture
+} // namespace Dali
+
+#endif // DALI_TEXTURE_DEVEL_H
index 4911842..6b3386a 100644 (file)
@@ -3496,6 +3496,11 @@ int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
   return componentIndex;
 }
 
+bool Actor::IsAnimationPossible() const
+{
+  return OnScene();
+}
+
 void Actor::SetParent( Actor* parent )
 {
   if( parent )
index 6573930..379667b 100644 (file)
@@ -1679,6 +1679,11 @@ public:
   int32_t GetPropertyComponentIndex( Property::Index index ) const override;
 
   /**
+   * @copydoc Dali::Internal::Object::IsAnimationPossible()
+   */
+  bool IsAnimationPossible() const override;
+
+  /**
    * Retrieve the actor's node.
    * @return The node used by this actor
    */
index 92791da..dde0a5a 100644 (file)
@@ -1108,7 +1108,7 @@ void Animation::NotifyObjects( Animation::Notify notifyValueType )
       AnimatorConnectorBase* connector = mConnectors[ iter->connectorIndex ];
 
       Object* object = connector->GetObject();
-      if( object )
+      if(object && object->IsAnimationPossible())
       {
         const auto propertyIndex = connector->GetPropertyIndex();
         object->NotifyPropertyAnimation(
index e65d1f3..63b809c 100644 (file)
@@ -761,7 +761,7 @@ void Object::NotifyPropertyAnimation( Animation& animation, Property::Index inde
   }
 }
 
-void Object::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName ) const
+void Object::AddUniformMapping(Property::Index propertyIndex, std::string uniformName) const
 {
   // Get the address of the property if it's a scene property
   const PropertyInputImpl* propertyPtr = GetSceneObjectInputProperty( propertyIndex );
@@ -789,7 +789,8 @@ void Object::AddUniformMapping( Property::Index propertyIndex, const std::string
   {
     const SceneGraph::PropertyOwner& sceneObject = GetSceneObject();
 
-    OwnerPointer< SceneGraph::UniformPropertyMapping > map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
+    OwnerPointer<SceneGraph::UniformPropertyMapping> map =
+      new SceneGraph::UniformPropertyMapping(std::move(uniformName), propertyPtr);
     // Message takes ownership of Uniform map (and will delete it after copy)
     AddUniformMapMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), sceneObject, map );
   }
index 5e3afb1..5ef0f9e 100644 (file)
@@ -270,7 +270,7 @@ public:
    * @param propertyIndex index of the property
    * @param uniformName name of the uniform (same as property name)
    */
-  void AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName ) const;
+  void AddUniformMapping(Property::Index propertyIndex, std::string uniformName) const;
 
   /**
    * Removes uniform mapping for given property
@@ -349,6 +349,15 @@ public:
   virtual int32_t GetPropertyComponentIndex( Property::Index index ) const;
 
   /**
+   * Query whether playing an animation is possible or not.
+   * @return true if playing an animation is possible.
+   */
+  virtual bool IsAnimationPossible() const
+  {
+    return true;
+  }
+
+  /**
    * @copydoc Dali::Handle::PropertySetSignal()
    */
   Handle::PropertySetSignalType& PropertySetSignal();
index 74484ba..2d9146f 100644 (file)
@@ -34,34 +34,16 @@ namespace Internal
 
 /**
  * These macros are used to define a table of property details per object.
- * The index property is only compiled in for DEBUG_ENABLED builds and allows checking the table index VS the property enum index.
- * DALI_PROPERTY_TABLE_END Forces a run-time check that will happen once.
+ * Checking of the table index VS the property enum index happens during compile time.
  * the macros define an instance of PropertyMetadata with the name that is passed to DALI_PROPERTY_TABLE_END
  */
-#define DALI_PROPERTY_TABLE_BEGIN const Dali::PropertyDetails DEFAULT_PROPERTY_DETAILS[] = {
-#ifdef DEBUG_ENABLED
-#define DALI_PROPERTY_TABLE_END( startIndex, constantName )   }; const Property::Index DEFAULT_PROPERTY_COUNT = static_cast<Property::Index>( sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Dali::PropertyDetails ) ); \
-  struct PROPERTY_CHECK \
-  { \
-    PROPERTY_CHECK() \
-    { \
-      for( int i = 0; i < DEFAULT_PROPERTY_COUNT; i++ ) \
-      { \
-        if ( DEFAULT_PROPERTY_DETAILS[i].enumIndex != ( startIndex + i ) ) \
-        { \
-          DALI_LOG_ERROR( "Checking property failed: index:%d, enumIndex:%d == index+start:%d, (name:%s)\n", i, \
-                          DEFAULT_PROPERTY_DETAILS[i].enumIndex, (startIndex + i), DEFAULT_PROPERTY_DETAILS[i].name ); \
-          DALI_ASSERT_DEBUG( false && "Property enumeration mismatch" ); \
-        } \
-      } \
-    } \
-  }; \
-  constexpr Dali::DefaultPropertyMetadata constantName{ DEFAULT_PROPERTY_DETAILS, DEFAULT_PROPERTY_COUNT }; \
-  static PROPERTY_CHECK PROPERTY_CHECK_INSTANCE;
-#else
-#define DALI_PROPERTY_TABLE_END( startIndex, constantName )   }; const Property::Index DEFAULT_PROPERTY_COUNT = static_cast<Property::Index>( sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Dali::PropertyDetails ) );\
-  constexpr Dali::DefaultPropertyMetadata constantName{ DEFAULT_PROPERTY_DETAILS, DEFAULT_PROPERTY_COUNT };
-#endif
+#define DALI_PROPERTY_TABLE_BEGIN static constexpr Dali::PropertyDetails DEFAULT_PROPERTY_DETAILS[] = {
+
+#define DALI_PROPERTY_TABLE_END(startIndex, tableName)                                  \
+  };                                                                                    \
+  static constexpr auto tableName = GeneratePropertyMetadata(DEFAULT_PROPERTY_DETAILS); \
+  static_assert(CheckPropertyMetadata(tableName, startIndex), "Property enumeration mismatch");
+
 #define DALI_PROPERTY( text, type, writable, animatable, constraint, index ) { text, index, Dali::Property::type, writable, animatable, constraint },
 
 /**
index 8fd9fb8..48a549e 100644 (file)
@@ -413,7 +413,7 @@ std::string TypeInfo::GetPropertyName( Property::Index index ) const
   // default or custom
   if ( mDefaultProperties && ( index < DEFAULT_PROPERTY_MAX_COUNT ) )
   {
-    const char* name = nullptr;
+    std::string_view name;
     if( GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::name, name ) )
     {
       propertyName = name;
@@ -630,7 +630,7 @@ Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
   {
     for( Property::Index tableIndex = 0; tableIndex < mDefaultPropertyCount; ++tableIndex )
     {
-      if( 0 == name.compare( mDefaultProperties[ tableIndex ].name ) )
+      if(mDefaultProperties[tableIndex].name == name)
       {
         index = mDefaultProperties[ tableIndex ].enumIndex;
         found = true;
index a95a9cd..734eb61 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <string_view>
+
 // INTERNAL INCLUDES
 #include <dali/public-api/object/property.h>
 
@@ -33,7 +36,7 @@ namespace Dali
  */
 struct PropertyDetails
 {
-  const char* name;           ///< The name of the property.
+  std::string_view name;       ///< The name of the property.
   Property::Index enumIndex;  ///< Used to check the index is correct within a debug build.
   Property::Type type;        ///< The property type.
   bool writable;              ///< Whether the property is writable
@@ -47,9 +50,25 @@ struct PropertyDetails
 struct DefaultPropertyMetadata
 {
   const PropertyDetails* propertyTable; ///< address of the table defining property meta-data.
-  Property::Index propertyCount;        ///< count of the default properties.
+  const Property::Index  propertyCount; ///< count of the default properties.
 };
 
+inline constexpr bool CheckPropertyMetadata(const DefaultPropertyMetadata& table, Property::Index startIndex) noexcept
+{
+  for(int i = 0; i < table.propertyCount; i++)
+  {
+    if(table.propertyTable[i].enumIndex != startIndex + i)
+      return false;
+  }
+  return true;
+}
+
+template<size_t N>
+inline constexpr DefaultPropertyMetadata GeneratePropertyMetadata(const PropertyDetails (&array)[N]) noexcept
+{
+  return {array, N};
+}
+
 } // namespace Dali
 
 #endif // DALI_DEFAULT_PROPERTY_METADATA_H
index 7dbc73d..54d611f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
 #include <dali/internal/event/rendering/texture-impl.h> // Dali::Internal::Texture
 
 // INTERNAL INCLUDES
-#include <dali/internal/update/manager/update-manager.h>
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/integration-api/render-controller.h>
+#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/update/manager/update-manager.h>
+
+// EXTERNAL INCLUDES
+#include <cstring>
+
+namespace
+{
+const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
+} // namespace
 
 namespace Dali
 {
 namespace Internal
 {
-
-TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height )
+TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height)
 {
-  constexpr auto max_value = std::numeric_limits< uint16_t >::max();
-  DALI_ASSERT_ALWAYS( ( width < max_value )&&( height < max_value )&& "Size out of range" );
-  TexturePtr texture( new Texture( type, format, ImageDimensions( width, height) ) );
+  constexpr auto max_value = std::numeric_limits<uint16_t>::max();
+  DALI_ASSERT_ALWAYS((width < max_value) && (height < max_value) && "Size out of range");
+  TexturePtr texture(new Texture(type, format, ImageDimensions(width, height)));
   texture->Initialize();
   return texture;
 }
 
-TexturePtr Texture::New( NativeImageInterface& nativeImageInterface )
+TexturePtr Texture::New(NativeImageInterface& nativeImageInterface)
 {
-  TexturePtr texture( new Texture( &nativeImageInterface ) );
+  TexturePtr texture(new Texture(&nativeImageInterface));
   texture->Initialize();
 
   // Request event processing and update forcely.
-  texture->mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle( true );
+  texture->mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
   texture->mEventThreadServices.ForceNextUpdate();
   return texture;
 }
@@ -53,112 +60,115 @@ Render::Texture* Texture::GetRenderObject() const
   return mRenderObject;
 }
 
-Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size )
-: mEventThreadServices( EventThreadServices::Get() ),
-  mRenderObject( nullptr ),
+Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
+: mEventThreadServices(EventThreadServices::Get()),
+  mRenderObject(nullptr),
   mNativeImage(),
-  mSize( size ),
-  mType( type ),
-  mFormat( format )
+  mSize(size),
+  mType(type),
+  mFormat(format)
 {
 }
 
-Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
-: mEventThreadServices( EventThreadServices::Get() ),
-  mRenderObject( nullptr ),
-  mNativeImage( nativeImageInterface ),
-  mSize( nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight() ),
-  mType( TextureType::TEXTURE_2D ),
-  mFormat( Pixel::RGB888 )
+Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
+: mEventThreadServices(EventThreadServices::Get()),
+  mRenderObject(nullptr),
+  mNativeImage(nativeImageInterface),
+  mSize(nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight()),
+  mType(TextureType::TEXTURE_2D),
+  mFormat(Pixel::RGB888)
 {
 }
 
 void Texture::Initialize()
 {
-  if( EventThreadServices::IsCoreRunning() )
+  if(EventThreadServices::IsCoreRunning())
   {
-    if( mNativeImage )
+    if(mNativeImage)
     {
-      mRenderObject = new Render::Texture( mNativeImage );
+      mRenderObject = new Render::Texture(mNativeImage);
     }
     else
     {
-      mRenderObject = new Render::Texture( mType, mFormat, mSize );
+      mRenderObject = new Render::Texture(mType, mFormat, mSize);
     }
 
-    OwnerPointer< Render::Texture > transferOwnership( mRenderObject );
-    AddTexture( mEventThreadServices.GetUpdateManager(), transferOwnership );
+    OwnerPointer<Render::Texture> transferOwnership(mRenderObject);
+    AddTexture(mEventThreadServices.GetUpdateManager(), transferOwnership);
   }
 }
 
 Texture::~Texture()
 {
-  if( EventThreadServices::IsCoreRunning() && mRenderObject )
+  if(EventThreadServices::IsCoreRunning() && mRenderObject)
   {
-    RemoveTexture( mEventThreadServices.GetUpdateManager(), *mRenderObject );
+    RemoveTexture(mEventThreadServices.GetUpdateManager(), *mRenderObject);
   }
 }
 
-bool Texture::Upload( PixelDataPtr pixelData )
+bool Texture::Upload(PixelDataPtr pixelData)
 {
-  return Upload( pixelData, 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight() );
+  return Upload(pixelData, 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
 }
 
-bool Texture::Upload( PixelDataPtr pixelData,
-                      unsigned int layer, unsigned int mipmap,
-                      unsigned int xOffset, unsigned int yOffset,
-                      unsigned int width, unsigned int height )
+bool Texture::Upload(PixelDataPtr pixelData,
+                     unsigned int layer,
+                     unsigned int mipmap,
+                     unsigned int xOffset,
+                     unsigned int yOffset,
+                     unsigned int width,
+                     unsigned int height)
 {
-  constexpr auto max_value = std::numeric_limits< uint16_t >::max();
-  DALI_ASSERT_ALWAYS( layer < max_value &&
-                      mipmap < max_value &&
-                      xOffset < max_value &&
-                      yOffset < max_value &&
-                      width < max_value &&
-                      height < max_value &&
-                      "Parameter value out of range" );
+  constexpr auto max_value = std::numeric_limits<uint16_t>::max();
+  DALI_ASSERT_ALWAYS(layer < max_value &&
+                     mipmap < max_value &&
+                     xOffset < max_value &&
+                     yOffset < max_value &&
+                     width < max_value &&
+                     height < max_value &&
+                     "Parameter value out of range");
 
   bool result(false);
-  if( EventThreadServices::IsCoreRunning() && mRenderObject )
+  if(EventThreadServices::IsCoreRunning() && mRenderObject)
   {
-    if( mNativeImage )
+    if(mNativeImage)
     {
-      DALI_LOG_ERROR( "OpenGL ES does not support uploading data to native texture\n");
+      DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
     }
     else
     {
-      unsigned int pixelDataSize = pixelData->GetWidth()*pixelData->GetHeight();
-      if( pixelData->GetBuffer() == nullptr || pixelDataSize == 0 )
+      unsigned int pixelDataSize = pixelData->GetWidth() * pixelData->GetHeight();
+      if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
       {
-        DALI_LOG_ERROR( "PixelData is empty\n");
+        DALI_LOG_ERROR("PixelData is empty\n");
       }
       else
       {
         Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
-        if( ( pixelDataFormat == mFormat ) || ( (pixelDataFormat == Pixel::RGB888 ) && ( mFormat == Pixel::RGBA8888 ) ) )
+        if((pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
         {
-          if( pixelDataSize < width * height )
+          if(pixelDataSize < width * height)
           {
-            DALI_LOG_ERROR( "PixelData of an incorrect size when trying to update texture\n");
+            DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
           }
-          else if( ( xOffset + width  > ( mSize.GetWidth()  / (1u << mipmap) ) ) ||
-              ( yOffset + height > ( mSize.GetHeight() / (1u << mipmap) ) ) )
+          else if((xOffset + width > (mSize.GetWidth() / (1u << mipmap))) ||
+                  (yOffset + height > (mSize.GetHeight() / (1u << mipmap))))
           {
-            DALI_LOG_ERROR( "Texture update area out of bounds\n");
+            DALI_LOG_ERROR("Texture update area out of bounds\n");
           }
           else
           {
             //Parameters are correct. Send message to upload data to the texture
-            UploadParams params = { static_cast< uint16_t >( layer ),
-                                    static_cast< uint16_t >( mipmap ),
-                                    static_cast< uint16_t >( xOffset ),
-                                    static_cast< uint16_t >( yOffset ),
-                                    static_cast< uint16_t >( width ),
-                                    static_cast< uint16_t >( height ) };
-            UploadTextureMessage( mEventThreadServices.GetUpdateManager(), *mRenderObject, pixelData, params );
+            UploadParams params = {static_cast<uint16_t>(layer),
+                                   static_cast<uint16_t>(mipmap),
+                                   static_cast<uint16_t>(xOffset),
+                                   static_cast<uint16_t>(yOffset),
+                                   static_cast<uint16_t>(width),
+                                   static_cast<uint16_t>(height)};
+            UploadTextureMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject, pixelData, params);
 
             // Request event processing and update forcely
-            mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle( true );
+            mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
             mEventThreadServices.ForceNextUpdate();
 
             result = true;
@@ -166,7 +176,7 @@ bool Texture::Upload( PixelDataPtr pixelData,
         }
         else
         {
-          DALI_LOG_ERROR( "Bad format\n");
+          DALI_LOG_ERROR("Bad format\n");
         }
       }
     }
@@ -177,9 +187,9 @@ bool Texture::Upload( PixelDataPtr pixelData,
 
 void Texture::GenerateMipmaps()
 {
-  if( EventThreadServices::IsCoreRunning() && mRenderObject )
+  if(EventThreadServices::IsCoreRunning() && mRenderObject)
   {
-    GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject );
+    GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject);
   }
 }
 
@@ -193,5 +203,46 @@ unsigned int Texture::GetHeight() const
   return mSize.GetHeight();
 }
 
+bool Texture::IsNative() const
+{
+  return mNativeImage != nullptr;
+}
+
+bool Texture::ApplyNativeFragmentShader(std::string& shader)
+{
+  std::string fragmentShader;
+  bool        modified = false;
+  if(mNativeImage != nullptr && !shader.empty())
+  {
+    const char* fragmentPrefix        = mNativeImage->GetCustomFragmentPrefix();
+    const char* customSamplerTypename = mNativeImage->GetCustomSamplerTypename();
+
+    if(fragmentPrefix != nullptr)
+    {
+      modified       = true;
+      fragmentShader = fragmentPrefix;
+      fragmentShader += "\n";
+    }
+    fragmentShader += shader;
+
+    if(customSamplerTypename != nullptr)
+    {
+      modified   = true;
+      size_t pos = fragmentShader.find(DEFAULT_SAMPLER_TYPENAME);
+      if(pos < fragmentShader.length())
+      {
+        fragmentShader.replace(pos, strlen(DEFAULT_SAMPLER_TYPENAME), customSamplerTypename);
+      }
+    }
+  }
+
+  if(modified)
+  {
+    shader = fragmentShader;
+  }
+
+  return modified;
+}
+
 } // namespace Internal
 } // namespace Dali
index d7f6b4a..57b098d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_NEW_TEXTURE_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  */
 
 // INTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h> // DALI_ASSERT_ALWAYS
-#include <dali/public-api/common/intrusive-ptr.h> // Dali::IntrusivePtr
-#include <dali/public-api/object/base-object.h>
-#include <dali/public-api/images/pixel.h>
-#include <dali/public-api/images/image-operations.h> // Dali::ImageDimensions
-#include <dali/public-api/rendering/texture.h> // Dali::Internal::Render::Texture
 #include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/event/images/pixel-data-impl.h>
+#include <dali/public-api/common/dali-common.h>      // DALI_ASSERT_ALWAYS
+#include <dali/public-api/common/intrusive-ptr.h>    // Dali::IntrusivePtr
+#include <dali/public-api/images/image-operations.h> // Dali::ImageDimensions
+#include <dali/public-api/images/pixel.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/rendering/texture.h> // Dali::Internal::Render::Texture
 
 namespace Dali
 {
@@ -43,18 +43,17 @@ using TexturePtr = IntrusivePtr<Texture>;
 class Texture : public BaseObject
 {
 public:
-
   /**
    * @brief Structure used to pass parameters to the Upload method
    */
   struct UploadParams
   {
-    uint16_t layer;    ///< Specifies the layer of a cube map or array texture
-    uint16_t mipmap;   ///< Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
-    uint16_t xOffset;  ///< Specifies a texel offset in the x direction within the texture array.
-    uint16_t yOffset;  ///< Specifies a texel offset in the y direction within the texture array.
-    uint16_t width;    ///< Specifies the width of the texture subimage
-    uint16_t height;   ///< Specifies the height of the texture subimage.
+    uint16_t layer;   ///< Specifies the layer of a cube map or array texture
+    uint16_t mipmap;  ///< Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
+    uint16_t xOffset; ///< Specifies a texel offset in the x direction within the texture array.
+    uint16_t yOffset; ///< Specifies a texel offset in the y direction within the texture array.
+    uint16_t width;   ///< Specifies the width of the texture subimage
+    uint16_t height;  ///< Specifies the height of the texture subimage.
   };
 
   /**
@@ -73,7 +72,7 @@ public:
    * @param[in] nativeImageInterface The native image
    * @return A smart-pointer to the newly allocated Texture.
    */
-  static TexturePtr New( NativeImageInterface& nativeImageInterface );
+  static TexturePtr New(NativeImageInterface& nativeImageInterface);
 
   /**
    * @brief Get the texture render object
@@ -85,15 +84,18 @@ public:
   /**
    * @copydoc Dali::Texture::Upload()
    */
-  bool Upload( PixelDataPtr pixelData );
+  bool Upload(PixelDataPtr pixelData);
 
   /**
    * @copydoc Dali::Texture::Upload()
    */
-  bool Upload( PixelDataPtr pixelData,
-               unsigned int layer, unsigned int mipmap,
-               unsigned int xOffset, unsigned int yOffset,
-               unsigned int width, unsigned int height );
+  bool Upload(PixelDataPtr pixelData,
+              unsigned int layer,
+              unsigned int mipmap,
+              unsigned int xOffset,
+              unsigned int yOffset,
+              unsigned int width,
+              unsigned int height);
 
   /**
    * @copydoc Dali::Texture::GenerateMipmaps()
@@ -110,21 +112,35 @@ public:
    */
   unsigned int GetHeight() const;
 
-private: // implementation
+  /**
+   * @brief Determine if the texture is a native image
+   *
+   * @return true if the texture has been initialized with a native image
+   */
+  bool IsNative() const;
+
+  /**
+   * @brief Apply any native texture code to the given fragment shader
+   *
+   * @param[in,out] shader The fragment shader
+   * @return true if the shader has been modified.
+   */
+  bool ApplyNativeFragmentShader(std::string& shader);
 
+private: // implementation
   /**
    * Constructor
    * @param[in] type The type of the texture
    * @param[in] format The format of the pixel data
    * @param[in] size The size of the texture
    */
-  Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size );
+  Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size);
 
   /**
    * Constructor from native image
    * @param[in] nativeImageInterface The native image
    */
-  Texture( NativeImageInterfacePtr nativeImageInterface );
+  Texture(NativeImageInterfacePtr nativeImageInterface);
 
   /**
    * Second stage initialization of the Texture
@@ -132,26 +148,23 @@ private: // implementation
   void Initialize();
 
 protected:
-
   /**
    * A reference counted object may only be deleted by calling Unreference()
    */
   ~Texture() override;
 
 private: // unimplemented methods
-  Texture( const Texture& );
-  Texture& operator=( const Texture& );
+  Texture(const Texture&);
+  Texture& operator=(const Texture&);
 
-private: // data
-
-  Internal::EventThreadServices& mEventThreadServices;    ///<Used to send messages to the render thread via update thread
-  Internal::Render::Texture* mRenderObject;            ///<The Render::Texture associated to this texture
+private:                                               // data
+  Internal::EventThreadServices& mEventThreadServices; ///<Used to send messages to the render thread via update thread
+  Internal::Render::Texture*     mRenderObject;        ///<The Render::Texture associated to this texture
 
   NativeImageInterfacePtr mNativeImage; ///< Pointer to native image
-  ImageDimensions mSize;                ///< Size of the texture
+  ImageDimensions         mSize;        ///< Size of the texture
   Dali::TextureType::Type mType;        ///< Texture type (cached)
-  Pixel::Format mFormat;                ///< Pixel format
-
+  Pixel::Format           mFormat;      ///< Pixel format
 };
 
 } // namespace Internal
index 378ee31..2e5a0ee 100644 (file)
@@ -60,9 +60,10 @@ public:
    * Size of the VertexAttributeArray enables
    * GLES specification states that there's minimum of 8
    */
-  static const unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
+  static constexpr unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
 
-  static const unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
+  static constexpr unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
+  static constexpr unsigned int MAX_TEXTURE_TARGET = 3; // We support only GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP and GL_TEXTURE_EXTERNAL_OES now
 
   /**
    * Creates the Dali Context object for surface rendering only.
@@ -133,6 +134,9 @@ public:
     DALI_LOG_INFO(Debug::Filter::gRender, Debug::General, "GL %s = %s\n", stringName, reinterpret_cast< const char * >( GetString( stringId ) ) );
   }
 
+  /**
+   * Reset the cached buffer ids.
+   */
   void ResetBufferCache()
   {
     // reset the cached buffer id's
@@ -143,13 +147,47 @@ public:
     mBoundTransformFeedbackBufferId = 0;
   }
 
+  /**
+   * Reset the cached texture ids.
+   */
   void ResetTextureCache()
   {
     // reset the cached texture id's in case the driver re-uses them
     // when creating new textures
-    for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
+    for(unsigned int i = 0; i < MAX_TEXTURE_UNITS; ++i)
     {
-       mBoundTextureId[ i ] = 0;
+      for(unsigned int j = 0; j < MAX_TEXTURE_TARGET; ++j)
+      {
+        mBoundTextureId[i][j] = 0;
+      }
+    }
+  }
+
+  /**
+   * Get an index of the cached texture list from the texture target.
+   * @param target The texture target
+   * @return The index of the cached texture list
+   */
+  static constexpr int16_t GetTextureIndexFromGlFormat(int target)
+  {
+    switch(target)
+    {
+      case GL_TEXTURE_2D:
+      {
+        return 0;
+      }
+      case GL_TEXTURE_CUBE_MAP:
+      {
+        return 1;
+      }
+      case GL_TEXTURE_EXTERNAL_OES:
+      {
+        return 2;
+      }
+      default:
+      {
+        return -1;
+      }
     }
   }
 
@@ -311,11 +349,8 @@ public:
    */
   void BindTextureForUnit( TextureUnit textureunit, int target, GLuint texture )
   {
-    if( mBoundTextureId[ textureunit ] != texture )
-    {
-      ActiveTexture( textureunit );
-      BindTexture( target, texture );
-    }
+    ActiveTexture(textureunit);
+    BindTexture(target, texture);
   }
 
   /**
@@ -323,12 +358,13 @@ public:
    */
   void BindTexture( int target, GLuint texture )
   {
-    if (mBoundTextureId[ mActiveTextureUnit ] != texture)
+    int16_t index = GetTextureIndexFromGlFormat(target);
+    if(index >= 0 && mBoundTextureId[ mActiveTextureUnit ][index] != texture)
     {
-      mBoundTextureId[ mActiveTextureUnit ] = texture;
+      mBoundTextureId[ mActiveTextureUnit ][index] = texture;
 
       LOG_GL("BindTexture target(%d) %d\n", target, texture);
-      CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(target, texture) );
+      CHECK_GL(mGlAbstraction, mGlAbstraction.BindTexture(target, texture));
     }
   }
 
@@ -1789,7 +1825,7 @@ private: // Data
 
   // glBindTexture() state
   TextureUnit mActiveTextureUnit;
-  GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ];  ///< The ID passed to glBindTexture()
+  GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ][MAX_TEXTURE_TARGET];  ///< The ID passed to glBindTexture()
 
   // glBlendColor() state
   Vector4 mBlendColor; ///< Blend color
index 1cc6ab6..120aa24 100644 (file)
@@ -222,6 +222,9 @@ public:
   {
     mConnectedToSceneGraph = true;
     mPropertyOwner->AddObserver(*this);
+
+    // Enable if the target object is valid and connected to the scene graph.
+    mEnabled = mPropertyOwner->IsAnimationPossible();
   }
 
   /**
index 0d915a1..8d560ca 100644 (file)
@@ -89,6 +89,8 @@ void PropertyOwner::Destroy()
 
 void PropertyOwner::ConnectToSceneGraph()
 {
+  mIsConnectedToSceneGraph = true;
+
   // Notification for observers
   const ConstObserverIter endIter = mObservers.End();
   for( ConstObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
@@ -99,6 +101,8 @@ void PropertyOwner::ConnectToSceneGraph()
 
 void PropertyOwner::DisconnectFromSceneGraph( BufferIndex updateBufferIndex )
 {
+  mIsConnectedToSceneGraph = false;
+
   // Notification for observers
   const ConstObserverIter endIter = mObservers.End();
   for( ConstObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
@@ -143,7 +147,8 @@ void PropertyOwner::RemoveConstraint( ConstraintBase* constraint )
 }
 
 PropertyOwner::PropertyOwner()
-: mUpdated( false )
+: mUpdated(false),
+  mIsConnectedToSceneGraph(false)
 {
 }
 
index c4dd922..5fbfc5a 100644 (file)
@@ -223,6 +223,14 @@ public:
    */
   void RemoveUniformMapObserver( UniformMap::Observer& observer );
 
+  /**
+   * Query whether playing an animation is possible or not.
+   * @return true if playing an animation is possible.
+   */
+  virtual bool IsAnimationPossible() const
+  {
+    return true;
+  }
 
 protected:
 
@@ -244,6 +252,7 @@ protected:
   OwnedPropertyContainer mCustomProperties; ///< Properties provided with InstallCustomProperty()
   UniformMap mUniformMaps; ///< Container of owned uniform maps
   bool mUpdated;
+  bool                   mIsConnectedToSceneGraph;
 
 private:
   using ObserverContainer = Dali::Vector<PropertyOwner::Observer*>;
index 96e0fe9..b3afaa2 100644 (file)
@@ -45,10 +45,10 @@ public:
   /**
    * Constructor
    */
-  UniformPropertyMapping( const std::string& theUniformName, const PropertyInputImpl* thePropertyPtr )
-  : propertyPtr( thePropertyPtr ),
-    uniformName( theUniformName ),
-    uniformNameHash( Dali::CalculateHash( theUniformName ) )
+  UniformPropertyMapping(std::string theUniformName, const PropertyInputImpl* thePropertyPtr)
+  : propertyPtr(thePropertyPtr),
+    uniformName(std::move(theUniformName)),
+    uniformNameHash(Dali::CalculateHash(theUniformName))
   {
   }
 
index 189d18c..ae6dd7f 100755 (executable)
@@ -188,6 +188,11 @@ void Node::RemoveUniformMapping( const std::string& uniformName )
   mRegenerateUniformMap = 2;
 }
 
+bool Node::IsAnimationPossible() const
+{
+  return mIsConnectedToSceneGraph;
+}
+
 void Node::PrepareRender( BufferIndex bufferIndex )
 {
   if( mRegenerateUniformMap != 0 )
index c89c245..7e5a05d 100644 (file)
@@ -806,6 +806,11 @@ public:
   void RemoveUniformMapping( const std::string& uniformName ) override;
 
   /**
+   * @copydoc Dali::Internal::SceneGraph::PropertyOwner::IsAnimationPossible
+   */
+  bool IsAnimationPossible() const override;
+
+  /**
    * Prepare the node for rendering.
    * This is called by the UpdateManager when an object is due to be rendered in the current frame.
    * @param[in] updateBufferIndex The current update buffer index.
index fa8145c..1092da7 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 1;
 const uint32_t    CORE_MINOR_VERSION = 9;
-const uint32_t    CORE_MICRO_VERSION = 29;
+const uint32_t    CORE_MICRO_VERSION = 30;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 72e9599..a71da44 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    1.9.29
+Version:    1.9.30
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT