Merge "refactor AlphaFunction class to reduce size" into devel/master
authorDavid Steele <david.steele@samsung.com>
Mon, 30 Nov 2020 12:50:50 +0000 (12:50 +0000)
committerGerrit Code Review <gerrit@review>
Mon, 30 Nov 2020 12:50:50 +0000 (12:50 +0000)
65 files changed:
.github/workflows/codeql-analysis.yml [new file with mode: 0644]
.gitignore
automated-tests/patch-coverage.pl
automated-tests/src/dali/CMakeLists.txt
automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.h
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Mutex.cpp
automated-tests/src/dali/utc-Dali-Renderer.cpp
automated-tests/src/dali/utc-Dali-Scene.cpp
automated-tests/src/dali/utc-Dali-Semaphore.cpp [new file with mode: 0644]
build/tizen/CMakeLists.txt
dali/devel-api/actors/actor-devel.h
dali/devel-api/common/capabilities.cpp [new file with mode: 0644]
dali/devel-api/common/capabilities.h [new file with mode: 0644]
dali/devel-api/file.list
dali/devel-api/rendering/renderer-devel.cpp
dali/devel-api/rendering/renderer-devel.h
dali/devel-api/threading/mutex.cpp
dali/devel-api/threading/mutex.h
dali/devel-api/threading/semaphore.h [new file with mode: 0644]
dali/integration-api/gl-abstraction.h
dali/integration-api/gl-defines.h
dali/integration-api/scene.cpp
dali/integration-api/scene.h
dali/internal/common/blending-options.cpp
dali/internal/common/blending-options.h
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/actor-property-handler.cpp
dali/internal/event/actors/camera-actor-impl.cpp
dali/internal/event/actors/camera-actor-impl.h
dali/internal/event/common/property-input-impl.h
dali/internal/event/common/scene-impl.cpp
dali/internal/event/common/scene-impl.h
dali/internal/event/common/thread-local-storage.cpp
dali/internal/event/common/thread-local-storage.h
dali/internal/event/events/pan-gesture/pan-gesture-detector-impl.h
dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp
dali/internal/event/events/ray-test.h
dali/internal/event/rendering/renderer-impl.cpp
dali/internal/event/rendering/renderer-impl.h
dali/internal/event/rendering/shader-impl.cpp
dali/internal/event/rendering/shader-impl.h
dali/internal/event/rendering/texture-impl.cpp
dali/internal/event/rendering/vertex-buffer-impl.cpp
dali/internal/render/common/render-instruction.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/gl-resources/context.cpp
dali/internal/render/gl-resources/context.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/update/manager/frame-callback-processor.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/manager/update-proxy-impl.h
dali/internal/update/render-tasks/scene-graph-camera.cpp
dali/internal/update/render-tasks/scene-graph-camera.h
dali/public-api/dali-core-version.cpp
dali/public-api/rendering/shader.cpp
dali/public-api/rendering/shader.h
packaging/dali.spec

diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644 (file)
index 0000000..799e0bc
--- /dev/null
@@ -0,0 +1,69 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+  push:
+    branches: [ master, devel/vulkan ]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [ master ]
+  schedule:
+    - cron: '24 1 * * 1'
+
+jobs:
+  analyze:
+    name: Analyze
+    runs-on: ubuntu-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        language: [ 'cpp' ]
+        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
+        # Learn more:
+        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v2
+
+    # Initializes the CodeQL tools for scanning.
+    - name: Initialize CodeQL
+      uses: github/codeql-action/init@v1
+      with:
+        languages: ${{ matrix.language }}
+        # If you wish to specify custom queries, you can do so here or in a config file.
+        # By default, queries listed here will override any specified in a config file.
+        # Prefix the list here with "+" to use these queries and those in the config file.
+        # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
+    # If this step fails, then you should remove it and run the build manually (see below)
+    #- name: Autobuild
+    #  uses: github/codeql-action/autobuild@v1
+
+    # ℹ️ Command-line programs to run using the OS shell.
+    # 📚 https://git.io/JvXDl
+
+    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+    #    and modify them (or add more) to build your code if your project
+    #    uses a compiled language
+
+    - run: |
+       cd build/tizen
+       export DESKTOP_PREFIX=/tmp
+       cmake -DCMAKE_INSTALL_PREFIX=$DESKTOP_PREFIX .
+       make -j8
+
+    - name: Perform CodeQL Analysis
+      uses: github/codeql-action/analyze@v1
index 2912c11..56258a1 100644 (file)
@@ -46,3 +46,5 @@ libdali2-core.so*
 /packaging/home*
 compile_commands.json
 file-list.cmake
+compile_commands.json
+.clangd
index 3a97dac..b3cf098 100755 (executable)
@@ -1105,7 +1105,7 @@ sub calc_patch_coverage_percentage
     my $percent = 0;
     if($total_exec > 0) { $percent = 100 * $total_covered_lines / $total_exec; }
 
-    return [ $total_exec, $percent ];
+    return [ $total_exec, $percent, $total_covered_lines ];
 }
 
 #
@@ -1417,6 +1417,7 @@ elsif( ! $opt_quiet )
     print RESET;
 }
 
+printf("Line Coverage: %d/%d\n", $percentref->[2], $percentref->[0]);
 printf("Percentage of change covered: %5.2f%\n", $percent);
 
 exit($percent<90);
index bab6fb6..67aceac 100644 (file)
@@ -47,6 +47,7 @@ SET(TC_SOURCES
         utc-Dali-Matrix3.cpp
         utc-Dali-MeshMaterial.cpp
         utc-Dali-Mutex.cpp
+        utc-Dali-Semaphore.cpp
         utc-Dali-ObjectRegistry.cpp
         utc-Dali-PanGesture.cpp
         utc-Dali-PanGestureDetector.cpp
index 2c1c703..b8de978 100644 (file)
@@ -378,6 +378,34 @@ inline void DALI_TEST_PRINT_ASSERT(DaliException& e)
     DALI_TEST_ASSERT(e, assertstring, TEST_LOCATION);                                                       \
   }
 
+/**
+ * Test that given piece of code triggers an exception
+ * Fails the test if the exception didn't occur.
+ * Turns off logging during the execution of the code to avoid excessive false positive log output from the assertions
+ * @param expressions code to execute
+ * @param except the exception expected in the assert
+ */
+#define DALI_TEST_THROWS(expressions, except)                                                               \
+  try                                                                                                       \
+  {                                                                                                         \
+    TestApplication::EnableLogging(false);                                                                  \
+    expressions;                                                                                            \
+    TestApplication::EnableLogging(true);                                                                   \
+    fprintf(stderr, "Test failed in %s, expected exception: '%s' didn't occur\n", __FILELINE__, #except);   \
+    tet_result(TET_FAIL);                                                                                   \
+    throw("TET_FAIL");                                                                                      \
+  }                                                                                                         \
+  catch(except &)                                                                                           \
+  {                                                                                                         \
+    tet_result(TET_PASS);                                                                                   \
+  }                                                                                                         \
+  catch(...)                                                                                                \
+  {                                                                                                         \
+    fprintf(stderr, "Test failed in %s, unexpected exception\n", __FILELINE__);                             \
+    tet_result(TET_FAIL);                                                                                   \
+    throw;                                                                                                  \
+  }
+
 // Functor to test whether an Applied signal is emitted
 struct ConstraintAppliedCheck
 {
index a694eeb..9e8c7a8 100644 (file)
@@ -112,6 +112,31 @@ bool TestGlAbstraction::IsSurfacelessContextSupported() const
   return true;
 }
 
+bool TestGlAbstraction::IsAdvancedBlendEquationSupported()
+{
+  return true;
+}
+
+bool TestGlAbstraction::IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
+{
+  return true;
+}
+
+std::string TestGlAbstraction::GetShaderVersionPrefix()
+{
+  return std::string("");
+}
+
+std::string TestGlAbstraction::GetVertexShaderPrefix()
+{
+  return std::string("");
+}
+
+std::string TestGlAbstraction::GetFragmentShaderPrefix()
+{
+  return std::string("");
+}
+
 bool TestGlAbstraction::TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const
 {
   return ((imageGlFormat == GL_RGB) && (textureGlFormat == GL_RGBA));
index 99dca10..861f4ae 100644 (file)
@@ -61,6 +61,16 @@ public:
 
   bool IsSurfacelessContextSupported() const override;
 
+  bool IsAdvancedBlendEquationSupported() override;
+
+  bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
+
+  std::string GetShaderVersionPrefix();
+
+  std::string GetVertexShaderPrefix();
+
+  std::string GetFragmentShaderPrefix();
+
   bool TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const override;
 
   /* OpenGL ES 2.0 */
@@ -1889,6 +1899,10 @@ public:
   {
   }
 
+  inline void BlendBarrier(void)
+  {
+  }
+
 private:
   inline void AddUniformCallToTraceStack(GLint location, std::string& value)
   {
index 1093bf7..5ac38fa 100755 (executable)
@@ -23,6 +23,7 @@
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/events/hover-event-integ.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/devel-api/common/capabilities.h>
 #include <dali/public-api/dali-core.h>
 #include <mesh-builder.h>
 
@@ -8612,3 +8613,40 @@ int UtcDaliActorGetParentNegative(void)
   }
   END_TEST;
 }
+
+int UtcDaliActorPropertyBlendEquation(void)
+{
+  TestApplication application;
+
+  tet_infoline("Test SetProperty AdvancedBlendEquation");
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader shader = CreateShader();
+  Renderer renderer1 = Renderer::New( geometry, shader );
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::OPACITY, 0.1f);
+
+  actor.AddRenderer(renderer1);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(400, 400));
+  application.GetScene().Add(actor);
+
+  if( !Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SCREEN ) )
+  {
+    actor.SetProperty( Dali::DevelActor::Property::BLEND_EQUATION, Dali::DevelBlendEquation::SCREEN );
+    int equation = actor.GetProperty<int>( Dali::DevelActor::Property::BLEND_EQUATION );
+    DALI_TEST_EQUALS( ( Dali::DevelBlendEquation::SCREEN == equation ), false, TEST_LOCATION );
+  }
+
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SCREEN ) )
+  {
+    actor.SetProperty( Dali::DevelActor::Property::BLEND_EQUATION, Dali::DevelBlendEquation::SCREEN );
+    int equation = actor.GetProperty<int>( Dali::DevelActor::Property::BLEND_EQUATION );
+    DALI_TEST_EQUALS( ( Dali::DevelBlendEquation::SCREEN == equation ), true, TEST_LOCATION );
+  }
+
+  Renderer renderer2 = Renderer::New( geometry, shader );
+  actor.AddRenderer(renderer2);
+
+  END_TEST;
+}
index edbd1cc..a15d26f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <iostream>
 #include <type_traits>
+#include <utility>
 
 using Dali::Mutex;
 using Dali::Thread;
@@ -49,6 +50,20 @@ int UtcDaliMutexSingleThread(void)
   }
   DALI_TEST_EQUALS(false, mutex3.IsLocked(), TEST_LOCATION);
 
+  {
+    Mutex mutex4;
+    Mutex mutex5(std::move(mutex4)); // move constructor
+    Mutex::ScopedLock lock(mutex5);
+    DALI_TEST_EQUALS(true, mutex5.IsLocked(), TEST_LOCATION);
+  }
+
+  {
+    Mutex mutex4, mutex5;
+    mutex5 = std::move(mutex4); // move assignment
+    Mutex::ScopedLock lock(mutex5);
+    DALI_TEST_EQUALS(true, mutex5.IsLocked(), TEST_LOCATION);
+  }
+
   END_TEST;
 }
 
index d77fabc..b50d710 100644 (file)
@@ -21,7 +21,7 @@
 #include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/integration-api/render-task-list-integ.h>
 #include <dali/public-api/dali-core.h>
-
+#include <dali/devel-api/common/capabilities.h>
 #include <cstdio>
 #include <string>
 
@@ -256,12 +256,13 @@ int UtcDaliRendererDefaultProperties(void)
   DALI_PROPERTY( "stencilOperationOnZPass",         INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS )
   DALI_PROPERTY( "opacity",                         FLOAT,     true, true,   true,  Dali::DevelRenderer::Property::OPACITY )
   DALI_PROPERTY( "renderingBehavior",               INTEGER,   true, false,  false, Dali::DevelRenderer::Property::RENDERING_BEHAVIOR )
+  DALI_PROPERTY( "blendEquation",                   INTEGER,   true, false,  false, Dali::DevelRenderer::Property::BLEND_EQUATION )
 */
 
   Geometry geometry = CreateQuadGeometry();
   Shader   shader   = CreateShader();
   Renderer renderer = Renderer::New(geometry, shader);
-  DALI_TEST_EQUALS(renderer.GetPropertyCount(), 26, TEST_LOCATION);
+  DALI_TEST_EQUALS(renderer.GetPropertyCount(), 27, TEST_LOCATION);
 
   TEST_RENDERER_PROPERTY(renderer, "depthIndex", Property::INTEGER, true, false, false, Renderer::Property::DEPTH_INDEX, TEST_LOCATION);
   TEST_RENDERER_PROPERTY(renderer, "faceCullingMode", Property::INTEGER, true, false, false, Renderer::Property::FACE_CULLING_MODE, TEST_LOCATION);
@@ -289,6 +290,7 @@ int UtcDaliRendererDefaultProperties(void)
   TEST_RENDERER_PROPERTY(renderer, "stencilOperationOnZPass", Property::INTEGER, true, false, false, Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, TEST_LOCATION);
   TEST_RENDERER_PROPERTY(renderer, "opacity", Property::FLOAT, true, true, true, DevelRenderer::Property::OPACITY, TEST_LOCATION);
   TEST_RENDERER_PROPERTY(renderer, "renderingBehavior", Property::INTEGER, true, false, false, DevelRenderer::Property::RENDERING_BEHAVIOR, TEST_LOCATION);
+  TEST_RENDERER_PROPERTY(renderer, "blendEquation", Property::INTEGER, true, false, false, DevelRenderer::Property::BLEND_EQUATION, TEST_LOCATION);
 
   END_TEST;
 }
@@ -654,6 +656,127 @@ int UtcDaliRendererBlendOptions04(void)
   END_TEST;
 }
 
+int UtcDaliRendererBlendOptions05(void)
+{
+  TestApplication application;
+
+  tet_infoline("Test SetAdvancedBlendEquation ");
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader shader = CreateShader();
+  Renderer renderer = Renderer::New( geometry, shader );
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::OPACITY, 0.1f);
+
+  actor.AddRenderer(renderer);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(400, 400));
+  application.GetScene().Add(actor);
+
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::MAX ) )
+  {
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::MAX );
+    int equationRgb = renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::MAX, equationRgb, TEST_LOCATION );
+  }
+
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SCREEN ) )
+  {
+    renderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::SCREEN );
+    int equation = renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION );
+
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::SCREEN, equation, TEST_LOCATION );
+    DALI_TEST_EQUALS( DevelRenderer::IsAdvancedBlendEquationApplied( renderer ), true, TEST_LOCATION );
+
+    application.SendNotification();
+    application.Render();
+  }
+
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SCREEN ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::MULTIPLY ) )
+  {
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::ADD );
+    renderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION_RGB, DevelBlendEquation::SCREEN );
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION_ALPHA, DevelBlendEquation::MULTIPLY );
+    int equationRgb = renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION_RGB );
+    int equationAlpha = renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION_ALPHA );
+
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::ADD, equationRgb, TEST_LOCATION );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::ADD, equationAlpha, TEST_LOCATION );
+    DALI_TEST_EQUALS( DevelRenderer::IsAdvancedBlendEquationApplied( renderer ), false, TEST_LOCATION );
+
+    application.SendNotification();
+    application.Render();
+  }
+
+  tet_infoline("Error Checking\n");
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::MULTIPLY ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SCREEN ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::OVERLAY ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::DARKEN ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::LIGHTEN ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::COLOR_DODGE ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::COLOR_BURN ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::HARD_LIGHT ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SOFT_LIGHT ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::DIFFERENCE ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::EXCLUSION ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::HUE ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SATURATION ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::COLOR ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::LUMINOSITY ) )
+  {
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::MULTIPLY );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::MULTIPLY, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::SCREEN );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::SCREEN, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::OVERLAY );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::OVERLAY, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::DARKEN );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::DARKEN, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::LIGHTEN );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::LIGHTEN, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::COLOR_DODGE );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::COLOR_DODGE, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::COLOR_BURN );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::COLOR_BURN, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::HARD_LIGHT );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::HARD_LIGHT, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::SOFT_LIGHT );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::SOFT_LIGHT, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::DIFFERENCE );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::DIFFERENCE, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::EXCLUSION );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::EXCLUSION, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::HUE );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::HUE, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::SATURATION );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::SATURATION, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::COLOR );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::COLOR, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+
+    renderer.SetProperty( DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::LUMINOSITY );
+    DALI_TEST_EQUALS( (int)DevelBlendEquation::LUMINOSITY, renderer.GetProperty<int>( DevelRenderer::Property::BLEND_EQUATION ), TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
 int UtcDaliRendererSetBlendMode01(void)
 {
   TestApplication application;
@@ -2341,6 +2464,21 @@ int UtcDaliRendererEnumProperties(void)
   CheckEnumerationProperty<StencilOperation::Type>(application, renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT");
   CheckEnumerationProperty<StencilOperation::Type>(application, renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT");
 
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::MAX ) &&
+      Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::MIN ) )
+  {
+    application.SendNotification();
+    application.Render();
+    CheckEnumerationProperty< DevelBlendEquation::Type >( application, renderer, DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::REVERSE_SUBTRACT, DevelBlendEquation::MAX, DevelBlendEquation::MIN, "MIN" );
+  }
+
+  if( Dali::Capabilities::IsBlendEquationSupported( DevelBlendEquation::SCREEN ) )
+  {
+    application.SendNotification();
+    application.Render();
+    CheckEnumerationProperty< DevelBlendEquation::Type >( application, renderer, DevelRenderer::Property::BLEND_EQUATION, DevelBlendEquation::MIN, DevelBlendEquation::MULTIPLY, DevelBlendEquation::SCREEN, "SCREEN" );
+  }
+
   END_TEST;
 }
 
index 2fb7d3c..688f7c3 100644 (file)
@@ -1050,6 +1050,232 @@ int UtcDaliSceneSurfaceResizedAdditionalScene(void)
   END_TEST;
 }
 
+#define CLIPPING_RECT_X          (16)
+#define CLIPPING_RECT_Y          (768)
+#define CLIPPING_RECT_WIDTH      (32)
+#define CLIPPING_RECT_HEIGHT     (32)
+
+int UtcDaliSceneSurfaceRotatedWithAngle0(void)
+{
+  tet_infoline("Ensure rotation of the surface is handled properly with Angle 0");
+
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
+                                        TestApplication::DEFAULT_SURFACE_HEIGHT, 0);
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(CLIPPING_RECT_X, CLIPPING_RECT_Y, CLIPPING_RECT_WIDTH, CLIPPING_RECT_HEIGHT); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliSceneSurfaceRotatedWithAngle90(void)
+{
+  tet_infoline("Ensure rotation of the surface is handled properly with Angle 90");
+
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
+                                        TestApplication::DEFAULT_SURFACE_HEIGHT, 90);
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(CLIPPING_RECT_X, CLIPPING_RECT_Y, CLIPPING_RECT_WIDTH, CLIPPING_RECT_HEIGHT); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // It is recalculation for glScissor.
+  // Because surface is rotated and glScissor is called with recalcurated value.
+  clippingRect.x = TestApplication::DEFAULT_SURFACE_HEIGHT - (CLIPPING_RECT_Y + CLIPPING_RECT_HEIGHT);
+  clippingRect.y = CLIPPING_RECT_X;
+  clippingRect.width = CLIPPING_RECT_HEIGHT;
+  clippingRect.height = CLIPPING_RECT_WIDTH;
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliSceneSurfaceRotatedWithAngle180(void)
+{
+  tet_infoline("Ensure rotation of the surface is handled properly with Angle 180");
+
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
+                                        TestApplication::DEFAULT_SURFACE_HEIGHT, 180);
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(CLIPPING_RECT_X, CLIPPING_RECT_Y, CLIPPING_RECT_WIDTH, CLIPPING_RECT_HEIGHT); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // It is recalculation for glScissor.
+  // Because surface is rotated and glScissor is called with recalcurated value.
+  clippingRect.x = TestApplication::DEFAULT_SURFACE_WIDTH - (CLIPPING_RECT_X + CLIPPING_RECT_WIDTH);
+  clippingRect.y = TestApplication::DEFAULT_SURFACE_HEIGHT - (CLIPPING_RECT_Y +CLIPPING_RECT_HEIGHT);
+  clippingRect.width = CLIPPING_RECT_WIDTH;
+  clippingRect.height = CLIPPING_RECT_HEIGHT;
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliSceneSurfaceRotatedWithAngle270(void)
+{
+  tet_infoline("Ensure rotation of the surface is handled properly with Angle 270");
+
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
+                                        TestApplication::DEFAULT_SURFACE_HEIGHT, 270);
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(CLIPPING_RECT_X, CLIPPING_RECT_Y, CLIPPING_RECT_WIDTH, CLIPPING_RECT_HEIGHT); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // It is recalculation for glScissor.
+  // Because surface is rotated and glScissor is called with recalcurated value.
+  clippingRect.x = CLIPPING_RECT_Y;
+  clippingRect.y = TestApplication::DEFAULT_SURFACE_WIDTH - (CLIPPING_RECT_X + CLIPPING_RECT_WIDTH);
+  clippingRect.width = CLIPPING_RECT_HEIGHT;
+  clippingRect.height = CLIPPING_RECT_WIDTH;
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliSceneKeyEventGeneratedSignalP(void)
 {
   TestApplication          application;
diff --git a/automated-tests/src/dali/utc-Dali-Semaphore.cpp b/automated-tests/src/dali/utc-Dali-Semaphore.cpp
new file mode 100644 (file)
index 0000000..4cda5e6
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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-test-suite-utils.h>
+#include <dali/devel-api/threading/semaphore.h>
+#include <dali/public-api/dali-core.h>
+#include <algorithm>
+#include <chrono>
+#include <stdexcept>
+#include <thread>
+#include <future>
+
+int UtcDaliSemaphoreTryAcquire(void)
+{
+  using namespace std::chrono_literals;
+  constexpr auto waitTime{100ms};
+
+  tet_infoline("Testing Dali::Semaphore try acquire methods");
+  Dali::Semaphore<3> sem(0);
+
+  DALI_TEST_EQUALS(false, sem.TryAcquire(), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, sem.TryAcquireFor(waitTime), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, sem.TryAcquireUntil(std::chrono::system_clock::now() + waitTime), TEST_LOCATION);
+
+  sem.Release(3);
+
+  DALI_TEST_EQUALS(true, sem.TryAcquire(), TEST_LOCATION);
+  DALI_TEST_EQUALS(true, sem.TryAcquireFor(waitTime), TEST_LOCATION);
+  DALI_TEST_EQUALS(true, sem.TryAcquireUntil(std::chrono::system_clock::now() + waitTime), TEST_LOCATION);
+
+  DALI_TEST_EQUALS(false, sem.TryAcquire(), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, sem.TryAcquireFor(waitTime), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, sem.TryAcquireUntil(std::chrono::system_clock::now() + waitTime), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliSemaphoreInvalidArguments(void)
+{
+  tet_infoline("Testing Dali::Semaphore invalid arguments");
+
+  Dali::Semaphore<2> sem(0);
+
+  DALI_TEST_THROWS(sem.Release(3), std::invalid_argument);
+  DALI_TEST_THROWS(sem.Release(-1), std::invalid_argument);
+  sem.Release(1);
+  DALI_TEST_THROWS(sem.Release(2), std::invalid_argument);
+  sem.Release(1);
+  DALI_TEST_THROWS(sem.Release(1), std::invalid_argument);
+
+  DALI_TEST_THROWS(Dali::Semaphore<1>(2), std::invalid_argument);
+  DALI_TEST_THROWS(Dali::Semaphore<>(-1), std::invalid_argument);
+
+  END_TEST;
+}
+
+int UtcDaliSemaphoreAcquire(void)
+{
+  tet_infoline("Testing Dali::Semaphore multithread acquire");
+
+  using namespace std::chrono_literals;
+
+  constexpr std::ptrdiff_t numTasks{2};
+
+  auto f = [](Dali::Semaphore<numTasks> &sem, bool &flag)
+  {
+    sem.Acquire();
+    flag = true;
+  };
+
+  auto flag1{false}, flag2{false};
+  Dali::Semaphore<numTasks> sem(0);
+
+  auto fut1 = std::async(std::launch::async, f, std::ref(sem), std::ref(flag1));
+  auto fut2 = std::async(std::launch::async, f, std::ref(sem), std::ref(flag2));
+
+  DALI_TEST_EQUALS(std::future_status::timeout, fut1.wait_for(100ms), TEST_LOCATION);
+  DALI_TEST_EQUALS(std::future_status::timeout, fut2.wait_for(100ms), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, flag1, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, flag2, TEST_LOCATION);
+  sem.Release(numTasks);
+  fut1.wait();
+  DALI_TEST_EQUALS(true, flag1, TEST_LOCATION);
+  fut2.wait();
+  DALI_TEST_EQUALS(true, flag2, TEST_LOCATION);
+
+  END_TEST;
+}
index f174d4c..eb890c2 100644 (file)
@@ -140,6 +140,8 @@ IF( WIN32 ) # WIN32 includes x64 as well according to the cmake doc.
 
 ELSEIF( UNIX )
 
+  INCLUDE(CheckCXXCompilerFlag)
+
   # Set up compiler flags and warnings
   ADD_COMPILE_OPTIONS( -Wnon-virtual-dtor -Woverloaded-virtual -Wold-style-cast )
 
@@ -149,8 +151,21 @@ ELSEIF( UNIX )
     ADD_COMPILE_OPTIONS( -Werror )
   ENDIF()
 
-  ADD_COMPILE_OPTIONS( -Wall -Wextra -Wno-unused-parameter -Wfloat-equal -Wno-class-memaccess -Wno-cast-function-type )
+  ADD_COMPILE_OPTIONS( -Wall -Wextra -Wno-unused-parameter -Wfloat-equal )
+  CHECK_CXX_COMPILER_FLAG(-Wno-class-memaccess HAVE_NO_CLASS_MEMACCESS)
+  IF (HAVE_NO_CLASS_MEMACCESS)
+    ADD_COMPILE_OPTIONS( -Wno-class-memaccess )
+  ENDIF()
+
+  CHECK_CXX_COMPILER_FLAG(-Wno-cast-function-type HAVE_NO_CAST_FUNCTION_TYPE)
+  IF (HAVE_NO_CAST_FUNCTION_TYPE)
+    ADD_COMPILE_OPTIONS( -Wno-cast-function-type )
+  ENDIF()
 
+  CHECK_CXX_COMPILER_FLAG(-Wno-string-plus-int HAVE_NO_STRING_PLUS_INT)
+  IF (HAVE_NO_STRING_PLUS_INT)
+    ADD_COMPILE_OPTIONS( -Wno-string-plus-int )
+  ENDIF()
   IF( ENABLE_COVERAGE OR "$ENV{CXXFLAGS}" MATCHES --coverage )
     ADD_COMPILE_OPTIONS( --coverage )
     SET(ENABLE_COVERAGE ON)
@@ -245,7 +260,7 @@ IF( INSTALL_CMAKE_MODULES )
   INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake DESTINATION share/${name} )
 
   # Install the pdb file.
-  IF( ENABLE_DEBUG )
+  IF( ENABLE_DEBUG AND WIN32 )
     install( FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/${name}.pdb DESTINATION ${BIN_DIR} )
   ENDIF()
 ELSE()
index 6c9eba0..5821af0 100755 (executable)
@@ -131,7 +131,16 @@ enum Type
     *
     *  If you want to reset the touch area to an area different with the size of the actor, you can set this TOUCH_AREA property.
     */
-  TOUCH_AREA
+  TOUCH_AREA,
+
+  /**
+   * @brief Determines which blend equation will be used to render renderers of this actor.
+   * @pre To use Advanced Blend Equation(DevelBlendEquation::MULTIPLY ~ DevelBlendEquation::LUMINOSITY), the color to be rendered should be pre-multipled alpha.
+   * @details Name "blendEquation", type Property::INTEGER.
+   * @note Color of each renderer will be blended with rendering framebuffer.
+   * @note To check the blend equation is supported in the system, use Dali::Capabilities::IsBlendEquationSupported
+   */
+  BLEND_EQUATION
 };
 
 } // namespace Property
diff --git a/dali/devel-api/common/capabilities.cpp b/dali/devel-api/common/capabilities.cpp
new file mode 100644 (file)
index 0000000..fb04891
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+// CLASS HEADER\r
+#include <dali/devel-api/common/capabilities.h>\r
+#include <dali/internal/event/common/thread-local-storage.h>\r
+\r
+namespace Dali\r
+{\r
+\r
+namespace Capabilities\r
+{\r
+\r
+bool IsBlendEquationSupported( BlendEquation::Type blendEquation )\r
+{\r
+  return IsBlendEquationSupported( static_cast<DevelBlendEquation::Type>( blendEquation ) );\r
+}\r
+\r
+bool IsBlendEquationSupported( DevelBlendEquation::Type blendEquation )\r
+{\r
+  Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();\r
+  return tls.IsBlendEquationSupported(blendEquation);\r
+}\r
+\r
+} // namespace Capabilities\r
+\r
+} // namespace Dali
\ No newline at end of file
diff --git a/dali/devel-api/common/capabilities.h b/dali/devel-api/common/capabilities.h
new file mode 100644 (file)
index 0000000..f56c27d
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef DALI_CAPABILITIES_H\r
+#define DALI_CAPABILITIES_H\r
+\r
+/*\r
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+// INTERNAL INCLUDES\r
+#include <dali/devel-api/rendering/renderer-devel.h>\r
+\r
+namespace Dali\r
+{\r
+\r
+namespace Capabilities\r
+{\r
+\r
+/**\r
+ * @brief Returns whether the blend equation is supported in the system or not.\r
+ * @param[in] blendEquation blend equation to be checked.\r
+ * @return True if the blend equation supported.\r
+ */\r
+DALI_CORE_API bool IsBlendEquationSupported( BlendEquation::Type blendEquation );\r
+\r
+/**\r
+ * @brief Returns whether the blend equation is supported in the system or not.\r
+ * @param[in] blendEquation blend equation to be checked.\r
+ * @return True if the blend equation supported.\r
+ */\r
+DALI_CORE_API bool IsBlendEquationSupported( DevelBlendEquation::Type blendEquation );\r
+\r
+} // namespace Capabilities\r
+\r
+} // namespace Dali\r
+\r
+#endif // DALI_CAPABILITIES_H
\ No newline at end of file
index a6dba21..1973073 100644 (file)
@@ -9,6 +9,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/animation/animation-devel.cpp
   ${devel_api_src_dir}/animation/path-constrainer.cpp
   ${devel_api_src_dir}/common/addon-binder.cpp
+  ${devel_api_src_dir}/common/capabilities.cpp
   ${devel_api_src_dir}/common/hash.cpp
   ${devel_api_src_dir}/common/singleton-service.cpp
   ${devel_api_src_dir}/common/stage-devel.cpp
@@ -64,6 +65,7 @@ SET( devel_api_core_animation_header_files
 SET( devel_api_core_common_header_files
   ${devel_api_src_dir}/common/addon-binder.h
   ${devel_api_src_dir}/common/bitwise-enum.h
+  ${devel_api_src_dir}/common/capabilities.h
   ${devel_api_src_dir}/common/circular-queue.h
   ${devel_api_src_dir}/common/hash.h
   ${devel_api_src_dir}/common/singleton-service.h
@@ -126,6 +128,7 @@ SET( devel_api_core_scripting_header_files
 SET( devel_api_core_threading_header_files
   ${devel_api_src_dir}/threading/conditional-wait.h
   ${devel_api_src_dir}/threading/mutex.h
+  ${devel_api_src_dir}/threading/semaphore.h
   ${devel_api_src_dir}/threading/thread.h
   ${devel_api_src_dir}/threading/thread-pool.h
 )
index 303f389..d0913b6 100644 (file)
  */
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/internal/event/rendering/renderer-impl.h>
 
 namespace Dali
 {
 namespace DevelRenderer
 {
+bool IsAdvancedBlendEquationApplied(const Renderer& renderer)
+{
+  return GetImplementation(renderer).IsAdvancedBlendEquationApplied();
+}
+
 void AddDrawCommand(Dali::Renderer renderer, const DrawCommand& drawCommand)
 {
   auto& impl = GetImplementation(renderer);
index 59d9247..9c1ad32 100644 (file)
 
 namespace Dali
 {
+
+namespace DevelBlendEquation
+{
+
+/**
+ * @brief Enumeration for blend equation.
+ */
+enum Type
+{
+  ADD                           = Dali::BlendEquation::ADD,
+  SUBTRACT                      = Dali::BlendEquation::SUBTRACT,
+  REVERSE_SUBTRACT              = Dali::BlendEquation::REVERSE_SUBTRACT,
+
+  // OpenGL es 3.0 enumeration
+  MIN                           = 0x8007,
+  MAX                           = 0x8008,
+
+  // OpenGL es 3.2 or KHR_Blend_Equation_Advanced enumeration
+  MULTIPLY                      = 0x9294,
+  SCREEN                        = 0x9295,
+  OVERLAY                       = 0x9296,
+  DARKEN                        = 0x9297,
+  LIGHTEN                       = 0x9298,
+  COLOR_DODGE                   = 0x9299,
+  COLOR_BURN                    = 0x929A,
+  HARD_LIGHT                    = 0x929B,
+  SOFT_LIGHT                    = 0x929C,
+  DIFFERENCE                    = 0x929E,
+  EXCLUSION                     = 0x92A0,
+  HUE                           = 0x92AD,
+  SATURATION                    = 0x92AE,
+  COLOR                         = 0x92AF,
+  LUMINOSITY                    = 0x92B0
+};
+
+} // namespace DevelBlendEquation
+
 namespace DevelRenderer
 {
 /**
@@ -104,6 +141,12 @@ enum Type
      * @details Name "renderingBehavior", type Property::INTEGER.
      */
   RENDERING_BEHAVIOR = STENCIL_OPERATION_ON_Z_PASS + 2,
+
+  /**
+   * @brief name "blendEquation", type INTEGER
+   * @note The default value is BlendEquation::ADD
+   */
+  BLEND_EQUATION,
 };
 } // namespace Property
 
@@ -120,6 +163,14 @@ enum Type
 
 } // namespace Rendering
 
+
+/**
+ * @brief Query whether current blend equation is advanced option.
+ * @param[in] renderer to be checked whether it has been applied advanced blend equation or not
+ * @return True if current blend equation is advanced.
+ */
+DALI_CORE_API bool IsAdvancedBlendEquationApplied( const Renderer& renderer );
+
 } // namespace DevelRenderer
 
 } // namespace Dali
index 31c29b3..f8580de 100644 (file)
@@ -46,6 +46,24 @@ Mutex::~Mutex()
   delete mImpl;
 }
 
+Mutex::Mutex(Mutex&& rhs) noexcept
+  : mImpl(rhs.mImpl)
+{
+  rhs.mImpl = nullptr;
+}
+
+Mutex &Mutex::operator=(Mutex&& rhs) noexcept
+{
+  if (mImpl != rhs.mImpl)
+  {
+    delete mImpl;
+    mImpl = rhs.mImpl;
+    rhs.mImpl = nullptr;
+  }
+
+  return *this;
+}
+
 bool Mutex::IsLocked()
 {
   return mImpl->locked;
index b829b8b..925f363 100644 (file)
@@ -43,6 +43,16 @@ public:
   ~Mutex();
 
   /**
+   * @brief Move constructor
+   */
+  Mutex(Mutex&& rhs) noexcept;
+
+  /**
+   * @brief Move assignment
+   */
+  Mutex &operator=(Mutex&& rhs) noexcept;
+
+  /**
    * @brief Check if the mutex is locked
    * @return true if the mutex is locked
    */
diff --git a/dali/devel-api/threading/semaphore.h b/dali/devel-api/threading/semaphore.h
new file mode 100644 (file)
index 0000000..9ecb41a
--- /dev/null
@@ -0,0 +1,180 @@
+#pragma once
+
+/*
+ * 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/common/dali-common.h>
+
+// EXTERNAL INCLUDES
+#include <mutex>
+#include <condition_variable>
+#include <stdexcept>
+#include <sstream>
+#include <limits>
+
+namespace Dali
+{
+/**
+ * @brief  Class that implements a C++20 counting_semaphore like interface
+ */
+template<std::ptrdiff_t LeastMaxValue = std::numeric_limits<std::ptrdiff_t>::max()>
+class Semaphore
+{
+public:
+  /**
+   * @brief Returns the internal counter's maximum possible value,
+   *        which is greater than or equal to LeastMaxValue.
+   *
+   * @return the maximum value of the semaphore
+   */
+  static constexpr std::ptrdiff_t Max() noexcept
+  {
+    return LeastMaxValue;
+  }
+
+  /**
+   * @brief class constructor
+   *
+   * @param[in] desired the desired initial value of the semaphore
+   */
+  explicit Semaphore(std::ptrdiff_t desired)
+    : mCount(desired)
+  {
+    if (mCount < 0 || mCount > Max())
+    {
+      ThrowInvalidParamException(desired);
+    }
+  }
+
+  /**
+   * @brief Atomically increments the internal counter by the value of update.
+   *
+   * Any thread waiting for the counter to be greater than 0 will subsequently
+   * be unlocked.
+   *
+   * @param[in] update value to increment the semaphore
+   */
+  void Release(std::ptrdiff_t update = 1)
+  {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (update < 0 || update > Max() - mCount)
+    {
+      ThrowInvalidParamException(update);
+    }
+
+    mCount += update;
+    while (update--)
+    {
+      mCondVar.notify_one();
+    }
+  }
+
+  /**
+   * @brief Atomically decrements the internal counter by one if it is greater
+   *        than zero; otherwise blocks until it is greater than zero and can
+   *        successfully decrement the internal counter.
+   */
+  void Acquire()
+  {
+    std::unique_lock<std::mutex> lock(mLock);
+    while (mCount == 0)
+    {
+      mCondVar.wait(lock);
+    }
+    --mCount;
+  }
+
+  /**
+   * @brief Tries to atomically decrement the internal counter by one if it is
+   *        greater than zero; no blocking occurs regardless.
+   *
+   * @return true if it decremented the counter, otherwise false.
+   */
+  bool TryAcquire()
+  {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mCount)
+    {
+      --mCount;
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * @brief Tries to atomically decrement the internal counter by one if it is greater
+   *        than zero; otherwise blocks until it is greater than zero can successfully
+   *        decrement the internal counter, or the relTime duration has been exceeded.
+   *
+   * @param[in] relTime the minimum duration the function must wait for to fail
+   *
+   * @return true if it decremented the internal counter, otherwise false
+   */
+  template<typename Rep, typename Period>
+  bool TryAcquireFor(const std::chrono::duration<Rep, Period> &relTime)
+  {
+    std::unique_lock<std::mutex> lock(mLock);
+    while (mCount == 0)
+    {
+      if (mCondVar.wait_for(lock, relTime) == std::cv_status::timeout)
+      {
+        return false;
+      }
+    }
+    --mCount;
+    return true;
+  }
+
+  /**
+   * @brief Tries to atomically decrement the internal counter by one if it is greater
+   *        than zero; otherwise blocks until it is greater than zero can successfully
+   *        decrement the internal counter, or the absTime duration point has been passed.
+   *
+   * @param[in] absTime the earliest time the function must wait until in order to fail
+   *
+   * @return true if it decremented the internal counter, otherwise false
+   */
+  template<typename Clock, typename Duration>
+  bool TryAcquireUntil(const std::chrono::time_point<Clock, Duration> &absTime)
+  {
+    std::unique_lock<std::mutex> lock(mLock);
+    while (mCount == 0)
+    {
+      if (mCondVar.wait_until(lock, absTime) == std::cv_status::timeout)
+      {
+        return false;
+      }
+    }
+    --mCount;
+    return true;
+  }
+
+private:
+  void ThrowInvalidParamException(std::ptrdiff_t param) const
+  {
+    std::stringstream ss("Invalid parameter value ");
+    ss << param;
+    throw std::invalid_argument(ss.str());
+  }
+
+  std::condition_variable mCondVar;
+  std::mutex mLock;
+  std::ptrdiff_t mCount;
+};
+}
index ed36bdc..11a96b1 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <stdint.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 
 /*
  * This file is based on gl3.h, the following licence is included for conformance.
@@ -118,6 +119,36 @@ public:
   virtual bool IsSurfacelessContextSupported() const = 0;
 
   /**
+   * Returns current gles can support advanced blend equation
+   * @Return true current gles support advanced blend equation
+   */
+  virtual bool IsAdvancedBlendEquationSupported() = 0;
+
+  /**
+   * Returns current gles can support the blend equation
+   * @Return true current gles support the blend equation
+   */
+  virtual bool IsBlendEquationSupported( DevelBlendEquation::Type blendEquation ) = 0;
+
+  /**
+   * Returns shader prefix of shading language version.
+   * @Return shader prefix of shading language version.
+   */
+  virtual std::string GetShaderVersionPrefix() = 0;
+
+  /**
+   * Returns vertex shader prefix including shading language version.
+   * @Return vertex shader prefix including shading language version.
+   */
+  virtual std::string GetVertexShaderPrefix() = 0;
+
+  /**
+   * Returns fragment shader prefix including shading language version and extension information.
+   * @Return fragment shader prefix including shading language version and extension information.
+   */
+  virtual std::string GetFragmentShaderPrefix() = 0;
+
+  /**
    * Determine whether to convert pixel format or not.
    * @param[in] imageGlFormat GLformat of input image.
    * @param[in] textureGlFormat GLformat of Texture.
@@ -382,6 +413,7 @@ public:
   virtual void           TexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) = 0;
   virtual void           TexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
   virtual void           GetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) = 0;
+  virtual void           BlendBarrier (void) = 0;
   // clang-format on
 };
 
index ab7e5e2..8bb7d18 100644 (file)
 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR        0x93DC
 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR        0x93DD
 
+// GL_blend_equation_advanced / GLES 3.2
+#define GL_MULTIPLY                                      0x9294
+#define GL_SCREEN                                        0x9295
+#define GL_OVERLAY                                       0x9296
+#define GL_DARKEN                                        0x9297
+#define GL_LIGHTEN                                       0x9298
+#define GL_COLORDODGE                                    0x9299
+#define GL_COLORBURN                                     0x929A
+#define GL_HARDLIGHT                                     0x929B
+#define GL_SOFTLIGHT                                     0x929C
+#define GL_DIFFERENCE                                    0x929E
+#define GL_EXCLUSION                                     0x92A0
+#define GL_HSL_HUE                                       0x92AD
+#define GL_HSL_SATURATION                                0x92AE
+#define GL_HSL_COLOR                                     0x92AF
+#define GL_HSL_LUMINOSITY                                0x92B0
+
 /*------------------------------------------------------------------------*
  * EXT extension tokens
  *------------------------------------------------------------------------*/
index 9a6af8e..8650fea 100644 (file)
@@ -27,9 +27,9 @@ namespace Dali
 {
 namespace Integration
 {
-Scene Scene::New(Size size)
+Scene Scene::New(Size size, int orientation)
 {
-  Internal::ScenePtr internal = Internal::Scene::New(size);
+  Internal::ScenePtr internal = Internal::Scene::New(size, orientation);
   return Scene(internal.Get());
 }
 
@@ -156,6 +156,11 @@ void Scene::GetFramePresentedCallback(FrameCallbackContainer& callbacks)
   GetImplementation(*this).GetFramePresentedCallback(callbacks);
 }
 
+void Scene::SurfaceRotated(float width, float height, int orientation)
+{
+  GetImplementation(*this).SurfaceRotated(width, height, orientation);
+}
+
 Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
 {
   return GetImplementation(*this).EventProcessingFinishedSignal();
index 7d97dd3..d5920da 100644 (file)
@@ -66,10 +66,11 @@ public:
    * @brief Create an initialized Scene handle.
    *
    * @param[in] size The size of the set surface for this scene
+   * @param[in] orientation The rotated angle of the set surface for this scene
    *
    * @return a handle to a newly allocated Dali resource.
    */
-  static Scene New(Size size);
+  static Scene New(Size size, int orientation = 0);
 
   /**
    * @brief Downcast an Object handle to Scene handle.
@@ -284,6 +285,15 @@ public:
   void GetFramePresentedCallback(FrameCallbackContainer& callbacks);
 
   /**
+   * @brief Informs the scene that the set surface has been rotated.
+   *
+   * @param[in] width The width of rotated surface
+   * @param[in] height The height of rotated surface
+   * @param[in] orientation The orientation of rotated surface
+   */
+  void SurfaceRotated(float width, float height, int orientation);
+
+  /**
    * @brief This signal is emitted just after the event processing is finished.
    *
    * @return The signal to connect to
index 81b4db4..596e544 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 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.
@@ -27,18 +27,18 @@ const int MASK_SRC_FACTOR_RGB    = 0x0000000F;
 const int MASK_SRC_FACTOR_ALPHA  = 0x000000F0;
 const int MASK_DEST_FACTOR_RGB   = 0x00000F00;
 const int MASK_DEST_FACTOR_ALPHA = 0x0000F000;
-const int MASK_EQUATION_RGB      = 0x000F0000;
-const int MASK_EQUATION_ALPHA    = 0x00F00000;
+const int MASK_EQUATION_RGB      = 0x00FF0000;
+const int MASK_EQUATION_ALPHA    = 0xFF000000;
 
 const int SHIFT_TO_SRC_FACTOR_RGB    =  0;
 const int SHIFT_TO_SRC_FACTOR_ALPHA  =  4;
 const int SHIFT_TO_DEST_FACTOR_RGB   =  8;
 const int SHIFT_TO_DEST_FACTOR_ALPHA = 12;
 const int SHIFT_TO_EQUATION_RGB      = 16;
-const int SHIFT_TO_EQUATION_ALPHA    = 20;
+const int SHIFT_TO_EQUATION_ALPHA    = 24;
 
 static unsigned int CLEAR_BLEND_FUNC_MASK     = 0xFFFF0000; // Bottom 16 bits cleared
-static unsigned int CLEAR_BLEND_EQUATION_MASK = 0xFF00FFFF; // 8 bits cleared
+static unsigned int CLEAR_BLEND_EQUATION_MASK = 0x0000FFFF; // Top 16 bits cleared
 
 /**
  * Utility to store one of the BlendFunc values.
@@ -148,54 +148,203 @@ void StoreBlendFactor( unsigned int& options, BlendFactor::Type factor, int bitS
  * @param[in] factor The BlendEquation value.
  * @param[in] bitshift Used to shift to the correct part of options.
  */
-void StoreBlendEquation( unsigned int& options, BlendEquation::Type factor, int bitShift )
+void StoreBlendEquation( unsigned int& options, DevelBlendEquation::Type factor, int bitShift )
 {
+  // Must be same order as BLENDING_EQUATIONS, below:
+  enum {
+    ADD_BITVAL = 0u,
+    SUBTRACT_BITVAL,
+    REVERSE_SUBTRACT_BITVAL,
+    MIN_BITVAL,
+    MAX_BITVAL,
+    MULTIPLY_BITVAL,
+    SCREEN_BITVAL,
+    OVERLAY_BITVAL,
+    DARKEN_BITVAL,
+    LIGHTEN_BITVAL,
+    COLOR_DODGE_BITVAL,
+    COLOR_BURN_BITVAL,
+    HARD_LIGHT_BITVAL,
+    SOFT_LIGHT_BITVAL,
+    DIFFERENCE_BITVAL,
+    EXCLUSION_BITVAL,
+    HUE_BITVAL,
+    SATURATION_BITVAL,
+    COLOR_BITVAL,
+    LUMINOSITY_BITVAL
+  };
+
   switch ( factor )
   {
-    case BlendEquation::ADD:
+    case DevelBlendEquation::ADD:
     {
-      options |= ( 0u << bitShift );
+      options |= ( ADD_BITVAL << bitShift );
       break;
     }
 
-    case BlendEquation::SUBTRACT:
+    case DevelBlendEquation::SUBTRACT:
     {
-      options |= ( 1u << bitShift );
+      options |= ( SUBTRACT_BITVAL << bitShift );
       break;
     }
 
-    case BlendEquation::REVERSE_SUBTRACT:
+    case DevelBlendEquation::REVERSE_SUBTRACT:
     {
-      options |= ( 2u << bitShift );
+      options |= ( REVERSE_SUBTRACT_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::MIN:
+    {
+      options |= ( MIN_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::MAX:
+    {
+      options |= ( MAX_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::MULTIPLY:
+    {
+      options |= ( MULTIPLY_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::SCREEN:
+    {
+      options |= ( SCREEN_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::OVERLAY:
+    {
+      options |= ( OVERLAY_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::DARKEN:
+    {
+      options |= ( DARKEN_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::LIGHTEN:
+    {
+      options |= ( LIGHTEN_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::COLOR_DODGE:
+    {
+      options |= ( COLOR_DODGE_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::COLOR_BURN:
+    {
+      options |= ( COLOR_BURN_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::HARD_LIGHT:
+    {
+      options |= ( HARD_LIGHT_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::SOFT_LIGHT:
+    {
+      options |= ( SOFT_LIGHT_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::DIFFERENCE:
+    {
+      options |= ( DIFFERENCE_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::EXCLUSION:
+    {
+      options |= ( EXCLUSION_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::HUE:
+    {
+      options |= ( HUE_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::SATURATION:
+    {
+      options |= ( SATURATION_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::COLOR:
+    {
+      options |= ( COLOR_BITVAL << bitShift );
+      break;
+    }
+
+    case DevelBlendEquation::LUMINOSITY:
+    {
+      options |= ( LUMINOSITY_BITVAL << bitShift );
       break;
     }
   }
 }
 
 const unsigned int BLENDING_FACTOR_COUNT   = 15;
-const unsigned int BLENDING_EQUATION_COUNT = 3;
+const unsigned int BLENDING_EQUATION_COUNT = 20;
+const unsigned int BLENDING_EQUATION_ADVANCED_INDEX_START = 5;
+const unsigned int BLENDING_EQUATION_ADVANCED_INDEX_END = 19;
 
 BlendFactor::Type BLENDING_FACTORS[ BLENDING_FACTOR_COUNT ] =
-  { BlendFactor::ZERO,
-    BlendFactor::ONE,
-    BlendFactor::SRC_COLOR,
-    BlendFactor::ONE_MINUS_SRC_COLOR,
-    BlendFactor::SRC_ALPHA,
-    BlendFactor::ONE_MINUS_SRC_ALPHA,
-    BlendFactor::DST_ALPHA,
-    BlendFactor::ONE_MINUS_DST_ALPHA,
-    BlendFactor::DST_COLOR,
-    BlendFactor::ONE_MINUS_DST_COLOR,
-    BlendFactor::SRC_ALPHA_SATURATE,
-    BlendFactor::CONSTANT_COLOR,
-    BlendFactor::ONE_MINUS_CONSTANT_COLOR,
-    BlendFactor::CONSTANT_ALPHA,
-    BlendFactor::ONE_MINUS_CONSTANT_ALPHA };
-
-BlendEquation::Type BLENDING_EQUATIONS[ BLENDING_EQUATION_COUNT ] =
-  { BlendEquation::ADD,
-    BlendEquation::SUBTRACT,
-    BlendEquation::REVERSE_SUBTRACT };
+{
+  BlendFactor::ZERO,
+  BlendFactor::ONE,
+  BlendFactor::SRC_COLOR,
+  BlendFactor::ONE_MINUS_SRC_COLOR,
+  BlendFactor::SRC_ALPHA,
+  BlendFactor::ONE_MINUS_SRC_ALPHA,
+  BlendFactor::DST_ALPHA,
+  BlendFactor::ONE_MINUS_DST_ALPHA,
+  BlendFactor::DST_COLOR,
+  BlendFactor::ONE_MINUS_DST_COLOR,
+  BlendFactor::SRC_ALPHA_SATURATE,
+  BlendFactor::CONSTANT_COLOR,
+  BlendFactor::ONE_MINUS_CONSTANT_COLOR,
+  BlendFactor::CONSTANT_ALPHA,
+  BlendFactor::ONE_MINUS_CONSTANT_ALPHA
+};
+
+DevelBlendEquation::Type BLENDING_EQUATIONS[ BLENDING_EQUATION_COUNT ] =
+{
+  DevelBlendEquation::ADD,
+  DevelBlendEquation::SUBTRACT,
+  DevelBlendEquation::REVERSE_SUBTRACT,
+  DevelBlendEquation::MIN,
+  DevelBlendEquation::MAX,
+  DevelBlendEquation::MULTIPLY,
+  DevelBlendEquation::SCREEN,
+  DevelBlendEquation::OVERLAY,
+  DevelBlendEquation::DARKEN,
+  DevelBlendEquation::LIGHTEN,
+  DevelBlendEquation::COLOR_DODGE,
+  DevelBlendEquation::COLOR_BURN,
+  DevelBlendEquation::HARD_LIGHT,
+  DevelBlendEquation::SOFT_LIGHT,
+  DevelBlendEquation::DIFFERENCE,
+  DevelBlendEquation::EXCLUSION,
+  DevelBlendEquation::HUE,
+  DevelBlendEquation::SATURATION,
+  DevelBlendEquation::COLOR,
+  DevelBlendEquation::LUMINOSITY
+};
 
 /**
  * Utility to retrieve one of the BlendFunc values.
@@ -221,7 +370,7 @@ BlendFactor::Type RetrieveBlendFactor( unsigned int options, int mask, int bitSh
  * @param[in] bitshift Used to shift to the correct part of options.
  * @return The blending equation.
  */
-BlendEquation::Type RetrieveBlendEquation( unsigned int options, int mask, int bitShift )
+DevelBlendEquation::Type RetrieveBlendEquation( unsigned int options, int mask, int bitShift )
 {
   unsigned int index = options & mask;
   index = index >> bitShift;
@@ -246,7 +395,7 @@ BlendingOptions::BlendingOptions()
   SetBlendFunc( BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA,
                 BlendFactor::ONE,       BlendFactor::ONE_MINUS_SRC_ALPHA );
 
-  SetBlendEquation( BlendEquation::ADD, BlendEquation::ADD );
+  SetBlendEquation( DevelBlendEquation::ADD, DevelBlendEquation::ADD );
 }
 
 BlendingOptions::~BlendingOptions() = default;
@@ -292,7 +441,7 @@ BlendFactor::Type BlendingOptions::GetBlendDestFactorAlpha() const
   return RetrieveBlendFactor( mBitmask, MASK_DEST_FACTOR_ALPHA, SHIFT_TO_DEST_FACTOR_ALPHA );
 }
 
-void BlendingOptions::SetBlendEquation( BlendEquation::Type equationRgb, BlendEquation::Type equationAlpha )
+void BlendingOptions::SetBlendEquation( DevelBlendEquation::Type equationRgb, DevelBlendEquation::Type equationAlpha )
 {
   mBitmask &= CLEAR_BLEND_EQUATION_MASK; // Clear the BlendEquation values
 
@@ -300,12 +449,12 @@ void BlendingOptions::SetBlendEquation( BlendEquation::Type equationRgb, BlendEq
   StoreBlendEquation( mBitmask, equationAlpha, SHIFT_TO_EQUATION_ALPHA );
 }
 
-BlendEquation::Type BlendingOptions::GetBlendEquationRgb() const
+DevelBlendEquation::Type BlendingOptions::GetBlendEquationRgb() const
 {
   return RetrieveBlendEquation( mBitmask, MASK_EQUATION_RGB, SHIFT_TO_EQUATION_RGB );
 }
 
-BlendEquation::Type BlendingOptions::GetBlendEquationAlpha() const
+DevelBlendEquation::Type BlendingOptions::GetBlendEquationAlpha() const
 {
   return RetrieveBlendEquation( mBitmask, MASK_EQUATION_ALPHA, SHIFT_TO_EQUATION_ALPHA );
 }
@@ -335,6 +484,47 @@ const Vector4* BlendingOptions::GetBlendColor() const
   return mBlendColor.Get();
 }
 
+bool BlendingOptions::IsAdvancedBlendEquationApplied()
+{
+  unsigned int indexRgb = mBitmask & MASK_EQUATION_RGB;
+  indexRgb = indexRgb >> SHIFT_TO_EQUATION_RGB;
+  unsigned int indexA = mBitmask & MASK_EQUATION_ALPHA;
+  indexA = indexA >> SHIFT_TO_EQUATION_ALPHA;
+
+  return ( ( ( indexRgb >= BLENDING_EQUATION_ADVANCED_INDEX_START ) && ( indexRgb <= BLENDING_EQUATION_ADVANCED_INDEX_END ) ) ||
+           ( ( indexA   >= BLENDING_EQUATION_ADVANCED_INDEX_START ) && ( indexA   <= BLENDING_EQUATION_ADVANCED_INDEX_END ) ) );
+}
+
+bool BlendingOptions::IsAdvancedBlendEquation( DevelBlendEquation::Type equation )
+{
+  switch ( equation )
+  {
+    case DevelBlendEquation::MULTIPLY:
+    case DevelBlendEquation::SCREEN:
+    case DevelBlendEquation::OVERLAY:
+    case DevelBlendEquation::DARKEN:
+    case DevelBlendEquation::LIGHTEN:
+    case DevelBlendEquation::COLOR_DODGE:
+    case DevelBlendEquation::COLOR_BURN:
+    case DevelBlendEquation::HARD_LIGHT:
+    case DevelBlendEquation::SOFT_LIGHT:
+    case DevelBlendEquation::DIFFERENCE:
+    case DevelBlendEquation::EXCLUSION:
+    case DevelBlendEquation::HUE:
+    case DevelBlendEquation::SATURATION:
+    case DevelBlendEquation::COLOR:
+    case DevelBlendEquation::LUMINOSITY:
+    {
+      return true;
+    }
+
+    default:
+    {
+      return false;
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Dali
index b469c26..f150685 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_BLENDING_OPTIONS_H
 
 /*
- * Copyright (c) 2017 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.
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/rendering/renderer.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/public-api/math/vector4.h>
 #include <dali/internal/common/owner-pointer.h>
 
@@ -83,17 +84,17 @@ struct BlendingOptions
   /**
    * @copydoc Dali::RenderableActor::SetBlendEquation()
    */
-  void SetBlendEquation( BlendEquation::Type equationRgb, BlendEquation::Type equationAlpha );
+  void SetBlendEquation( DevelBlendEquation::Type equationRgb, DevelBlendEquation::Type equationAlpha );
 
   /**
    * @copydoc Dali::RenderableActor::GetBlendEquation()
    */
-  BlendEquation::Type GetBlendEquationRgb() const;
+  DevelBlendEquation::Type GetBlendEquationRgb() const;
 
   /**
    * @copydoc Dali::RenderableActor::GetBlendEquation()
    */
-  BlendEquation::Type GetBlendEquationAlpha() const;
+  DevelBlendEquation::Type GetBlendEquationAlpha() const;
 
   /**
    * Set the blend color.
@@ -108,6 +109,18 @@ struct BlendingOptions
    */
   const Vector4* GetBlendColor() const;
 
+  /**
+   * Query whether current blend equation is advanced option.
+   * @return True if current blend equation is advanced.
+   */
+  bool IsAdvancedBlendEquationApplied();
+
+  /**
+   * Query whether input blend equation is advanced option.
+   * @return True if input blend equation is advanced.
+   */
+  static bool IsAdvancedBlendEquation( DevelBlendEquation::Type equation );
+
 private:
 
   // Undefined copy constructor.
index b3b953f..cffc170 100644 (file)
@@ -91,6 +91,7 @@ Core::Core( RenderController& renderController,
             Integration::PartialUpdateAvailable partialUpdateAvailable )
 : mRenderController( renderController ),
   mPlatform(platform),
+  mGlAbstraction(glAbstraction),
   mProcessingEvent(false),
   mForceNextUpdate( false )
 {
@@ -422,6 +423,11 @@ AnimationPlaylist& Core::GetAnimationPlaylist() const
   return *(mAnimationPlaylist);
 }
 
+Integration::GlAbstraction& Core::GetGlAbstraction() const
+{
+  return mGlAbstraction;
+}
+
 void Core::AddScene( Scene* scene )
 {
   mScenes.push_back( scene );
index 1e72470..478bfcd 100644 (file)
@@ -311,6 +311,13 @@ private:
    */
   AnimationPlaylist& GetAnimationPlaylist() const;
 
+  /**
+   * @brief Returns GlAbstraction.
+   * @note Use only for the capability. Do not use this for bypass context
+   * @return GlAbstraction
+   */
+  Integration::GlAbstraction& GetGlAbstraction() const;
+
 private:
 
   /**
@@ -349,6 +356,10 @@ private:
   // The object registry
   ObjectRegistryPtr                             mObjectRegistry;
 
+  // GlAbstraction for capabilities of GL
+  // Not to use this for bypass Context.
+  Integration::GlAbstraction&               mGlAbstraction;
+
   bool                                      mProcessingEvent  : 1;        ///< True during ProcessEvents()
   bool                                      mForceNextUpdate:1;           ///< True if the next rendering is really required.
 
index bdd3d94..b6960ed 100755 (executable)
@@ -31,6 +31,7 @@
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/radian.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/common/capabilities.h>
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/internal/event/actors/actor-property-handler.h>
 #include <dali/internal/event/actors/actor-relayouter.h>
@@ -144,6 +145,7 @@ DALI_PROPERTY( "siblingOrder",              INTEGER,  true,  false, false, Dali:
 DALI_PROPERTY( "updateSizeHint",            VECTOR2,  true,  false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
 DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN,  true,  false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START )
 DALI_PROPERTY( "touchArea",                 VECTOR2,  true,  false, false, Dali::DevelActor::Property::TOUCH_AREA )
+DALI_PROPERTY( "blendEquation",             INTEGER,  true,  false, false, Dali::DevelActor::Property::BLEND_EQUATION )
 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
 
 // Signals
@@ -1195,6 +1197,12 @@ uint32_t Actor::AddRenderer( Renderer& renderer )
     mRenderers = new RendererContainer;
   }
 
+  if(mIsBlendEquationSet)
+  {
+    renderer.SetBlendMode(Dali::BlendMode::ON);
+    renderer.SetBlendEquation(static_cast<DevelBlendEquation::Type>(mBlendEquation));
+  }
+
   uint32_t index = static_cast<uint32_t>( mRenderers->size() ); //  4,294,967,295 renderers per actor
   RendererPtr rendererPtr = RendererPtr( &renderer );
   mRenderers->push_back( rendererPtr );
@@ -1251,6 +1259,34 @@ void Actor::RemoveRenderer( uint32_t index )
   }
 }
 
+void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
+{
+  if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
+  {
+    if(mBlendEquation != blendEquation)
+    {
+      mBlendEquation         = blendEquation;
+      uint32_t rendererCount = GetRendererCount();
+      for(uint32_t i = 0; i < rendererCount; ++i)
+      {
+        RendererPtr renderer = GetRendererAt(i);
+        renderer->SetBlendMode(Dali::BlendMode::ON);
+        renderer->SetBlendEquation(static_cast<DevelBlendEquation::Type>(blendEquation));
+      }
+    }
+    mIsBlendEquationSet = true;
+  }
+  else
+  {
+    DALI_LOG_ERROR("Invalid blend equation is entered.\n");
+  }
+}
+
+DevelBlendEquation::Type Actor::GetBlendEquation() const
+{
+  return mBlendEquation;
+}
+
 void Actor::SetDrawMode( DrawMode::Type drawMode )
 {
   // this flag is not animatable so keep the value
@@ -1475,7 +1511,9 @@ Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
   mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
   mDrawMode( DrawMode::NORMAL ),
   mColorMode( Node::DEFAULT_COLOR_MODE ),
-  mClippingMode( ClippingMode::DISABLED )
+  mClippingMode( ClippingMode::DISABLED ),
+  mBlendEquation( DevelBlendEquation::ADD ),
+  mIsBlendEquationSet( false )
 {
 }
 
index a3ad757..367beeb 100755 (executable)
@@ -1241,6 +1241,16 @@ public:
    */
   void RemoveRenderer( uint32_t index );
 
+  /**
+   * Set BlendEquation at each renderer that added on this Actor.
+   */
+  void SetBlendEquation( DevelBlendEquation::Type blendEquation );
+
+  /**
+   * @brief Get Blend Equation that applied to this Actor
+   */
+  DevelBlendEquation::Type GetBlendEquation() const;
+
 public:
 
   /**
@@ -2071,6 +2081,8 @@ protected:
   DrawMode::Type mDrawMode                         : 3; ///< Cached: How the actor and its children should be drawn
   ColorMode mColorMode                             : 3; ///< Cached: Determines whether mWorldColor is inherited
   ClippingMode::Type mClippingMode                 : 3; ///< Cached: Determines which clipping mode (if any) to use.
+  DevelBlendEquation::Type mBlendEquation          : 16;///< Cached: Determines which blend equation will be used to render renderers.
+  bool mIsBlendEquationSet                         : 1; ///< Flag to identify whether the Blend equation is set
 
 private:
 
index 3df53fc..76f82f5 100755 (executable)
@@ -584,6 +584,15 @@ void Actor::PropertyHandler::SetDefaultProperty( Internal::Actor& actor, Propert
       break;
     }
 
+    case Dali::DevelActor::Property::BLEND_EQUATION:
+    {
+      int value;
+      if( property.Get( value ) )
+      {
+        actor.SetBlendEquation( static_cast<DevelBlendEquation::Type>( value ) );
+      }
+      break;
+    }
 
     default:
     {
@@ -1620,6 +1629,12 @@ bool Actor::PropertyHandler::GetCachedPropertyValue(const Internal::Actor& actor
       break;
     }
 
+    case Dali::DevelActor::Property::BLEND_EQUATION:
+    {
+      value = actor.GetBlendEquation();
+      break;
+    }
+
     default:
     {
       // Must be a scene-graph only property
index fecea3c..b81341a 100644 (file)
@@ -524,6 +524,12 @@ const SceneGraph::Camera* CameraActor::GetCamera() const
   return mSceneObject;
 }
 
+void CameraActor::RotateProjection(int rotationAngle)
+{
+  // sceneObject is being used in a separate thread; queue a message to set
+  RotateProjectionMessage(GetEventThreadServices(), *mSceneObject, rotationAngle);
+}
+
 void CameraActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
index 4463ba1..97b62bd 100644 (file)
@@ -204,6 +204,13 @@ public:
    */
   const SceneGraph::Camera* GetCamera() const;
 
+  /**
+   * Rotate the projection.
+   * It is used in case that the target buffer direction is different from the window direction.
+   * @param [in] rotationAngle The rotation angle
+   */
+  void RotateProjection(int rotationAngle);
+
 public: // properties
 
   /**
index 081a81c..996fde7 100644 (file)
@@ -31,7 +31,7 @@
 #include <dali/public-api/math/matrix.h>
 #include <dali/internal/common/buffer-index.h>
 
-#if defined (ANDROID) || defined(WIN32)
+#if defined (ANDROID) || defined(WIN32) || defined(__APPLE__)
 namespace std
 {
 
index 496fba4..4ab5142 100755 (executable)
@@ -43,23 +43,24 @@ namespace Dali
 namespace Internal
 {
 
-ScenePtr Scene::New( Size size )
+ScenePtr Scene::New(Size size, int orientation)
 {
   ScenePtr scene = new Scene;
 
   // Second-phase construction
-  scene->Initialize( size );
+  scene->Initialize(size, orientation);
 
   return scene;
 }
 
 Scene::Scene()
-: mSceneObject( nullptr ),
+: mSceneObject(nullptr),
   mSize(), // Don't set the proper value here, this will be set when the surface is set later
   mDpi(),
-  mBackgroundColor( DEFAULT_BACKGROUND_COLOR ),
-  mDepthTreeDirty( false ),
-  mEventProcessor( *this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor() )
+  mBackgroundColor(DEFAULT_BACKGROUND_COLOR),
+  mDepthTreeDirty(false),
+  mEventProcessor(*this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor()),
+  mSurfaceOrientation(0)
 {
 }
 
@@ -94,7 +95,7 @@ Scene::~Scene()
   // When this destructor is called, the scene has either already been removed from Core or Core has already been destroyed
 }
 
-void Scene::Initialize( Size size )
+void Scene::Initialize(Size size, int orientation)
 {
   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
 
@@ -130,8 +131,9 @@ void Scene::Initialize( Size size )
   // Create the default render-task and ensure clear is enabled on it to show the background color
   RenderTaskPtr renderTask = mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() );
   renderTask->SetClearEnabled(true);
+  mSurfaceOrientation = orientation;
 
-  SurfaceResized( size.width, size.height );
+  SurfaceRotated( size.width, size.height, mSurfaceOrientation );
 
   // Create scene graph object
   mSceneObject = new SceneGraph::Scene();
@@ -199,27 +201,11 @@ Actor& Scene::GetDefaultRootActor()
   return *mRootLayer;
 }
 
-void Scene::SurfaceResized( float width, float height )
+void Scene::SurfaceResized(float width, float height)
 {
-  if( ( fabsf( mSize.width - width ) > Math::MACHINE_EPSILON_1 ) || ( fabsf( mSize.height - height ) > Math::MACHINE_EPSILON_1 ) )
+  if((fabsf(mSize.width - width) > Math::MACHINE_EPSILON_1) || (fabsf(mSize.height - height) > Math::MACHINE_EPSILON_1))
   {
-    Rect< int32_t > newSize( 0, 0, static_cast< int32_t >( width ), static_cast< int32_t >( height ) ); // truncated
-
-    mSize.width = width;
-    mSize.height = height;
-
-    // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
-    mDefaultCamera->SetPerspectiveProjection( mSize );
-
-    mRootLayer->SetSize( mSize.width, mSize.height );
-
-    ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
-    SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
-    SetDefaultSurfaceRectMessage( updateManager, newSize );
-
-    // set default render-task viewport parameters
-    RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u );
-    defaultRenderTask->SetViewport( newSize );
+    ChangedSurface(width, height, mSurfaceOrientation);
   }
 }
 
@@ -294,6 +280,43 @@ void Scene::EmitKeyEventSignal(const Dali::KeyEvent& event)
   }
 }
 
+void Scene::SurfaceRotated(float width, float height, int orientation)
+{
+  mSurfaceOrientation = orientation;
+  ChangedSurface(width, height, orientation);
+}
+
+int Scene::GetSurfaceOrientation()
+{
+  return mSurfaceOrientation;
+}
+
+void Scene::ChangedSurface(float width, float height, int orientation)
+{
+  Rect<int32_t> newSize(0, 0, static_cast<int32_t>(width), static_cast<int32_t>(height)); // truncated
+
+  mSize.width  = width;
+  mSize.height = height;
+
+  // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
+  mDefaultCamera->SetPerspectiveProjection(mSize);
+  // Set the surface orientation to Default camera for window/screen rotation
+  mDefaultCamera->RotateProjection(orientation);
+
+  mRootLayer->SetSize(width, height);
+
+  ThreadLocalStorage*        tls           = ThreadLocalStorage::GetInternal();
+  SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
+  SetDefaultSurfaceRectMessage(updateManager, newSize);
+
+  // Send the surface orientation to render manager for calculating glViewport/Scissor
+  SetDefaultSurfaceOrientationMessage(updateManager, orientation);
+
+  // set default render-task viewport parameters
+  RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u);
+  defaultRenderTask->SetViewport(newSize);
+}
+
 bool Scene::EmitKeyEventGeneratedSignal(const Dali::KeyEvent& event)
 {
   // Emit the KeyEventGenerated signal when KeyEvent is generated
index 67d08d5..44a5e3b 100755 (executable)
@@ -114,7 +114,7 @@ public:
   /**
    * @copydoc Dali::Integration::Scene::New
    */
-  static ScenePtr New( Size size );
+  static ScenePtr New(Size size, int orientation = 0);
 
   /**
    * virtual destructor
@@ -232,6 +232,24 @@ public:
   SceneGraph::Scene* GetSceneObject() const;
 
   /**
+   * Notify the surface has been rotated.
+   * When the device is rotated or the rotation event is received by display manager,
+   * this function will be called by window implementation.
+   *
+   * @param[in] width The width of rotated surface
+   * @param[in] height The height of rotated surface
+   * @param[in] orientation The orientation of rotated surface
+   */
+  void SurfaceRotated(float width, float height, int orientation);
+
+  /**
+   * @brief Get surface's current orientation
+   *
+   * @return surface orientation
+   */
+  int GetSurfaceOrientation();
+
+  /**
    * Used by the EventProcessor to emit key event signals.
    * @param[in] event The key event.
    */
@@ -338,8 +356,9 @@ private:
    * Second-phase constructor.
    *
    * @param[in] size The size of the set surface
+   * @param[in] orientation The orientation of the set surface for this scene
    */
-  void Initialize( Size size );
+  void Initialize(Size size, int orientation);
 
   // Undefined
   Scene(const Scene&) = delete;
@@ -347,6 +366,15 @@ private:
   // Undefined
   Scene& operator=(const Scene& rhs) = delete;
 
+  /**
+   * Informs the scene that the set surface has been resized or rotated.
+   *
+   * @param[in] width The width of rotated surface
+   * @param[in] height The height of rotated surface
+   * @param[in] orientation The orientation of rotated surface
+   */
+  void ChangedSurface(float width, float height, int orientation);
+
 private:
   Internal::SceneGraph::Scene* mSceneObject;
 
@@ -370,6 +398,9 @@ private:
 
   EventProcessor mEventProcessor;
 
+  // The Surface's orientation
+  int mSurfaceOrientation;
+
   // The key event signal
   Integration::Scene::KeyEventSignalType mKeyEventSignal;
   Integration::Scene::KeyEventGeneratedSignalType   mKeyEventGeneratedSignal;
index 5962768..0628fbe 100644 (file)
@@ -149,6 +149,26 @@ AnimationPlaylist& ThreadLocalStorage::GetAnimationPlaylist()
   return mCore->GetAnimationPlaylist();
 }
 
+bool ThreadLocalStorage::IsBlendEquationSupported( DevelBlendEquation::Type blendEquation )
+{
+  return mCore->GetGlAbstraction().IsBlendEquationSupported( blendEquation );
+}
+
+std::string ThreadLocalStorage::GetShaderVersionPrefix()
+{
+  return mCore->GetGlAbstraction().GetShaderVersionPrefix();
+}
+
+std::string ThreadLocalStorage::GetVertexShaderPrefix()
+{
+  return mCore->GetGlAbstraction().GetVertexShaderPrefix();
+}
+
+std::string ThreadLocalStorage::GetFragmentShaderPrefix()
+{
+  return mCore->GetGlAbstraction().GetFragmentShaderPrefix();
+}
+
 void ThreadLocalStorage::AddScene( Scene* scene )
 {
   mCore->AddScene( scene );
index f994a12..052b438 100644 (file)
@@ -163,6 +163,28 @@ public:
   AnimationPlaylist& GetAnimationPlaylist();
 
   /**
+   * @brief Returns whether the blend equation is supported in the system or not.
+   * @param[in] blendEquation blend equation to be checked.
+   * @return True if the blend equation supported.
+   */
+  bool IsBlendEquationSupported( DevelBlendEquation::Type blendEquation );
+
+  /**
+   * @brief Returns shader prefix of shading language version.
+   */
+  std::string GetShaderVersionPrefix();
+
+  /**
+   * @brief Returns vertex shader prefix including shading language version.
+   */
+  std::string GetVertexShaderPrefix();
+
+  /**
+   * @brief Returns fragment shader prefix including shading language version and extension information.
+   */
+  std::string GetFragmentShaderPrefix();
+
+  /**
    * Add a Scene to the Core.
    * This is only used by the Scene to add itself to the core when the Scene is created.
    * @param[in] scene The Scene.
index 46ca899..aa20b73 100644 (file)
@@ -40,7 +40,6 @@ namespace
 const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN( 15.0f );
 const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_BEFORE_PAN );
 const float MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO( 2.0f / 3.0f );
-const unsigned long MAXIMUM_TIME_DIFF_ALLOWED( 500 );
 const unsigned long MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS( 100 );
 const unsigned int MINIMUM_MOTION_EVENTS_BEFORE_PAN(2);
 } // unnamed namespace
index 660d4e0..7190989 100644 (file)
@@ -24,8 +24,8 @@
 namespace Dali
 {
 
-class Vector2;
-class Vector4;
+struct Vector2;
+struct Vector4;
 
 namespace Internal
 {
index ef47828..838e047 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 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.
@@ -65,6 +65,7 @@ DALI_PROPERTY( "stencilOperationOnZFail",         INTEGER,   true, false,  false
 DALI_PROPERTY( "stencilOperationOnZPass",         INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS )
 DALI_PROPERTY( "opacity",                         FLOAT,     true, true,   true,  Dali::DevelRenderer::Property::OPACITY )
 DALI_PROPERTY( "renderingBehavior",               INTEGER,   true, false,  false, Dali::DevelRenderer::Property::RENDERING_BEHAVIOR )
+DALI_PROPERTY( "blendEquation",                   INTEGER,   true, false,  false, Dali::DevelRenderer::Property::BLEND_EQUATION )
 DALI_PROPERTY_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX, RendererDefaultProperties )
 
 // Property string to enumeration tables:
@@ -86,6 +87,23 @@ DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_EQUATION )
 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, ADD )
 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, SUBTRACT )
 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, REVERSE_SUBTRACT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MIN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MAX )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MULTIPLY )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SCREEN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, OVERLAY )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, DARKEN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, LIGHTEN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR_DODGE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR_BURN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, HARD_LIGHT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SOFT_LIGHT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, DIFFERENCE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, EXCLUSION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, HUE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SATURATION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, LUMINOSITY )
 DALI_ENUM_TO_STRING_TABLE_END( BLEND_EQUATION )
 
 DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_FACTOR )
@@ -281,21 +299,26 @@ void Renderer::GetBlendFunc( BlendFactor::Type& srcFactorRgb,
   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
 }
 
-void Renderer::SetBlendEquation( BlendEquation::Type equationRgba )
+void Renderer::SetBlendEquation( DevelBlendEquation::Type equationRgba )
 {
   mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
   SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::SetBlendEquation( BlendEquation::Type equationRgb,
-                                 BlendEquation::Type equationAlpha )
+void Renderer::SetBlendEquation( DevelBlendEquation::Type equationRgb,
+                                 DevelBlendEquation::Type equationAlpha )
 {
+  if( mBlendingOptions.IsAdvancedBlendEquation( equationRgb ) || mBlendingOptions.IsAdvancedBlendEquation( equationAlpha ) )
+  {
+    DALI_LOG_ERROR("Advanced blend equation requires to be set by using SetBlendEquation( DevelBlendEquation::Type equationRgba ).");
+    return;
+  }
   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
   SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::GetBlendEquation( BlendEquation::Type& equationRgb,
-                                 BlendEquation::Type& equationAlpha ) const
+void Renderer::GetBlendEquation( DevelBlendEquation::Type& equationRgb,
+                                 DevelBlendEquation::Type& equationAlpha ) const
 {
   // These are not animatable, the cached values are up-to-date.
   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
@@ -343,6 +366,19 @@ bool Renderer::IsPreMultipliedAlphaEnabled() const
   return mPremultipledAlphaEnabled;
 }
 
+bool Renderer::IsAdvancedBlendEquationApplied() const
+{
+  DevelBlendEquation::Type equationRgb, equationAlpha;
+  GetBlendEquation( equationRgb, equationAlpha );
+
+  if( equationRgb != equationAlpha )
+  {
+    return false;
+  }
+
+  return mBlendingOptions.IsAdvancedBlendEquation( equationRgb );
+}
+
 const SceneGraph::Renderer& Renderer::GetRendererSceneObject() const
 {
   return static_cast<const SceneGraph::Renderer&>( GetSceneObject() );
@@ -377,13 +413,29 @@ void Renderer::SetDefaultProperty( Property::Index index,
       }
       break;
     }
+    case Dali::DevelRenderer::Property::BLEND_EQUATION:
+    {
+      DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
+
+      if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
+      {
+        mBlendingOptions.SetBlendEquation( convertedValue, convertedValue );
+        SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
+      }
+      break;
+    }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
-      BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
+      DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
 
-      if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
+      if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
       {
-        BlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
+        if( mBlendingOptions.IsAdvancedBlendEquation( convertedValue ) )
+        {
+          DALI_LOG_ERROR("Advanced blend equation requires to be set by using DevelBlendEquation::BLEND_EQUATION.");
+          break;
+        }
+        DevelBlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
         mBlendingOptions.SetBlendEquation( convertedValue, alphaEquation );
         SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
       }
@@ -391,11 +443,16 @@ void Renderer::SetDefaultProperty( Property::Index index,
     }
     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
     {
-      BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
+      DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
 
-      if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
+      if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
       {
-        BlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
+        if( mBlendingOptions.IsAdvancedBlendEquation( convertedValue ) )
+        {
+          DALI_LOG_ERROR("Advanced blend equation requires to be set by using DevelBlendEquation::BLEND_EQUATION.");
+          break;
+        }
+        DevelBlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
         mBlendingOptions.SetBlendEquation( rgbEquation, convertedValue );
         SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
       }
@@ -775,6 +832,11 @@ bool Renderer::GetCachedPropertyValue( Property::Index index, Property::Value& v
       value = mBlendMode;
       break;
     }
+    case Dali::DevelRenderer::Property::BLEND_EQUATION:
+    {
+      value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationRgb() );
+      break;
+    }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
       value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationRgb() );
@@ -943,6 +1005,14 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
       value = sceneObject.GetBlendMode();
       break;
     }
+    case Dali::DevelRenderer::Property::BLEND_EQUATION:
+    {
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int32_t>( blendingOptions.GetBlendEquationRgb() );
+      break;
+    }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
       uint32_t bitMask = sceneObject.GetBlendingOptions();
index 2ec0e5c..6849bf3 100755 (executable)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_RENDERER_H
 
 /*
- * Copyright (c) 2018 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.
@@ -123,19 +123,19 @@ public:
                     BlendFactor::Type& srcFactorAlpha, BlendFactor::Type& destFactorAlpha ) const;
 
   /**
-   * @copydoc Dali::Renderer::SetBlendEquation()
+   * @brief Set same Blend Equation for the RGB and alpha
    */
-  void SetBlendEquation( BlendEquation::Type equationRgba );
+  void SetBlendEquation( DevelBlendEquation::Type equationRgba );
 
   /**
-   * @copydoc Dali::Renderer::SetBlendEquation()
+   * @brief Set Blend Equation separately for the RGB and alpha
    */
-  void SetBlendEquation( BlendEquation::Type equationRgb, BlendEquation::Type equationAlpha );
+  void SetBlendEquation( DevelBlendEquation::Type equationRgb, DevelBlendEquation::Type equationAlpha );
 
   /**
-   * @copydoc Dali::Renderer::GetBlendEquation()
+   * @brief Get Blend Equation of rgb and alpha
    */
-  void GetBlendEquation( BlendEquation::Type& equationRgb, BlendEquation::Type& equationAlpha ) const;
+  void GetBlendEquation( DevelBlendEquation::Type& equationRgb, DevelBlendEquation::Type& equationAlpha ) const;
 
   /**
    * @copydoc Dali::Renderer::SetIndexedDrawFirstElement
@@ -162,6 +162,13 @@ public:
   bool IsPreMultipliedAlphaEnabled() const;
 
   /**
+   * @brief Query whether Blend Equation Advanced is used in this renderer
+   *
+   * @return True is Blend Equation Advanced is used, false otherwise.
+   */
+  bool IsAdvancedBlendEquationApplied() const;
+
+  /**
    * @brief Get the scene graph object
    *
    * @return the scene object
index 3c3dcf9..aa85ac7 100644 (file)
@@ -223,6 +223,23 @@ Shader::~Shader()
   }
 }
 
+std::string Shader::GetShaderVersionPrefix()
+{
+  Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
+  return tls.GetShaderVersionPrefix();
+}
+
+std::string Shader::GetVertexShaderPrefix()
+{
+  Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
+  return tls.GetVertexShaderPrefix();
+}
+
+std::string Shader::GetFragmentShaderPrefix()
+{
+  Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
+  return tls.GetFragmentShaderPrefix();
+}
 
 } // namespace Internal
 } // namespace Dali
index 565e6e4..9476f40 100644 (file)
@@ -106,6 +106,23 @@ private:
 
   Internal::ShaderDataPtr mShaderData;
 
+public:
+
+  /**
+   * @copydoc Dali::Shader::GetShaderVersionPrefix()
+   */
+  static std::string GetShaderVersionPrefix();
+
+  /**
+   * @copydoc Dali::Shader::GetVertexShaderPrefix()
+   */
+  static std::string GetVertexShaderPrefix();
+
+  /**
+   * @copydoc Dali::Shader::GetFragmentShaderPrefix()
+   */
+  static std::string GetFragmentShaderPrefix();
+
 };
 
 } // namespace Internal
index 54d611f..ccf284b 100644 (file)
@@ -217,11 +217,20 @@ bool Texture::ApplyNativeFragmentShader(std::string& shader)
     const char* fragmentPrefix        = mNativeImage->GetCustomFragmentPrefix();
     const char* customSamplerTypename = mNativeImage->GetCustomSamplerTypename();
 
+    size_t prefixIndex = shader.find(Dali::Shader::GetShaderVersionPrefix());
     if(fragmentPrefix != nullptr)
     {
       modified       = true;
-      fragmentShader = fragmentPrefix;
-      fragmentShader += "\n";
+      if(prefixIndex == std::string::npos)
+      {
+        fragmentShader = fragmentPrefix;
+        fragmentShader += "\n";
+      }
+      else
+      {
+        fragmentShader.clear();
+        shader.insert(prefixIndex + Dali::Shader::GetShaderVersionPrefix().length(), std::string(fragmentPrefix) + "\n");
+      }
     }
     fragmentShader += shader;
 
index 84f7f18..9d131c7 100644 (file)
@@ -22,7 +22,7 @@
 #include <dali/public-api/rendering/vertex-buffer.h>
 #include <dali/internal/update/manager/update-manager.h>
 
-#if defined (ANDROID) || defined(WIN32)
+#if defined (ANDROID) || defined(WIN32) || defined(__APPLE__)
 namespace std
 {
   uint64_t _Hash_bytes(const void* bytes, uint64_t size, uint64_t seed)
index 8f59b13..7ebecee 100644 (file)
@@ -122,7 +122,7 @@ public:
   const Matrix* GetProjectionMatrix( BufferIndex index ) const
   {
     // inlined as this is called once per frame per render instruction
-    return &mCamera->GetProjectionMatrix( index );
+    return &mCamera->GetFinalProjectionMatrix(index);
   }
   // for reflection effect
   const Camera* GetCamera() const
index e885c33..3f3d319 100755 (executable)
@@ -77,7 +77,8 @@ struct RenderManager::Impl
     programController( glAbstraction ),
     depthBufferAvailable( depthBufferAvailableParam ),
     stencilBufferAvailable( stencilBufferAvailableParam ),
-    partialUpdateAvailable( partialUpdateAvailableParam )
+    partialUpdateAvailable( partialUpdateAvailableParam ),
+    defaultSurfaceOrientation(0)
   {
      // Create thread pool with just one thread ( there may be a need to create more threads in the future ).
     threadPool = std::unique_ptr<Dali::ThreadPool>( new Dali::ThreadPool() );
@@ -174,6 +175,9 @@ struct RenderManager::Impl
   std::unique_ptr<Dali::ThreadPool>         threadPool;               ///< The thread pool
   Vector<GLuint>                            boundTextures;            ///< The textures bound for rendering
   Vector<GLuint>                            textureDependencyList;    ///< The dependency list of binded textures
+
+  int                                       defaultSurfaceOrientation; ///< defaultSurfaceOrientation for the default surface we are rendering to
+
 };
 
 RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction,
@@ -257,6 +261,11 @@ void RenderManager::SetDefaultSurfaceRect(const Rect<int32_t>& rect)
   mImpl->defaultSurfaceRect = rect;
 }
 
+void RenderManager::SetDefaultSurfaceOrientation(int orientation)
+{
+  mImpl->defaultSurfaceOrientation = orientation;
+}
+
 void RenderManager::AddRenderer( OwnerPointer< Render::Renderer >& renderer )
 {
   // Initialize the renderer as we are now in render thread
@@ -822,6 +831,7 @@ void RenderManager::RenderScene( Integration::RenderStatus& status, Integration:
     Rect<int32_t> surfaceRect = mImpl->defaultSurfaceRect;
     Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable;
     Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable;
+    int surfaceOrientation = sceneInternal.GetSurfaceOrientation();
 
     if ( instruction.mFrameBuffer )
     {
@@ -921,6 +931,7 @@ void RenderManager::RenderScene( Integration::RenderStatus& status, Integration:
       {
         viewportRect.Set( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() );
       }
+      surfaceOrientation = 0;
     }
     else // No Offscreen frame buffer rendering
     {
@@ -937,6 +948,9 @@ void RenderManager::RenderScene( Integration::RenderStatus& status, Integration:
       }
     }
 
+    // Set surface orientation
+    mImpl->currentContext->SetSurfaceOrientation(surfaceOrientation);
+
     bool clearFullFrameRect = true;
     if( instruction.mFrameBuffer != nullptr )
     {
@@ -1079,6 +1093,7 @@ void RenderManager::RenderScene( Integration::RenderStatus& status, Integration:
 
   GLenum attachments[] = { GL_DEPTH, GL_STENCIL };
   mImpl->currentContext->InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments);
+
 }
 
 void RenderManager::PostRender( bool uploadOnly )
index 2e3ea2d..8474a8a 100644 (file)
@@ -131,6 +131,12 @@ public:
   void SetDefaultSurfaceRect( const Rect<int>& rect );
 
   /**
+   * Returns the orintation for the default surface (probably the application window).
+   * @param[in] orientation the surface's orientation.
+   */
+  void SetDefaultSurfaceOrientation(int orientation);
+
+  /**
    * Add a Renderer to the render manager.
    * @param[in] renderer The renderer to add.
    * @post renderer is owned by RenderManager
index f92d0d0..279113f 100644 (file)
@@ -107,7 +107,8 @@ Context::Context( Integration::GlAbstraction& glAbstraction, OwnerContainer< Con
   mClearColor(Color::WHITE),    // initial color, never used until it's been set by the user
   mCullFaceMode( FaceCullingMode::NONE ),
   mViewPort( 0, 0, 0, 0 ),
-  mSceneContexts( contexts )
+  mSceneContexts( contexts ),
+  mSurfaceOrientation(0)
 {
 }
 
index 89538f0..a66cee1 100644 (file)
@@ -408,8 +408,16 @@ public:
    */
   void BlendEquation(GLenum mode)
   {
-    // use BlendEquationSeparate to set the rgb and alpha modes the same
-    BlendEquationSeparate( mode, mode );
+    // DO NOT USE BlendEquationSeparate to set the same rgb and alpha modes
+    // KHR blending extensions require use of glBlendEquation
+
+    if( mBlendEquationSeparateModeRGB != mode || mBlendEquationSeparateModeAlpha != mode )
+    {
+      mBlendEquationSeparateModeRGB = mode;
+      mBlendEquationSeparateModeAlpha = mode;
+      LOG_GL("BlendEquation %d\n", mode);
+      CHECK_GL( mGlAbstraction, mGlAbstraction.BlendEquation( mode ) );
+    }
   }
 
   /**
@@ -1572,8 +1580,42 @@ public:
    */
   void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
   {
-    LOG_GL("Scissor %d %d %d %d\n", x, y, width, height);
-    CHECK_GL( mGlAbstraction, mGlAbstraction.Scissor(x, y, width, height) );
+    GLint cx, cy, cw, ch;
+
+    // scissor's value should be set based on the default system coordinates.
+    // when the surface is rotated, the input valus already were set with the rotated angle.
+    // So, re-calculation is needed.
+    if(mSurfaceOrientation == 90)
+    {
+      cx = mViewPort.height - (y + height);
+      cy = x;
+      cw = height;
+      ch = width;
+    }
+    else if(mSurfaceOrientation == 180)
+    {
+      cx = mViewPort.width - (x + width);
+      cy = mViewPort.height - (y + height);
+      cw = width;
+      ch = height;
+    }
+    else if(mSurfaceOrientation == 270)
+    {
+      cx = y;
+      cy = mViewPort.width - (x + width);
+      cw = height;
+      ch = width;
+    }
+    else
+    {
+      cx = x;
+      cy = y;
+      cw = width;
+      ch = height;
+    }
+
+    LOG_GL("Scissor %d %d %d %d\n", cx, cy, cw, ch);
+    CHECK_GL(mGlAbstraction, mGlAbstraction.Scissor(cx, cy, cw, ch));
   }
 
   /**
@@ -1727,7 +1769,7 @@ public:
   }
 
   /**
-   * Wrapper for OpenGL ES 3.0 glUnmapBubffer()
+   * Wrapper for OpenGL ES 3.0 glUnmapBuffer()
    */
   GLboolean UnmapBuffer(GLenum target)
   {
@@ -1735,27 +1777,54 @@ public:
     GLboolean val = CHECK_GL( mGlAbstraction, mGlAbstraction.UnmapBuffer(target) );
     return val;
   }
+
   /**
    * Wrapper for OpenGL ES 2.0 glViewport()
    */
   void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
   {
     // check if its same as already set
-    Rect<int> newViewport( x, y, width, height );
+    GLsizei cw, ch;
+
+    // viewport's value shoud be set based on the default system size.
+    // when the surface is rotated, the input width and height already were swapped.
+    // So, re-swapping is needed.
+    if(mSurfaceOrientation == 90 || mSurfaceOrientation == 270)
+    {
+      cw = height;
+      ch = width;
+    }
+    else
+    {
+      cw = width;
+      ch = height;
+    }
+
+    // User uses the rotated viewport size.
+    Rect<int> newViewport(x, y, width, height);
 
     // Temporarily disable the viewport caching, as the implementation of GLES driver in Tizen platform
     // share a global viewport between multiple contexts, therefore glViewport has to be called every
     // time after glBindFramebuffer regardless of the same vewport size in the same context.
-//    if( mViewPort != newViewport )
+    //    if( mViewPort != newViewport )
     {
       // set new one
-      LOG_GL("Viewport %d %d %d %d\n", x, y, width, height);
-      CHECK_GL( mGlAbstraction, mGlAbstraction.Viewport(x, y, width, height) );
+      LOG_GL("Viewport %d %d %d %d\n", x, y, cw, ch);
+      CHECK_GL(mGlAbstraction, mGlAbstraction.Viewport(x, y, cw, ch));
       mViewPort = newViewport; // remember new one
     }
   }
 
   /**
+   * Wrapper for OpenGL ES 3.2 and GL_KHR_blend_equation_advanced extention glBlendBarrier()
+   */
+  void BlendBarrier()
+  {
+    LOG_GL( "BlendBarrier\n" );
+    CHECK_GL( mGlAbstraction, mGlAbstraction.BlendBarrier() );
+  }
+
+  /**
    * Get the implementation defined MAX_TEXTURE_SIZE. This values is cached when the context is created
    * @return The implementation defined MAX_TEXTURE_SIZE
    */
@@ -1764,6 +1833,12 @@ public:
     return mMaxTextureSize;
   }
 
+  void SetSurfaceOrientation(int orientation)
+  {
+    LOG_GL( "SetSurfaceOrientation: orientation: %d\n", orientation );
+    mSurfaceOrientation = orientation;
+  }
+
   /**
    * Get the current viewport.
    * @return Viewport rectangle.
@@ -1875,6 +1950,8 @@ private: // Data
   FrameBufferStateCache mFrameBufferStateCache;   ///< frame buffer state cache
 
   OwnerContainer< Context* >* mSceneContexts;      ///< The pointer of the container of contexts for surface rendering
+
+  int mSurfaceOrientation;
 };
 
 } // namespace Internal
index 2c82094..cb316e8 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.
@@ -201,8 +201,21 @@ void Renderer::SetBlending( Context& context, bool blend )
                                mBlendingOptions.GetBlendDestFactorAlpha() );
 
     // Set blend equations
-    context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(),
-                                   mBlendingOptions.GetBlendEquationAlpha() );
+    Dali::DevelBlendEquation::Type rgbEquation   = mBlendingOptions.GetBlendEquationRgb();
+    Dali::DevelBlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
+
+    if( mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled )
+    {
+      if( rgbEquation != alphaEquation )
+      {
+        DALI_LOG_ERROR( "Advanced Blend Equation have to be appried by using BlendEquation.\n" );
+      }
+      context.BlendEquation( rgbEquation );
+    }
+    else
+    {
+      context.BlendEquationSeparate( rgbEquation, alphaEquation );
+    }
   }
 
   mUpdated = true;
@@ -649,6 +662,11 @@ void Renderer::Render( Context& context,
       mUpdateAttributesLocation = false;
     }
 
+    if( mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled )
+    {
+      context.BlendBarrier();
+    }
+
     if(mDrawCommands.empty())
     {
       SetBlending( context, blend );
index 09f4acd..2c27d8b 100644 (file)
@@ -67,7 +67,7 @@ public:
   FrameCallbackProcessor( const FrameCallbackProcessor& )            = delete;  ///< Deleted copy constructor.
   FrameCallbackProcessor( FrameCallbackProcessor&& )                 = default; ///< Default move constructor.
   FrameCallbackProcessor& operator=( const FrameCallbackProcessor& ) = delete;  ///< Deleted copy assignment operator.
-  FrameCallbackProcessor& operator=( FrameCallbackProcessor&& )      = default; ///< Default move assignment operator.
+  FrameCallbackProcessor& operator=( FrameCallbackProcessor&& )      = delete;  ///< Deleted move assignment operator.
 
   /**
    * Adds an implementation of the FrameCallbackInterface.
index a7ca327..3127eab 100644 (file)
@@ -1148,6 +1148,17 @@ void UpdateManager::SurfaceReplaced( Scene* scene )
   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SurfaceReplaced, scene );
 }
 
+void UpdateManager::SetDefaultSurfaceOrientation(int orientation)
+{
+  using DerivedType = MessageValue1<RenderManager, int>;
+
+  // Reserve some memory inside the render queue
+  unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
+
+  // Construct message in the render queue memory; note that delete should not be called on the return value
+  new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetDefaultSurfaceOrientation, orientation);
+}
+
 void UpdateManager::KeepRendering( float durationSeconds )
 {
   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
index 8f272d8..4f2214a 100644 (file)
@@ -634,6 +634,12 @@ public:
   void SetDefaultSurfaceRect( const Rect<int>& rect );
 
   /**
+   * Set the default surface orientation.
+   * @param[in] orientation The orientation value representing the surface.
+   */
+  void SetDefaultSurfaceOrientation(int orientation);
+
+  /**
    * @copydoc Dali::Stage::KeepRendering()
    */
   void KeepRendering( float durationSeconds );
@@ -1095,6 +1101,17 @@ inline void SurfaceReplacedMessage( UpdateManager& manager, const SceneGraph::Sc
   new (slot) LocalType( &manager, &UpdateManager::SurfaceReplaced, &scene );
 }
 
+inline void SetDefaultSurfaceOrientationMessage(UpdateManager& manager, int orientation)
+{
+  using LocalType = MessageValue1<UpdateManager, int>;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = manager.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&manager, &UpdateManager::SetDefaultSurfaceOrientation, orientation);
+}
+
 inline void KeepRenderingMessage( UpdateManager& manager, float durationSeconds )
 {
   using LocalType = MessageValue1<UpdateManager, float>;
index 88fefbb..ac9c4a9 100644 (file)
@@ -70,7 +70,7 @@ public:
   UpdateProxy( const UpdateProxy& )            = delete;  ///< Deleted copy constructor.
   UpdateProxy( UpdateProxy&& )                 = default; ///< Default move constructor.
   UpdateProxy& operator=( const UpdateProxy& ) = delete;  ///< Deleted copy assignment operator.
-  UpdateProxy& operator=( UpdateProxy&& )      = default; ///< Default move assignment operator.
+  UpdateProxy& operator=( UpdateProxy&& )      = delete;  ///< Deleted move assignment operator.
 
   /**
    * @copydoc Dali::UpdateProxy::GetPosition()
index e644bb3..d07c8c7 100644 (file)
@@ -161,6 +161,7 @@ const Vector3 Camera::DEFAULT_TARGET_POSITION( 0.0f, 0.0f, 0.0f );
 Camera::Camera()
 : mUpdateViewFlag( UPDATE_COUNT ),
   mUpdateProjectionFlag( UPDATE_COUNT ),
+  mProjectionRotation(0),
   mNode( nullptr ),
   mType( DEFAULT_TYPE ),
   mProjectionMode( DEFAULT_MODE ),
@@ -176,7 +177,8 @@ Camera::Camera()
   mTargetPosition( DEFAULT_TARGET_POSITION ),
   mViewMatrix(),
   mProjectionMatrix(),
-  mInverseViewProjection( Matrix::IDENTITY )
+  mInverseViewProjection( Matrix::IDENTITY ),
+  mFinalProjection(Matrix::IDENTITY)
 {
 }
 
@@ -268,8 +270,6 @@ void Camera::SetTargetPosition( const Vector3& targetPosition )
   mUpdateViewFlag = UPDATE_COUNT;
 }
 
-
-
 void VectorReflectedByPlane(Vector4 &out, Vector4 &in, Vector4 &plane)
 {
   float d = float(2.0) * plane.Dot(in);
@@ -331,6 +331,12 @@ void Camera::SetReflectByPlane( const Vector4& plane )
   mUpdateViewFlag = UPDATE_COUNT;
 }
 
+void Camera::RotateProjection(int rotationAngle)
+{
+  mProjectionRotation = rotationAngle;
+  mUpdateViewFlag     = UPDATE_COUNT;
+}
+
 const Matrix& Camera::GetProjectionMatrix( BufferIndex bufferIndex ) const
 {
   return mProjectionMatrix[ bufferIndex ];
@@ -346,6 +352,11 @@ const Matrix& Camera::GetInverseViewProjectionMatrix( BufferIndex bufferIndex )
   return mInverseViewProjection[ bufferIndex ];
 }
 
+const Matrix& Camera::GetFinalProjectionMatrix(BufferIndex bufferIndex) const
+{
+  return mFinalProjection[ bufferIndex ];
+}
+
 const PropertyInputImpl* Camera::GetProjectionMatrix() const
 {
   return &mProjectionMatrix;
@@ -654,7 +665,39 @@ uint32_t Camera::UpdateProjection( BufferIndex updateBufferIndex )
         }
       }
 
-      mProjectionMatrix.SetDirty( updateBufferIndex );
+      mProjectionMatrix.SetDirty(updateBufferIndex);
+
+      Matrix& finalProjection = mFinalProjection[updateBufferIndex];
+      finalProjection.SetIdentity();
+
+      Quaternion rotationAngle;
+      switch(mProjectionRotation)
+      {
+        case 90:
+        {
+          rotationAngle = Quaternion(Dali::ANGLE_90, Vector3::ZAXIS);
+          break;
+        }
+        case 180:
+        {
+          rotationAngle = Quaternion(Dali::ANGLE_180, Vector3::ZAXIS);
+          break;
+        }
+        case 270:
+        {
+          rotationAngle = Quaternion(Dali::ANGLE_270, Vector3::ZAXIS);
+          break;
+        }
+        default:
+          rotationAngle = Quaternion(Dali::ANGLE_0, Vector3::ZAXIS);
+          break;
+      }
+
+      Matrix rotation;
+      rotation.SetIdentity();
+      rotation.SetTransformComponents(Vector3(1.0f, 1.0f, 1.0f), rotationAngle, Vector3(0.0f, 0.0f, 0.0f));
+
+      Matrix::Multiply(finalProjection, mProjectionMatrix.Get(updateBufferIndex), rotation);
     }
     --mUpdateProjectionFlag;
   }
index c5917a0..d752b5c 100644 (file)
@@ -161,6 +161,11 @@ public:
   void SetFarClippingPlane( float farClippingPlane );
 
   /**
+   * @copydoc Dali::Internal::CameraActor::RotateProjection
+   */
+  void RotateProjection(int rotationAngle);
+
+  /**
    * @copydoc Dali::Internal::CameraActor::SetTarget
    */
   void SetTargetPosition( const Vector3& targetPosition );
@@ -224,6 +229,13 @@ public:
   const Matrix& GetInverseViewProjectionMatrix( BufferIndex bufferIndex ) const;
 
   /**
+   * Retrieve the final projection-matrix; this is double buffered for input handling.
+   * @param[in] bufferIndex The buffer to read from.
+   * @return The projection-matrix that should be used to render.
+   */
+  const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
+
+  /**
    * Retrieve the projection-matrix property querying interface.
    * @pre The camera is on-stage.
    * @return The projection-matrix property querying interface.
@@ -295,6 +307,7 @@ private:
 
   uint32_t                  mUpdateViewFlag;       ///< This is non-zero if the view matrix requires an update
   uint32_t                  mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
+  int                       mProjectionRotation;   ///< The rotaion angle of the projection
   const Node*                   mNode;                 ///< The node this scene graph camera belongs to
 
 public:  // PROPERTIES
@@ -323,6 +336,7 @@ public:  // PROPERTIES
 
   DoubleBuffered< FrustumPlanes > mFrustum;               ///< Clipping frustum; double buffered for input handling
   DoubleBuffered< Matrix >        mInverseViewProjection; ///< Inverted viewprojection; double buffered for input handling
+  DoubleBuffered< Matrix >        mFinalProjection;       ///< Final projection matrix; double buffered for input handling
 
 };
 
@@ -460,6 +474,17 @@ inline void SetInvertYAxisMessage( EventThreadServices& eventThreadServices, con
   new (slot) LocalType( &camera, &Camera::SetInvertYAxis, parameter );
 }
 
+inline void RotateProjectionMessage( EventThreadServices& eventThreadServices, const Camera& camera, int parameter )
+{
+  typedef MessageValue1< Camera, int > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &camera, &Camera::RotateProjection, parameter );
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index ed5005d..371199a 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 2;
 const uint32_t    CORE_MINOR_VERSION = 0;
-const uint32_t    CORE_MICRO_VERSION = 0;
+const uint32_t    CORE_MICRO_VERSION = 3;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 760bf79..9adf7de 100644 (file)
@@ -53,4 +53,19 @@ Shader::Shader(Internal::Shader* pointer)
 {
 }
 
+std::string Shader::GetShaderVersionPrefix()
+{
+  return Dali::Internal::Shader::GetShaderVersionPrefix();
+}
+
+std::string Shader::GetVertexShaderPrefix()
+{
+  return Dali::Internal::Shader::GetVertexShaderPrefix();
+}
+
+std::string Shader::GetFragmentShaderPrefix()
+{
+  return Dali::Internal::Shader::GetFragmentShaderPrefix();
+}
+
 } // namespace Dali
index 2535639..f20c707 100644 (file)
@@ -187,6 +187,33 @@ public:
    */
   Shader& operator=(Shader&& rhs);
 
+  /**
+   * @brief Get shader preprocessor of shading language version.
+   * @note This can potentially block until GL has been initialized
+   * when the first time any DALi application is launched in the system.
+   * @SINCE_1_9.36
+   * @return shader preprocessor string.
+   */
+  static std::string GetShaderVersionPrefix();
+
+  /**
+   * @brief Get vertex shader preprocessor that includes shading language version.
+   * @note This can potentially block until GL has been initialized
+   * when the first time any DALi application is launched in the system.
+   * @SINCE_1_9.36
+   * @return Vertex shader preprocessor string.
+   */
+  static std::string GetVertexShaderPrefix();
+
+  /**
+   * @brief Get fragment shader preprocessor that includes shading language version.
+   * @note This can potentially block until GL has been initialized
+   * when the first time any DALi application is launched in the system.
+   * @SINCE_1_9.36
+   * @return Fragment shader preprocessor string.
+   */
+  static std::string GetFragmentShaderPrefix();
+
 public:
   /**
    * @brief This constructor is used by Dali New() methods.
index 236122e..d060792 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    2.0.0
+Version:    2.0.3
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT