FBO/Texture access synchronization for multiple contexts 91/210091/7
authorRichard Huang <r.huang@samsung.com>
Thu, 11 Jul 2019 13:50:53 +0000 (14:50 +0100)
committerRichard Huang <r.huang@samsung.com>
Wed, 17 Jul 2019 13:58:08 +0000 (14:58 +0100)
Change-Id: I62e2671eb14537d4267485ebaefa237b4743737f

20 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali/dali-test-suite-utils/test-application.h
automated-tests/src/dali/dali-test-suite-utils/test-gl-context-helper-abstraction.h [new file with mode: 0644]
dali/integration-api/CMakeLists.txt
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/integration-api/file.list
dali/integration-api/gl-context-helper-abstraction.h [new file with mode: 0644]
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/render/renderers/render-surface-frame-buffer.cpp
dali/internal/render/renderers/render-surface-frame-buffer.h
dali/internal/render/renderers/render-texture-frame-buffer.cpp
dali/internal/render/renderers/render-texture-frame-buffer.h

index d457916..6e41c42 100644 (file)
@@ -58,6 +58,7 @@ void TestApplication::CreateCore()
                                         mPlatformAbstraction,
                                         mGlAbstraction,
                                         mGlSyncAbstraction,
+                                        mGlContextHelperAbstraction,
                                         mDataRetentionPolicy,
                                         Integration::RenderToFrameBuffer::FALSE,
                                         Integration::DepthBufferAvailable::TRUE,
@@ -156,6 +157,11 @@ TestGlSyncAbstraction& TestApplication::GetGlSyncAbstraction()
   return mGlSyncAbstraction;
 }
 
+TestGlContextHelperAbstraction& TestApplication::GetGlContextHelperAbstraction()
+{
+  return mGlContextHelperAbstraction;
+}
+
 void TestApplication::ProcessEvent(const Integration::Event& event)
 {
   mCore->QueueEvent(event);
index 32447d6..cc694df 100644 (file)
@@ -22,6 +22,7 @@
 #include <test-platform-abstraction.h>
 #include "test-gl-sync-abstraction.h"
 #include "test-gl-abstraction.h"
+#include "test-gl-context-helper-abstraction.h"
 #include "test-render-controller.h"
 #include "test-render-surface.h"
 #include <dali/public-api/common/dali-common.h>
@@ -66,6 +67,7 @@ public:
   TestRenderController& GetRenderController();
   TestGlAbstraction& GetGlAbstraction();
   TestGlSyncAbstraction& GetGlSyncAbstraction();
+  TestGlContextHelperAbstraction& GetGlContextHelperAbstraction();
   void ProcessEvent(const Integration::Event& event);
   void SendNotification();
   bool Render( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL );
@@ -93,6 +95,7 @@ protected:
   TestRenderController      mRenderController;
   TestGlAbstraction         mGlAbstraction;
   TestGlSyncAbstraction     mGlSyncAbstraction;
+  TestGlContextHelperAbstraction mGlContextHelperAbstraction;
   TestRenderSurface*        mRenderSurface;
 
   Integration::UpdateStatus mStatus;
diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gl-context-helper-abstraction.h b/automated-tests/src/dali/dali-test-suite-utils/test-gl-context-helper-abstraction.h
new file mode 100644 (file)
index 0000000..0442f0d
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef TEST_GL_CONTEXT_HELPER_ABSTRACTION_H
+#define TEST_GL_CONTEXT_HELPER_ABSTRACTION_H
+
+/*
+ * Copyright (c) 2019 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/integration-api/gl-context-helper-abstraction.h>
+
+namespace Dali
+{
+
+/**
+ * Class to emulate the GL context helper
+ */
+class DALI_CORE_API TestGlContextHelperAbstraction: public Integration::GlContextHelperAbstraction
+{
+public:
+  /**
+   * Constructor
+   */
+  TestGlContextHelperAbstraction() {};
+
+  /**
+   * Destructor
+   */
+  ~TestGlContextHelperAbstraction() {};
+
+  /**
+   * @brief Switch to the surfaceless GL context
+   */
+  virtual void MakeSurfacelessContextCurrent() {};
+
+  /**
+   * @brief Switch to the GL context of the specific render surface
+   * @param[in] surface The render surface
+   */
+  virtual void MakeContextCurrent( Integration::RenderSurface* surface ) {};
+
+  /**
+   * @brief Clear the GL context
+   */
+  virtual void MakeContextNull() {};
+
+  /**
+   * @brief Wait until all GL rendering calls for the current GL context are executed
+   */
+  virtual void WaitClient() {};
+private:
+
+  TestGlContextHelperAbstraction( const TestGlContextHelperAbstraction& ); ///< Undefined
+  TestGlContextHelperAbstraction& operator=( const TestGlContextHelperAbstraction& ); ///< Undefined
+};
+
+} // Dali
+
+#endif // TEST_GL_CONTEXT_HELPER_ABSTRACTION_H
index c205870..e02a8cf 100644 (file)
@@ -34,6 +34,7 @@ SET(INTEGRATION_API_HEADERS
   ${CMAKE_CURRENT_SOURCE_DIR}/gl-abstraction.h
   ${CMAKE_CURRENT_SOURCE_DIR}/gl-defines.h
   ${CMAKE_CURRENT_SOURCE_DIR}/gl-sync-abstraction.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/gl-context-helper-abstraction.h
   ${CMAKE_CURRENT_SOURCE_DIR}/render-controller.h
   ${CMAKE_CURRENT_SOURCE_DIR}/platform-abstraction.h
   ${CMAKE_CURRENT_SOURCE_DIR}/processor-interface.h
index 596ef9a..c2c0fcf 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/integration-api/events/event.h>
 #include <dali/integration-api/gl-sync-abstraction.h>
+#include <dali/integration-api/gl-context-helper-abstraction.h>
 #include <dali/integration-api/processor-interface.h>
 #include <dali/internal/common/core-impl.h>
 
@@ -38,6 +39,7 @@ Core* Core::New( RenderController& renderController,
                  PlatformAbstraction& platformAbstraction,
                  GlAbstraction& glAbstraction,
                  GlSyncAbstraction& glSyncAbstraction,
+                 GlContextHelperAbstraction& glContextHelperAbstraction,
                  ResourcePolicy::DataRetention policy,
                  RenderToFrameBuffer renderToFboEnabled,
                  DepthBufferAvailable depthBufferAvailable,
@@ -48,6 +50,7 @@ Core* Core::New( RenderController& renderController,
                                         platformAbstraction,
                                         glAbstraction,
                                         glSyncAbstraction,
+                                        glContextHelperAbstraction,
                                         policy,
                                         renderToFboEnabled,
                                         depthBufferAvailable,
index ff62bcb..8da5583 100644 (file)
@@ -43,6 +43,7 @@ namespace Integration
 class Core;
 class GlAbstraction;
 class GlSyncAbstraction;
+class GlContextHelperAbstraction;
 class PlatformAbstraction;
 class Processor;
 class RenderController;
@@ -224,6 +225,7 @@ public:
    * @param[in] platformAbstraction The interface providing platform specific services.
    * @param[in] glAbstraction The interface providing OpenGL services.
    * @param[in] glSyncAbstraction The interface providing OpenGL sync objects.
+   * @param[in] glContextHelperAbstraction The interface providing OpenGL context helper objects.
    * @param[in] policy The data retention policy. This depends on application setting
    * and platform support. Dali should honour this policy when deciding to discard
    * intermediate resource data.
@@ -236,6 +238,7 @@ public:
                     PlatformAbstraction& platformAbstraction,
                     GlAbstraction& glAbstraction,
                     GlSyncAbstraction& glSyncAbstraction,
+                    GlContextHelperAbstraction& glContextHelperAbstraction,
                     ResourcePolicy::DataRetention policy,
                     RenderToFrameBuffer renderToFboEnabled,
                     DepthBufferAvailable depthBufferAvailable,
index 9ec9155..c4174fa 100644 (file)
@@ -33,6 +33,7 @@ platform_abstraction_header_files = \
    $(platform_abstraction_src_dir)/gl-abstraction.h \
    $(platform_abstraction_src_dir)/gl-defines.h \
    $(platform_abstraction_src_dir)/gl-sync-abstraction.h \
+   $(platform_abstraction_src_dir)/gl-context-helper-abstraction.h \
    $(platform_abstraction_src_dir)/render-controller.h \
    $(platform_abstraction_src_dir)/platform-abstraction.h \
    $(platform_abstraction_src_dir)/processor-interface.h \
diff --git a/dali/integration-api/gl-context-helper-abstraction.h b/dali/integration-api/gl-context-helper-abstraction.h
new file mode 100644 (file)
index 0000000..7e425f9
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_INTEGRATION_GL_CONTEXT_HELPER_ABSTRACTION_H
+#define DALI_INTEGRATION_GL_CONTEXT_HELPER_ABSTRACTION_H
+
+/*
+ * Copyright (c) 2019 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>
+#include <dali/integration-api/render-surface.h>
+
+namespace Dali
+{
+namespace Integration
+{
+
+/**
+ * This abstraction defines the interface for accessing GL context.
+ */
+class GlContextHelperAbstraction
+{
+protected:
+  /**
+   * Virtual protected destructor, no deletion through this interface
+   */
+  virtual ~GlContextHelperAbstraction() = default;
+
+public:
+
+  /**
+   * @brief Switch to the surfaceless GL context
+   */
+  virtual void MakeSurfacelessContextCurrent() = 0;
+
+  /**
+   * @brief Switch to the GL context of the specific render surface
+   * @param[in] surface The render surface
+   */
+  virtual void MakeContextCurrent( Integration::RenderSurface* surface ) = 0;
+
+  /**
+   * @brief Clear the GL context
+   */
+  virtual void MakeContextNull() = 0;
+
+  /**
+   * @brief Wait until all GL rendering calls for the current GL context are executed
+   */
+  virtual void WaitClient() = 0;
+};
+
+} // namespace Integration
+} // namespace Dali
+
+#endif // DALI_INTEGRATION_GL_CONTEXT_HELPER_ABSTRACTION_H
index b906d8f..fb5eb11 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/events/event.h>
 #include <dali/integration-api/gl-sync-abstraction.h>
+#include <dali/integration-api/gl-context-helper-abstraction.h>
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/integration-api/processor-interface.h>
 #include <dali/integration-api/render-controller.h>
@@ -75,6 +76,7 @@ using Integration::RenderController;
 using Integration::PlatformAbstraction;
 using Integration::GlSyncAbstraction;
 using Integration::GlAbstraction;
+using Integration::GlContextHelperAbstraction;
 using Integration::Event;
 using Integration::UpdateStatus;
 using Integration::RenderStatus;
@@ -83,6 +85,7 @@ Core::Core( RenderController& renderController,
             PlatformAbstraction& platform,
             GlAbstraction& glAbstraction,
             GlSyncAbstraction& glSyncAbstraction,
+            GlContextHelperAbstraction& glContextHelperAbstraction,
             ResourcePolicy::DataRetention dataRetentionPolicy,
             Integration::RenderToFrameBuffer renderToFboEnabled,
             Integration::DepthBufferAvailable depthBufferAvailable,
@@ -106,7 +109,7 @@ Core::Core( RenderController& renderController,
 
   mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
 
-  mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, depthBufferAvailable, stencilBufferAvailable );
+  mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, glContextHelperAbstraction, depthBufferAvailable, stencilBufferAvailable );
 
   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
 
index 21e0a74..e419745 100644 (file)
@@ -41,6 +41,7 @@ class RenderController;
 class PlatformAbstraction;
 class GlAbstraction;
 class GlSyncAbstraction;
+class GlContextHelperAbstraction;
 class UpdateStatus;
 class RenderStatus;
 class RenderSurface;
@@ -83,6 +84,7 @@ public:
         Integration::PlatformAbstraction& platform,
         Integration::GlAbstraction& glAbstraction,
         Integration::GlSyncAbstraction& glSyncAbstraction,
+        Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
         ResourcePolicy::DataRetention dataRetentionPolicy,
         Integration::RenderToFrameBuffer renderToFboEnabled,
         Integration::DepthBufferAvailable depthBufferAvailable,
index 1d80991..0061b87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -389,7 +389,8 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList,
                                                  const Matrix& viewMatrix,
                                                  const Matrix& projectionMatrix,
                                                  Integration::DepthBufferAvailable depthBufferAvailable,
-                                                 Integration::StencilBufferAvailable stencilBufferAvailable )
+                                                 Integration::StencilBufferAvailable stencilBufferAvailable,
+                                                 Vector<GLuint>& boundTextures )
 {
   DALI_PRINT_RENDER_LIST( renderList );
 
@@ -447,7 +448,7 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList,
 
       // Render the item.
       item.mRenderer->Render( context, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix,
-                              viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque );
+                              viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque, boundTextures );
     }
   }
 }
@@ -462,7 +463,8 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru
                                                  Context& context,
                                                  BufferIndex bufferIndex,
                                                  Integration::DepthBufferAvailable depthBufferAvailable,
-                                                 Integration::StencilBufferAvailable stencilBufferAvailable )
+                                                 Integration::StencilBufferAvailable stencilBufferAvailable,
+                                                 Vector<GLuint>& boundTextures )
 {
   DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
 
@@ -490,7 +492,8 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru
                            *viewMatrix,
                            *projectionMatrix,
                             depthBufferAvailable,
-                            stencilBufferAvailable );
+                            stencilBufferAvailable,
+                            boundTextures );
       }
     }
   }
index 523cc14..30c8041 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_RENDER_ALGORITHMS_H
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -58,12 +58,14 @@ class RenderAlgorithms
      * @param[in] bufferIndex            The current render buffer index (previous update buffer)
      * @param[in] depthBufferAvailable   Whether the depth buffer is available
      * @param[in] stencilBufferAvailable Whether the stencil buffer is available
+     * @param[in] boundTextures          The textures bound for rendering
      */
     void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction,
                                    Context& context,
                                    BufferIndex bufferIndex,
                                    Integration::DepthBufferAvailable depthBufferAvailable,
-                                   Integration::StencilBufferAvailable stencilBufferAvailable );
+                                   Integration::StencilBufferAvailable stencilBufferAvailable,
+                                   Vector<GLuint>& boundTextures );
 
   private:
 
@@ -113,6 +115,7 @@ class RenderAlgorithms
      * @param[in] projectionMatrix       The projection matrix from the appropriate camera.
      * @param[in] depthBufferAvailable   Whether the depth buffer is available
      * @param[in] stencilBufferAvailable Whether the stencil buffer is available
+     * @param[in] boundTextures          The textures bound for rendering
      */
     inline void ProcessRenderList( const Dali::Internal::SceneGraph::RenderList& renderList,
                                    Context& context,
@@ -120,7 +123,8 @@ class RenderAlgorithms
                                    const Matrix& viewMatrix,
                                    const Matrix& projectionMatrix,
                                    Integration::DepthBufferAvailable depthBufferAvailable,
-                                   Integration::StencilBufferAvailable stencilBufferAvailable );
+                                   Integration::StencilBufferAvailable stencilBufferAvailable,
+                                   Vector<GLuint>& boundTextures );
 
     // Prevent copying:
     RenderAlgorithms( RenderAlgorithms& rhs );
index 2d550b5..2eec97a 100644 (file)
 // CLASS HEADER
 #include <dali/internal/render/common/render-manager.h>
 
+// EXTERNAL INCLUDES
+#include <memory.h>
+
 // INTERNAL INCLUDES
 #include <dali/public-api/actors/sampling.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/render-tasks/render-task.h>
+#include <dali/devel-api/threading/thread-pool.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/core.h>
+#include <dali/integration-api/gl-context-helper-abstraction.h>
 #include <dali/internal/common/owner-pointer.h>
 #include <dali/internal/render/common/render-algorithms.h>
 #include <dali/internal/render/common/render-debug.h>
@@ -64,12 +69,14 @@ struct RenderManager::Impl
 {
   Impl( Integration::GlAbstraction& glAbstraction,
         Integration::GlSyncAbstraction& glSyncAbstraction,
+        Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
         Integration::DepthBufferAvailable depthBufferAvailableParam,
         Integration::StencilBufferAvailable stencilBufferAvailableParam )
   : context( glAbstraction ),
     currentContext( &context ),
     glAbstraction( glAbstraction ),
     glSyncAbstraction( glSyncAbstraction ),
+    glContextHelperAbstraction( glContextHelperAbstraction ),
     renderQueue(),
     instructions(),
     renderAlgorithms(),
@@ -86,10 +93,14 @@ struct RenderManager::Impl
     depthBufferAvailable( depthBufferAvailableParam ),
     stencilBufferAvailable( stencilBufferAvailableParam )
   {
+     // 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() );
+    threadPool->Initialize( 1u );
   }
 
   ~Impl()
   {
+    threadPool.reset( nullptr ); // reset now to maintain correct destruction order
   }
 
   void AddRenderTracker( Render::RenderTracker* renderTracker )
@@ -129,6 +140,7 @@ struct RenderManager::Impl
   OwnerContainer< Context* >                surfaceContextContainer; ///< List of owned contexts holding the GL state per surface
   Integration::GlAbstraction&               glAbstraction;           ///< GL abstraction
   Integration::GlSyncAbstraction&           glSyncAbstraction;       ///< GL sync abstraction
+  Integration::GlContextHelperAbstraction&  glContextHelperAbstraction; ///< GL context helper abstraction
   RenderQueue                               renderQueue;             ///< A message queue for receiving messages from the update-thread.
 
   // Render instructions describe what should be rendered during RenderManager::Render()
@@ -159,16 +171,21 @@ struct RenderManager::Impl
   Integration::DepthBufferAvailable         depthBufferAvailable;     ///< Whether the depth buffer is available
   Integration::StencilBufferAvailable       stencilBufferAvailable;   ///< Whether the stencil buffer is available
 
+  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
 };
 
 RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction,
                                    Integration::GlSyncAbstraction& glSyncAbstraction,
+                                   Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
                                    Integration::DepthBufferAvailable depthBufferAvailable,
                                    Integration::StencilBufferAvailable stencilBufferAvailable )
 {
   RenderManager* manager = new RenderManager;
   manager->mImpl = new Impl( glAbstraction,
                              glSyncAbstraction,
+                             glContextHelperAbstraction,
                              depthBufferAvailable,
                              stencilBufferAvailable );
   return manager;
@@ -476,11 +493,16 @@ void RenderManager::Render( Integration::RenderStatus& status, bool forceClear )
     if ( mImpl->currentContext != &mImpl->context )
     {
       mImpl->currentContext = &mImpl->context;
+
+      if ( mImpl->currentContext->IsSurfacelessContextSupported() )
+      {
+        mImpl->glContextHelperAbstraction.MakeSurfacelessContextCurrent();
+      }
+
       // Clear the current cached program when the context is switched
       mImpl->programController.ClearCurrentProgram();
     }
 
-
     // Upload the geometries
     for( uint32_t i = 0; i < count; ++i )
     {
@@ -524,6 +546,11 @@ void RenderManager::Render( Integration::RenderStatus& status, bool forceClear )
       DoRender( instruction );
     }
 
+    if ( mImpl->currentContext->IsSurfacelessContextSupported() )
+    {
+      mImpl->glContextHelperAbstraction.MakeSurfacelessContextCurrent();
+    }
+
     GLenum attachments[] = { GL_DEPTH, GL_STENCIL };
     mImpl->context.InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments);
     for ( auto&& context : mImpl->surfaceContextContainer )
@@ -590,6 +617,8 @@ void RenderManager::DoRender( RenderInstruction& instruction )
         {
           // Switch the correct context if rendering to a surface
           mImpl->currentContext = surfaceContext;
+          surfaceFrameBuffer->MakeContextCurrent();
+
           // Clear the current cached program when the context is switched
           mImpl->programController.ClearCurrentProgram();
         }
@@ -602,6 +631,11 @@ void RenderManager::DoRender( RenderInstruction& instruction )
     {
       // Switch to shared context for off-screen buffer
       mImpl->currentContext = &mImpl->context;
+
+      if ( mImpl->currentContext->IsSurfacelessContextSupported() )
+      {
+        mImpl->glContextHelperAbstraction.MakeSurfacelessContextCurrent();
+      }
     }
   }
 
@@ -614,6 +648,13 @@ void RenderManager::DoRender( RenderInstruction& instruction )
   if( instruction.mFrameBuffer )
   {
     instruction.mFrameBuffer->Bind( *mImpl->currentContext );
+
+    if ( !instruction.mFrameBuffer->IsSurfaceBacked() )
+    {
+      // For each offscreen buffer, update the dependency list with the new texture id used by this frame buffer.
+      Render::TextureFrameBuffer* textureFrameBuffer = static_cast<Render::TextureFrameBuffer*>( instruction.mFrameBuffer );
+      mImpl->textureDependencyList.PushBack( textureFrameBuffer->GetTextureId() );
+    }
   }
   else
   {
@@ -728,12 +769,79 @@ void RenderManager::DoRender( RenderInstruction& instruction )
     mImpl->currentContext->SetScissorTest( false );
   }
 
+  // Clear the list of bound textures
+  mImpl->boundTextures.Clear();
+
   mImpl->renderAlgorithms.ProcessRenderInstruction(
       instruction,
       *mImpl->currentContext,
       mImpl->renderBufferIndex,
       depthBufferAvailable,
-      stencilBufferAvailable );
+      stencilBufferAvailable,
+      mImpl->boundTextures );
+
+  // Synchronise the FBO/Texture access when there are multiple contexts
+  if ( mImpl->currentContext->IsSurfacelessContextSupported() )
+  {
+    // Check whether any binded texture is in the dependency list
+    bool textureFound = false;
+
+    if ( mImpl->boundTextures.Count() > 0u && mImpl->textureDependencyList.Count() > 0u )
+    {
+      for ( auto textureId : mImpl->textureDependencyList )
+      {
+
+        textureFound = std::find_if( mImpl->boundTextures.Begin(), mImpl->boundTextures.End(),
+                                     [textureId]( GLuint id )
+                                     {
+                                       return textureId == id;
+                                     } ) != mImpl->boundTextures.End();
+      }
+    }
+
+    if ( textureFound )
+    {
+
+      if ( !instruction.mFrameBuffer || !instruction.mFrameBuffer->IsSurfaceBacked() )
+      {
+        // For off-screen buffer
+
+        // Wait until all rendering calls for the currently context are executed
+        mImpl->glContextHelperAbstraction.WaitClient();
+
+        // Clear the dependency list
+        mImpl->textureDependencyList.Clear();
+      }
+      else
+      {
+        // For surface-backed frame buffer
+
+        // Worker thread lambda function
+        auto& glContextHelperAbstraction = mImpl->glContextHelperAbstraction;
+        auto workerFunction = [&glContextHelperAbstraction]( int workerThread )
+        {
+          // Switch to the shared context in the worker thread
+          glContextHelperAbstraction.MakeSurfacelessContextCurrent();
+
+          // Wait until all rendering calls for the shared context are executed
+          glContextHelperAbstraction.WaitClient();
+
+          // Must clear the context in the worker thread
+          // Otherwise the shared context cannot be switched to from the render thread
+          glContextHelperAbstraction.MakeContextNull();
+        };
+
+        auto future = mImpl->threadPool->SubmitTask( 0u, workerFunction );
+        if ( future )
+        {
+          mImpl->threadPool->Wait();
+
+          // Clear the dependency list
+          mImpl->textureDependencyList.Clear();
+        }
+      }
+    }
+  }
 
   if( instruction.mRenderTracker && ( instruction.mFrameBuffer != 0 ) )
   {
@@ -748,6 +856,10 @@ void RenderManager::DoRender( RenderInstruction& instruction )
   {
     surfaceFrameBuffer->PostRender();
   }
+  else
+  {
+    mImpl->currentContext->Flush();
+  }
 }
 
 } // namespace SceneGraph
index aceece5..fd3e35c 100644 (file)
@@ -33,6 +33,7 @@ namespace Integration
 {
 class GlAbstraction;
 class GlSyncAbstraction;
+class GlContextHelperAbstraction;
 class RenderStatus;
 }
 
@@ -72,13 +73,15 @@ public:
 
   /**
    * Construct a new RenderManager.
-   * @param[in]  glAbstraction           The GL abstraction used for rendering.
-   * @param[in]  glSyncAbstraction       The GL sync abstraction used fence sync creation/deletion.
-   * @param[in]  depthBufferAvailable    Whether the depth buffer is available
-   * @param[in]  stencilBufferAvailable  Whether the stencil buffer is available
+   * @param[in]  glAbstraction              The GL abstraction used for rendering.
+   * @param[in]  glSyncAbstraction          The GL sync abstraction used fence sync creation/deletion.
+   * @param[in]  glContextHelperAbstraction The GL context helper abstraction for accessing GL context.
+   * @param[in]  depthBufferAvailable       Whether the depth buffer is available
+   * @param[in]  stencilBufferAvailable     Whether the stencil buffer is available
    */
   static RenderManager* New( Integration::GlAbstraction& glAbstraction,
                              Integration::GlSyncAbstraction& glSyncAbstraction,
+                             Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
                              Integration::DepthBufferAvailable depthBufferAvailable,
                              Integration::StencilBufferAvailable stencilBufferAvailable );
 
index 2222abd..74c4959 100644 (file)
@@ -342,7 +342,7 @@ void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program
   }
 }
 
-bool Renderer::BindTextures( Context& context, Program& program )
+bool Renderer::BindTextures( Context& context, Program& program, Vector<GLuint>& boundTextures )
 {
   uint32_t textureUnit = 0;
   bool result = true;
@@ -355,6 +355,7 @@ bool Renderer::BindTextures( Context& context, Program& program )
     if( textures[i] )
     {
       result = textures[i]->Bind(context, textureUnit, samplers[i] );
+      boundTextures.PushBack( textures[i]->GetId() );
       if( result && program.GetSamplerUniformLocation( i, uniformLocation ) )
       {
         program.SetUniform1i( uniformLocation, textureUnit );
@@ -519,7 +520,8 @@ void Renderer::Render( Context& context,
                        const Matrix& viewMatrix,
                        const Matrix& projectionMatrix,
                        const Vector3& size,
-                       bool blend )
+                       bool blend,
+                       Vector<GLuint>& boundTextures )
 {
   // Get the program to use:
   Program* program = mRenderDataProvider->GetShader().GetProgram();
@@ -538,7 +540,7 @@ void Renderer::Render( Context& context,
   // Take the program into use so we can send uniforms to it
   program->Use();
 
-  if( DALI_LIKELY( BindTextures( context, *program ) ) )
+  if( DALI_LIKELY( BindTextures( context, *program, boundTextures ) ) )
   {
     // Only set up and draw if we have textures and they are all valid
 
index 66e33aa..9157d72 100755 (executable)
@@ -350,6 +350,7 @@ public:
    * @param[in] projectionMatrix The projection matrix.
    * @param[in] size Size of the render item
    * @param[in] blend If true, blending is enabled
+   * @param[in] boundTextures The textures bound for rendering
    */
   void Render( Context& context,
                BufferIndex bufferIndex,
@@ -359,7 +360,8 @@ public:
                const Matrix& viewMatrix,
                const Matrix& projectionMatrix,
                const Vector3& size,
-               bool blend );
+               bool blend,
+               Vector<GLuint>& boundTextures );
 
   /**
    * Write the renderer's sort attributes to the passed in reference
@@ -407,9 +409,10 @@ private:
    * Bind the textures and setup the samplers
    * @param[in] context The GL context
    * @param[in] program The shader program
+   * @param[in] boundTextures The textures bound for rendering
    * @return False if create or bind failed, true if success.
    */
-  bool BindTextures( Context& context, Program& program );
+  bool BindTextures( Context& context, Program& program, Vector<GLuint>& boundTextures );
 
 private:
 
index 2049620..7f1866d 100644 (file)
@@ -111,6 +111,14 @@ Context* SurfaceFrameBuffer::GetContext()
   return mContext;
 }
 
+void SurfaceFrameBuffer::MakeContextCurrent()
+{
+  if ( mSurface && !mIsSurfaceInvalid )
+  {
+    mSurface->MakeContextCurrent();
+  }
+}
+
 Integration::DepthBufferAvailable SurfaceFrameBuffer::GetDepthBufferRequired()
 {
   return mSurface && !mIsSurfaceInvalid ? Integration::DepthBufferAvailable::FALSE : mSurface->GetDepthBufferRequired();
index 7225769..704a360 100644 (file)
@@ -118,6 +118,11 @@ public:
   Context* GetContext();
 
   /**
+   * @brief Makes the graphics context current
+   */
+  void MakeContextCurrent();
+
+  /**
    * @brief Gets whether the depth buffer is required
    * @return TRUE if the depth buffer is required
    */
index 9e3120e..4e5cd51 100644 (file)
@@ -30,6 +30,7 @@ namespace Render
 TextureFrameBuffer::TextureFrameBuffer( uint32_t width, uint32_t height, Mask attachments )
 : FrameBuffer(),
   mId( 0u ),
+  mTextureId( 0u ),
   mDepthBuffer( attachments & Dali::FrameBuffer::Attachment::DEPTH ),
   mStencilBuffer( attachments & Dali::FrameBuffer::Attachment::STENCIL ),
   mWidth( width ),
@@ -83,22 +84,24 @@ void TextureFrameBuffer::AttachColorTexture( Context& context, Render::Texture*
 {
   context.BindFramebuffer( GL_FRAMEBUFFER, mId );
 
+  mTextureId = texture->GetId();
+
   // Create a color attachment.
   if( texture->GetType() == TextureType::TEXTURE_2D )
   {
     if( !texture->IsNativeImage() )
     {
-      context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetId(), mipmapLevel );
+      context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextureId, mipmapLevel );
     }
     else
     {
       // If it's a native image we need to use GL_TEXTURE_EXTERNAL_OES as the texture target parameter
-      context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, texture->GetId(), mipmapLevel );
+      context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, mTextureId, mipmapLevel );
     }
   }
   else
   {
-    context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, texture->GetId(), mipmapLevel );
+    context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, mTextureId, mipmapLevel );
   }
 
   context.BindFramebuffer( GL_FRAMEBUFFER, 0 );
index 021890f..7eecced 100644 (file)
@@ -91,9 +91,16 @@ public:
    */
   void AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer );
 
+  /**
+   * @brief Get the id of the texture binded to this frame buffer
+   * @return The texture id
+   */
+  GLuint GetTextureId() { return mTextureId; };
+
 private:
 
   GLuint mId;
+  GLuint mTextureId;
   GLuint mDepthBuffer;
   GLuint mStencilBuffer;
   uint32_t mWidth;