[macos] Prevent race condition while creating the EGL Window 24/250924/2
authorWander Lairson Costa <wander.lairson@gmail.com>
Tue, 29 Sep 2020 18:50:49 +0000 (15:50 -0300)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 5 Jan 2021 21:10:33 +0000 (21:10 +0000)
eglCreateWindowSurface must the called before the CAlayer is initialized
in the run loop. We we StartRender (which does nothing) to synchronize
the graphics initialization in the Render Thread with the main thread.

Change-Id: I85be6682ec8a25672a548cf085ef15500cd2993f

dali/internal/adaptor/common/combined-update-render-controller.cpp
dali/internal/window-system/file.list
dali/internal/window-system/macos/render-surface-factory-mac.cpp
dali/internal/window-system/macos/window-render-surface-cocoa.cpp [new file with mode: 0644]
dali/internal/window-system/macos/window-render-surface-cocoa.h [new file with mode: 0644]

index 818b4f0..1b9e11f 100644 (file)
@@ -178,18 +178,18 @@ void CombinedUpdateRenderController::Start()
     mEventThreadSemaphore.Acquire();
   }
 
-  Dali::RenderSurfaceInterface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
-  if( currentSurface )
-  {
-    currentSurface->StartRender();
-  }
-
   mRunning = TRUE;
 
   LOG_EVENT( "Startup Complete, starting Update/Render Thread" );
 
   RunUpdateRenderThread( CONTINUOUS, AnimationProgression::NONE, UpdateMode::NORMAL );
 
+  Dali::RenderSurfaceInterface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
+  if( currentSurface )
+  {
+    currentSurface->StartRender();
+  }
+
   DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Start\n" );
 }
 
index 8a8bccd..4f7b234 100644 (file)
@@ -71,6 +71,7 @@ SET( adaptor_window_system_windows_src_files
 SET( adaptor_window_system_macos_src_files
     ${adaptor_window_system_dir}/macos/display-connection-factory-mac.cpp
     ${adaptor_window_system_dir}/macos/display-connection-impl-mac.cpp
+    ${adaptor_window_system_dir}/macos/window-render-surface-cocoa.cpp
     ${adaptor_window_system_dir}/macos/window-system-mac.mm
     ${adaptor_window_system_dir}/macos/window-base-mac.mm
     ${adaptor_window_system_dir}/macos/window-factory-mac.cpp
index caa386e..1c76cf4 100644 (file)
@@ -25,7 +25,7 @@
 #include <dali/integration-api/adaptor-framework/native-render-surface.h>
 #include <dali/internal/window-system/common/display-utils.h>
 #include <dali/internal/window-system/common/pixmap-render-surface.h>
-#include <dali/internal/window-system/common/window-render-surface.h>
+#include "window-render-surface-cocoa.h"
 
 namespace Dali::Internal::Adaptor
 {
@@ -37,7 +37,7 @@ RenderSurfaceFactoryCocoa::CreateWindowRenderSurface(
   bool isTransparent
 )
 {
-  return Utils::MakeUnique< WindowRenderSurface >( positionSize, surface, isTransparent );
+  return Utils::MakeUnique< WindowRenderSurfaceCocoa >( positionSize, surface, isTransparent );
 }
 
 std::unique_ptr< PixmapRenderSurface >
diff --git a/dali/internal/window-system/macos/window-render-surface-cocoa.cpp b/dali/internal/window-system/macos/window-render-surface-cocoa.cpp
new file mode 100644 (file)
index 0000000..90d0d0d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 "window-render-surface-cocoa.h"
+
+namespace Dali::Internal::Adaptor
+{
+WindowRenderSurfaceCocoa::WindowRenderSurfaceCocoa(Dali::PositionSize positionSize, Any surface, bool isTransparent)
+  : WindowRenderSurface(positionSize, surface, isTransparent)
+  , mReady(false)
+{
+}
+
+void WindowRenderSurfaceCocoa::StartRender()
+{
+  std::unique_lock<std::mutex> lock(mCondMutex);
+  WindowRenderSurface::StartRender();
+  while (!mReady)
+  {
+    mRenderWait.wait(lock);
+  }
+}
+
+void WindowRenderSurfaceCocoa::CreateSurface()
+{
+  std::lock_guard<std::mutex> lock(mCondMutex);
+  WindowRenderSurface::CreateSurface();
+  mReady = true;
+  mRenderWait.notify_all();
+}
+} // Dali::Internal::Adaptor
diff --git a/dali/internal/window-system/macos/window-render-surface-cocoa.h b/dali/internal/window-system/macos/window-render-surface-cocoa.h
new file mode 100644 (file)
index 0000000..7e573a4
--- /dev/null
@@ -0,0 +1,57 @@
+#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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <mutex>
+#include <condition_variable>
+
+// INTERNAL INCLUDES
+#include <dali/internal/window-system/common/window-render-surface.h>
+
+namespace Dali::Internal::Adaptor
+{
+/**
+ * We must create the EGL Window before we enter the run loop.
+ * This specialization ensures this condition is respected.
+ */
+class WindowRenderSurfaceCocoa : public WindowRenderSurface
+{
+public:
+
+  /**
+   * @copydoc Dali::WindowRenderSurface()
+   */
+  WindowRenderSurfaceCocoa(Dali::PositionSize positionSize, Any surface, bool isTransparent = true);
+
+  /**
+   * @copydoc Dali::RenderSurfaceInterface::StartRender()
+   */
+  void StartRender() override;
+
+  /**
+   * @copydoc Dali::RenderSurfaceInterface::CreateSurface()
+   */
+  void CreateSurface() override;
+
+private:
+  std::mutex mCondMutex;
+  std::condition_variable mRenderWait;
+  bool mReady;
+};
+} // Dali::Internal::Adaptor