init glview 42/254542/1
authorDaekwang Ryu <dkdk.ryu@samsung.com>
Wed, 20 Jan 2021 10:18:48 +0000 (19:18 +0900)
committerDaekwang Ryu <dkdk.ryu@samsung.com>
Thu, 25 Feb 2021 02:06:47 +0000 (11:06 +0900)
Change-Id: I59934b5ec888b9c5085a08a7bdc79dae812c9fee

glview

Change-Id: I740061ae91b91d97c3cbc46842bdb216c0a20c74

Build OK

Change-Id: I5e437b9abede0cff92b5467a942e6d068d338391

Fix Any

Change-Id: I6c53e1afe61554afb59101142c71454975c2a70b

Clear Sample OK

Change-Id: I8a61364de45275a6c7431843697b16273e7fa2c8

Triangle sample OK

Change-Id: I6a3ca525cfbb2cb0d6e7b5967d76d02d35af92c0

13 files changed:
dali-toolkit/dali-toolkit.h
dali-toolkit/internal/controls/gl-view/gl-renderer.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/gl-renderer.h [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/public-api/controls/gl-view/gl-surface-view.cpp [new file with mode: 0644]
dali-toolkit/public-api/controls/gl-view/gl-surface-view.h [new file with mode: 0644]
dali-toolkit/public-api/file.list
docs/content/example-code/CMakeLists.txt
packaging/dali-toolkit.spec

index 26f96a69f3a0e90f4e26591041495bcfd2e7b295..75d572552b4de9e78804887af3e6f9abb6dd4a03 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/public-api/controls/flex-container/flex-container.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-surface-view.h>
 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
 #include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
 #include <dali-toolkit/public-api/controls/progress-bar/progress-bar.h>
diff --git a/dali-toolkit/internal/controls/gl-view/gl-renderer.cpp b/dali-toolkit/internal/controls/gl-view/gl-renderer.cpp
new file mode 100644 (file)
index 0000000..5a789b5
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2019 by Samsung Electronics, Inc.,
+ *
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ */
+
+// CLASS HEADER
+#include "gl-renderer.h"
+
+//INTERNAL INCLUDES
+// #include "dali-ext-dlog.h"
+// #include "rendering-behavior-manager.h"
+
+//EXTERNAL INCLUDES
+// #include <EGL/egl.h>
+// #include <EGL/eglext.h>
+// #include <GLES2/gl2.h>
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
+#include <dali/devel-api/threading/conditional-wait.h>
+// #include <tbm_dummy_display.h>
+// #include <tbm_surface_internal.h>
+// #include <tbm_surface_queue.h>
+#include <thread>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace
+{
+const unsigned int DEFAULT_SLEEP_TIME = 16u;
+}
+
+// struct EglData
+// {
+// public:
+//   EGLNativeDisplayType mNativeDisplay;
+//   tbm_surface_queue_h  mNativeWindow;
+//   EGLDisplay           mEglDisplay;
+//   EGLConfig            mEglConfig;
+//   EGLSurface           mEglSurface;
+//   EGLContext           mEglContext;
+
+//   EglData()
+//   : mNativeDisplay(NULL),
+//     mNativeWindow(NULL),
+//     mEglDisplay(EGL_NO_DISPLAY),
+//     mEglConfig(NULL),
+//     mEglSurface(EGL_NO_SURFACE),
+//     mEglContext(EGL_NO_CONTEXT)
+//   {
+//   }
+
+//   ~EglData()
+//   {
+//   }
+// };
+
+GLRenderer::GLRenderer(unsigned int viewWidth, unsigned viewHeight, tbm_surface_queue_h tbmSurfaceQueue)
+: mViewWidth(viewWidth),
+  mViewHeight(viewHeight),
+  mTbmSurfaceQueue(tbmSurfaceQueue),
+  mGLInitCallback(NULL),
+  mGLDrawCallback(NULL),
+  mGLTerminateCallback(NULL),
+  // mEglData(NULL),
+  mSleepTime(DEFAULT_SLEEP_TIME),
+  mMode(RENDER_MODE::RENDER_MODE_ONDEMAND),
+  mRenderOnce(false),
+  mPauseThread(true),
+  mQuitThread(false),
+  mGraphics(),
+  mDisplayConnection(nullptr),
+  mColorDepth(COLOR_DEPTH_24),
+  mGLInitCallback(),
+  mGLRenderFrameCallback(),
+  mGLTerminateCallback(),
+  mGLRenderCallback(nullptr),
+  mEGLSurface(nullptr),
+  mEGLContext(nullptr),
+  // mGLESVersion(Dali::GlWindow::GlesVersion::VERSION_3_0),
+  mInitCallback(false),
+  mDepth(false),
+  mStencil(false),
+  mIsEGLInitialize(false),
+  mMSAA(0)
+{
+}
+
+bool GLRenderer::InitializeEGL()
+{
+  // Init Graphics
+  std::unique_ptr<GraphicsFactory> graphicsFactoryPtr = Utils::MakeUnique<GraphicsFactory>(mEnvironmentOptions);
+  auto                             graphicsFactory    = *graphicsFactoryPtr.get();
+
+  mGraphics                      = std::unique_ptr<GraphicsInterface>(&graphicsFactory.Create());
+  GraphicsInterface* graphics    = mGraphics.get();
+  EglGraphics*       eglGraphics = static_cast<EglGraphics*>(graphics);
+  eglGraphics->Initialize(mDepth, mStencil, false, mMSAA);
+
+  mDisplayConnection = std::unique_ptr<Dali::DisplayConnection>(Dali::DisplayConnection::New(*graphics, Dali::RenderSurfaceInterface::Type::WINDOW_RENDER_SURFACE));
+  mDisplayConnection->Initialize();
+
+  Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+  // if(mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_2_0)
+  // {
+  //   eglImpl.SetGlesVersion(20);
+  // }
+  // else if(mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0)
+  // {
+  eglImpl.SetGlesVersion(30);
+  // }
+
+  if(eglImpl.ChooseConfig(true, mColorDepth) == false)
+  {
+    DALI_LOG_ERROR("InitializeGraphics: Fail to choose config");
+
+    // if(mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0)
+    // {
+    // DALI_LOG_RELEASE_INFO("InitializeGraphics: Fail to choose config with GLES30, retry with GLES20\n");
+    // eglImpl.SetGlesVersion(20);
+    // mGLESVersion = Dali::GlWindow::GlesVersion::VERSION_2_0;
+    // if(eglImpl.ChooseConfig(true, mColorDepth) == false)
+    // {
+    //   DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
+    //   return;
+    // }
+    // }
+    // else
+    // {
+    //   DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
+    //   return;
+    // }
+  }
+  eglImpl.CreateWindowContext(mEGLContext);
+  // EGLNativeWindowType window = mWindowBase->CreateEglWindow(mPositionSize.width, mPositionSize.height);
+  mEGLSurface = eglImpl.CreateSurfaceWindow(mTbmSurfaceQueue, mColorDepth);
+
+  return true;
+}
+
+void GLRenderer::DeInitializeEGL()
+{
+  // if(mEglData->mEglContext != EGL_NO_CONTEXT)
+  // {
+  //   eglDestroyContext(mEglData->mEglDisplay, mEglData->mEglContext);
+  //   mEglData->mEglContext = EGL_NO_CONTEXT;
+  // }
+
+  // if(mEglData->mEglSurface != EGL_NO_SURFACE)
+  // {
+  //   eglDestroySurface(mEglData->mEglDisplay, mEglData->mEglSurface);
+  //   mEglData->mEglSurface = EGL_NO_SURFACE;
+  // }
+
+  // eglMakeCurrent(mEglData->mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+  // if(mEglData->mEglDisplay != EGL_NO_DISPLAY)
+  // {
+  //   eglTerminate(mEglData->mEglDisplay);
+  //   mEglData->mEglDisplay = EGL_NO_DISPLAY;
+  // }
+
+  // if(mEglData->mNativeDisplay != NULL)
+  // {
+  //   tbm_dummy_display_destroy(reinterpret_cast<tbm_dummy_display*>(mEglData->mNativeDisplay));
+  //   mEglData->mNativeDisplay = NULL;
+  // }
+
+  // delete mEglData;
+  // mEglData = NULL;
+}
+
+void GLRenderer::RegisterGLCallback(GLInit glInitCallback, GLDraw glDrawCallback, GLTerminate glTerminateCallback)
+{
+  if(glInitCallback == NULL || glDrawCallback == NULL || glTerminateCallback == NULL)
+  {
+    DALI_LOG_ERROR("GLImageRender Callback is not set glInitCallback [%p] glDrawCallback[%p] glTerminateCallback[%p]",
+                   glInitCallback,
+                   glDrawCallback,
+                   glTerminateCallback);
+    return;
+  }
+
+  mGLInitCallback      = glInitCallback;
+  mGLDrawCallback      = glDrawCallback;
+  mGLTerminateCallback = glTerminateCallback;
+}
+
+void GLRenderer::SetRenderingMode(RENDER_MODE mode)
+{
+  if(mode == mMode)
+  {
+    return;
+  }
+
+  //Notify GLRender thread.
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  if(mMode == RENDER_MODE::RENDER_MODE_CONTINUOUSLY)
+  {
+    mRenderOnce = false;
+  }
+  mMode = mode;
+  mConditionalWait.Notify(updatelock);
+}
+
+void GLRenderer::RequestRender()
+{
+  if(mMode == RENDER_MODE::RENDER_MODE_CONTINUOUSLY)
+  {
+    return;
+  }
+
+  //Notify GLRender thread.
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  mRenderOnce = true;
+  mConditionalWait.Notify(updatelock);
+}
+
+void GLRenderer::Run()
+{
+  Dali::SetThreadName("GLViewRenderer");
+  bool ret = InitializeEGL();
+  if(ret == false)
+  {
+    DALI_LOG_ERROR("EGL Initilization Failed, Could not start GLRender Thread");
+    return;
+  }
+
+  bool callOnce = true;
+  bool initRet  = false;
+
+  while(1)
+  {
+    {
+      Dali::ConditionalWait::ScopedLock lock(mConditionalWait);
+      while(mPauseThread == true ||
+            (mMode == RENDER_MODE::RENDER_MODE_ONDEMAND && mRenderOnce == false))
+      {
+        mConditionalWait.Wait(lock);
+      }
+    }
+
+    if(mQuitThread)
+    {
+      DALI_LOG_ERROR("Exiting GLRender thread");
+      mGLTerminateCallback();
+      return;
+    }
+
+    auto startTime = std::chrono::steady_clock::now();
+
+    if(callOnce)
+    {
+      //Calling GLInit callback, only once.
+      initRet  = mGLInitCallback(mViewWidth, mViewHeight);
+      callOnce = false;
+    }
+
+    // Calling GLDraw callback, per frame depending on RenderMde set.
+    if(initRet == true)
+    {
+      mGLDrawCallback();
+    }
+
+    // eglSwapBuffers(mEglData->mEglDisplay, mEglData->mEglSurface);
+    GraphicsInterface*                    graphics    = mGraphics.get();
+    EglGraphics*                          eglGraphics = static_cast<EglGraphics*>(graphics);
+    Internal::Adaptor::EglImplementation& eglImpl     = eglGraphics->GetEglImplementation();
+    eglImpl->SwapBuffers(mEGLSurface);
+
+    {
+      Dali::ConditionalWait::ScopedLock updateLock(mConditionalWait);
+      if(mRenderOnce == true)
+      {
+        mRenderOnce = false;
+      }
+    }
+
+    // RenderingBehaviorManager::RequireRender();
+
+    auto endTime     = std::chrono::steady_clock::now();
+    auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
+    if(elapsedTime < mSleepTime)
+    {
+      std::this_thread::sleep_for(mSleepTime - elapsedTime);
+    }
+  }
+  return;
+}
+
+void GLRenderer::QuitRenderThread()
+{
+  mQuitThread = true;
+  // Set to come out Render Thread out of waiting condition.
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  mMode        = RENDER_MODE::RENDER_MODE_CONTINUOUSLY;
+  mPauseThread = false;
+  mConditionalWait.Notify(updatelock);
+}
+
+void GLRenderer::PauseRenderThread(bool pause)
+{
+  //Notify GLRender thread, If actor visibility is change
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  mPauseThread = pause;
+  mConditionalWait.Notify(updatelock);
+}
+
+GLRenderer::~GLRenderer()
+{
+  DeInitializeEGL();
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/gl-view/gl-renderer.h b/dali-toolkit/internal/controls/gl-view/gl-renderer.h
new file mode 100644 (file)
index 0000000..375a83a
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2019 by Samsung Electronics, Inc.,
+ *
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/thread.h>
+#include <dali/public-api/signals/callback.h>
+
+// #include <tbm_surface_queue.h>
+#include <atomic>
+#include <chrono>
+#include <memory>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+typedef bool (*GLInit)(unsigned, unsigned);
+typedef void (*GLDraw)();
+typedef void (*GLTerminate)();
+
+class GLRenderer : public Dali::Thread
+{
+public:
+  enum class RENDER_MODE
+  {
+    RENDER_MODE_CONTINUOUSLY,
+    RENDER_MODE_ONDEMAND
+  };
+  GLRenderer(unsigned int viewWidth, unsigned viewHeight, void* tbmSurfaceQueue);
+
+  virtual ~GLRenderer();
+  void RegisterGLCallback(GLInit glInitCallback, GLDraw glDrawCallback, GLTerminate glTerminateCallback);
+  void SetRenderingMode(RENDER_MODE mode);
+  void RequestRender();
+  void QuitRenderThread();
+  void PauseRenderThread(bool pause);
+
+protected:
+  virtual void Run();
+
+private:
+  GLRenderer(const GLRenderer& obj) = delete;
+  GLRenderer operator=(const GLRenderer& obj) = delete;
+
+  bool InitializeEGL();
+  void DeInitializeEGL();
+
+private:
+  unsigned mViewWidth;
+  unsigned mViewHeight;
+
+  // tbm_surface_queue_h mTbmSurfaceQueue;
+  void* mTbmSurfaceQueue;
+
+  GLInit      mGLInitCallback;
+  GLDraw      mGLDrawCallback;
+  GLTerminate mGLTerminateCallback;
+
+  Dali::ConditionalWait mConditionalWait;
+  // EglData*              mEglData;
+
+  std::chrono::milliseconds mSleepTime;
+  RENDER_MODE               mMode;
+
+  bool             mRenderOnce;
+  bool             mPauseThread;
+  std::atomic_bool mQuitThread;
+
+  std::unique_ptr<GraphicsInterface>       mGraphics; ///< Graphics interface
+  std::unique_ptr<Dali::DisplayConnection> mDisplayConnection;
+  ColorDepth                               mColorDepth;
+
+  EnvironmentOptions            mEnvironmentOptions;
+  std::unique_ptr<CallbackBase> mGLInitCallback;
+  std::unique_ptr<CallbackBase> mGLRenderFrameCallback;
+  std::unique_ptr<CallbackBase> mGLTerminateCallback;
+  CallbackBase*                 mGLRenderCallback;
+  // EGLSurface                    mEGLSurface;
+  // EGLContext                    mEGLContext;
+  void*                       mEGLSurface;
+  void*                       mEGLContext;
+  // Dali::GlWindow::GlesVersion mGLESVersion;
+  bool                        mInitCallback : 1;
+  bool                        mDepth : 1;
+  bool                        mStencil : 1;
+  bool                        mIsEGLInitialize : 1;
+  int                         mMSAA;
+};
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.cpp b/dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.cpp
new file mode 100644 (file)
index 0000000..4db99d3
--- /dev/null
@@ -0,0 +1,268 @@
+// CLASS HEADER
+#include "gl-surface-view-impl.h"
+// #include <dali-toolkit/public-api/controls/control.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
+#include <cstring>
+// #include <tbm_surface_internal.h>
+#include <tbm_surface_queue.h>
+
+// INTERNAL INCLUDES
+// #include "common-shader.h"
+// #include "dali-ext-dlog.h"
+// #include "misc.h"
+// #include "renderer-utility.h"
+// #include "rendering-behavior-manager.h"
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/any.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <dali/public-api/rendering/texture-set.h>
+#include <dali/public-api/rendering/texture.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+const char* GL_SURFACE_VIEW_SHADER_VERT_GL = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;
+  varying mediump vec2   vTexCoord;
+  uniform highp mat4     uMvpMatrix;
+  uniform highp vec3     uSize;
+  varying mediump vec2   sTexCoordRect;
+
+  void main() {
+    gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);
+    vTexCoord   = aPosition + vec2(0.5);
+  });
+
+const char* GL_SURFACE_VIEW_SHADER_FRAG_GL = DALI_COMPOSE_SHADER(
+  uniform lowp vec4          uColor;
+  varying mediump vec2       vTexCoord;
+  uniform samplerExternalOES sTexture;
+
+  void main() {
+    gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;
+  });
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+GLSurfaceView::GLSurfaceView(unsigned int viewWidth, unsigned int viewHeight)
+: Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
+  mViewWidth(viewWidth),
+  mViewHeight(viewHeight),
+  mGLRenderer(NULL),
+  mTargetSurface(NULL)
+{
+  // Add callback to pause and resume thread when application paused or resumed
+  Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
+  lifecycleController.PauseSignal().Connect(this, &GLSurfaceView::OnApplicationPaused);
+  lifecycleController.ResumeSignal().Connect(this, &GLSurfaceView::OnApplicationResumed);
+}
+
+GLSurfaceView::~GLSurfaceView()
+{
+  mGLRenderer->QuitRenderThread();
+  mGLRenderer->Join();
+  delete mGLRenderer;
+  mGLRenderer = NULL;
+
+  mTargetSurface = NULL;
+}
+
+Dali::Toolkit::GLSurfaceView GLSurfaceView::New(unsigned int viewWidth, unsigned int viewHeight)
+{
+  GLSurfaceView*               impl   = new GLSurfaceView(viewWidth, viewHeight);
+  Dali::Toolkit::GLSurfaceView handle = Dali::Toolkit::GLSurfaceView(*impl);
+  impl->Initialize();
+  return handle;
+}
+
+void GLSurfaceView::RegisterGLCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+  mGLRenderer->RegisterGLCallback(initCallback, renderFrameCallback, terminateCallback);
+}
+
+void GLSurfaceView::SetRenderingMode(Dali::Toolkit::GLSurfaceView::RENDER_MODE mode)
+{
+  mGLRenderer->SetRenderingMode(static_cast<GLRenderer::RENDER_MODE>(mode));
+}
+
+void GLSurfaceView::RequestRender()
+{
+  mGLRenderer->RequestRender();
+}
+
+void GLSurfaceView::OnInitialize()
+{
+  //making sure that RBM is initialized in main thread
+  // RenderingBehaviorManager::RequireRender();
+  CreateGLView();
+}
+
+Shader GLSurfaceView::CreateShader()
+{
+  // static const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
+
+  if(mTargetSurface)
+  {
+    std::string fragmentShader;
+
+    //Get custom fragment shader prefix
+    const char* fragmentPreFix = mTargetSurface->GetCustomFragmentPrefix();
+    if(fragmentPreFix)
+    {
+      fragmentShader = fragmentPreFix;
+      fragmentShader += GL_SURFACE_VIEW_SHADER_FRAG_GL;
+    }
+    else
+    {
+      fragmentShader = GL_SURFACE_VIEW_SHADER_FRAG_GL;
+    }
+
+    //Get custom sampler type name
+    // const char* customSamplerTypename = mTargetSurface->GetCustomSamplerTypename();
+    // if(customSamplerTypename)
+    // {
+    //   fragmentShader.replace(fragmentShader.find(DEFAULT_SAMPLER_TYPENAME), strlen(DEFAULT_SAMPLER_TYPENAME), customSamplerTypename);
+    // }
+
+    return Shader::New(GL_SURFACE_VIEW_SHADER_VERT_GL, fragmentShader);
+  }
+  else
+  {
+    return Shader::New(GL_SURFACE_VIEW_SHADER_VERT_GL, GL_SURFACE_VIEW_SHADER_FRAG_GL);
+  }
+}
+
+void GLSurfaceView::VisibilityChanged(Dali::Actor, bool visible, Dali::DevelActor::VisibilityChange::Type)
+{
+  if(Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE) == true)
+  {
+    mGLRenderer->PauseRenderThread(!visible);
+  }
+}
+
+void GLSurfaceView::OnApplicationResumed()
+{
+  if(Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE) == true)
+  {
+    mGLRenderer->PauseRenderThread(!Self().GetProperty<bool>(Actor::Property::VISIBLE));
+  }
+}
+
+void GLSurfaceView::OnApplicationPaused()
+{
+  mGLRenderer->PauseRenderThread(true);
+}
+
+void GLSurfaceView::OnSceneCallback(Actor actor)
+// void GLSurfaceView::OnSceneCallback(Actor actor UNUSED)
+{
+  mGLRenderer->PauseRenderThread(!Self().GetProperty<bool>(Actor::Property::VISIBLE));
+}
+
+void GLSurfaceView::OffSceneCallback(Actor actor)
+// void GLSurfaceView::OffSceneCallback(Actor actor UNUSED)
+{
+  mGLRenderer->PauseRenderThread(true);
+}
+
+void GLSurfaceView::AddRenderer()
+{
+  Actor self = Self();
+
+  // Geometry geometry = RendererUtility::GetInstance()->GetGeometry(RendererUtility::GeometryType::Quad);
+
+  // Shader shader = RendererUtility::GetInstance()->GetShader(RendererUtility::ShaderType::VideoImageView);
+  // if(!shader)
+  // {
+  //   shader = CreateShader();
+  //   RendererUtility::GetInstance()->SaveShader(shader, RendererUtility::ShaderType::VideoImageView);
+  // }
+  Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
+  Shader   shader   = CreateShader();
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  if(!mTargetSurface)
+  {
+    DALI_LOG_ERROR("Target Surface is NULL");
+    return;
+  }
+
+  Texture    nativeTexture = Texture::New(*mTargetSurface);
+  TextureSet textureSet    = TextureSet::New();
+  textureSet.SetTexture(0u, nativeTexture);
+
+  renderer.SetTextures(textureSet);
+  renderer.SetProperty(Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
+
+  self.AddRenderer(renderer);
+}
+
+// void GLSurfaceView::EnqueueDefaultTbmSurface(tbm_surface_queue_h tbmQueue)
+// {
+//   if(tbm_surface_queue_can_dequeue(tbmQueue, 0))
+//   {
+//     tbm_surface_h tbmSurface;
+//     if(tbm_surface_queue_dequeue(tbmQueue, &tbmSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
+//     {
+//       DALI_LOG_ERROR("Failed to dequeue a tbm_surface [%p]\n", this);
+//       return;
+//     }
+//     tbm_surface_info_s info;
+//     tbm_surface_map(tbmSurface, TBM_OPTION_WRITE, &info);
+//     memset(info.planes[0].ptr, 0x00, info.planes[0].size);
+//     tbm_surface_unmap(tbmSurface);
+//     tbm_surface_queue_enqueue(tbmQueue, tbmSurface);
+//   }
+// }
+
+void GLSurfaceView::CreateGLView()
+{
+  DALI_LOG_ERROR("DKDK CreateGLView");
+
+  mTargetSurface = Dali::NativeImageSourceQueue::New(mViewWidth, mViewHeight, Dali::NativeImageSourceQueue::COLOR_DEPTH_DEFAULT);
+  if(!mTargetSurface)
+  {
+    DALI_LOG_ERROR("NativeImageSourceQueue is NULL");
+    return;
+  }
+
+  AddRenderer();
+
+  Actor self = Self();
+  self.SetProperty(Actor::Property::SIZE, Vector2(mViewWidth, mViewHeight));
+
+  //Get the  Tbm queue, created internally by NativeImageSourceQueue.
+  tbm_surface_queue_h tbmQueue = AnyCast<tbm_surface_queue_h>(mTargetSurface->GetNativeImageSourceQueue());
+  // void* tbmQueue = AnyCast<void*>(mTargetSurface->GetNativeImageSourceQueue());
+  // void* tbmQueue = AnyCast<tbm_surface_queue_h>(mTargetSurface->GetNativeImageSourceQueue());
+
+  if(!tbmQueue)
+  {
+    DALI_LOG_ERROR("Tbm Surface queue is NULL");
+    return;
+  }
+
+  // EnqueueDefaultTbmSurface(tbmQueue);
+
+  //Create and Start Render Thread.
+  mGLRenderer = new GLRenderer(mViewWidth, mViewHeight, tbmQueue);
+  mGLRenderer->Start();
+
+  //Adding VisibilityChange Signal.
+  Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &GLSurfaceView::VisibilityChanged);
+  self.OnSceneSignal().Connect(this, &GLSurfaceView::OnSceneCallback);
+  self.OffSceneSignal().Connect(this, &GLSurfaceView::OffSceneCallback);
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.h b/dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.h
new file mode 100644 (file)
index 0000000..bd542d0
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef DALI_TOOLKIT_INTERNAL_GL_SURFACE_VIEW_H
+#define DALI_TOOLKIT_INTERNAL_GL_SURFACE_VIEW_H
+
+/*
+ * Copyright 2019 by Samsung Electronics, Inc.,
+ *
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-surface-view.h>
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/public-api/rendering/shader.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+class GLSurfaceView;
+
+namespace Internal
+{
+class GLSurfaceView : public Dali::Toolkit::Internal::Control
+{
+protected:
+  virtual ~GLSurfaceView();
+
+public:
+  /**
+   * @copydoc Dali::Toolkit::GLSurfaceView::New()
+   */
+  static Dali::Toolkit::GLSurfaceView New(unsigned int viewWidth, unsigned int viewHeight);
+
+  GLSurfaceView(unsigned int viewWidth, unsigned int viewHeight);
+
+  void RegisterGLCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+
+  void SetRenderingMode(Dali::Toolkit::GLSurfaceView::RENDER_MODE mode);
+
+  void RequestRender();
+
+private: // From Control
+  /**
+   * @copydoc Toolkit::Control::OnInitialize()
+   */
+  virtual void OnInitialize();
+
+private:
+  GLSurfaceView(const GLSurfaceView& glSurfaceView);
+
+  GLSurfaceView& operator=(const GLSurfaceView& glSurfaceView);
+
+  void CreateGLView();
+
+  Dali::Shader CreateShader();
+
+  // void EnqueueDefaultTbmSurface(tbm_surface_queue_h tbmQueue);
+
+  void VisibilityChanged(Dali::Actor, bool visible, Dali::DevelActor::VisibilityChange::Type);
+
+  void OnApplicationPaused();
+
+  void OnApplicationResumed();
+
+  void OnSceneCallback(Dali::Actor actor);
+
+  void OffSceneCallback(Dali::Actor actor);
+
+  void AddRenderer();
+
+private:
+  unsigned int mViewWidth;
+  unsigned int mViewHeight;
+
+  GLRenderer*                     mGLRenderer;
+  Dali::NativeImageSourceQueuePtr mTargetSurface;
+};
+
+} // namespace Internal
+
+inline Dali::Toolkit::Internal::GLSurfaceView& GetImpl(Dali::Toolkit::GLSurfaceView& handle)
+{
+  DALI_ASSERT_ALWAYS(handle);
+  Dali::RefObject& impl = handle.GetImplementation();
+  return static_cast<Dali::Toolkit::Internal::GLSurfaceView&>(impl);
+}
+
+inline const Dali::Toolkit::Internal::GLSurfaceView& GetImpl(const Dali::Toolkit::GLSurfaceView& handle)
+{
+  DALI_ASSERT_ALWAYS(handle);
+  const Dali::RefObject& impl = handle.GetImplementation();
+  return static_cast<const Dali::Toolkit::Internal::GLSurfaceView&>(impl);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_GL_SURFACE_VIEW_H
diff --git a/dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.cpp b/dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.cpp
new file mode 100644 (file)
index 0000000..726fdb0
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2019 by Samsung Electronics, Inc.,
+ *
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ */
+
+// CLASS HEADER
+#include "gl-surface-view-thread.h"
+
+#include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
+
+//EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/debug.h>
+#include <chrono>
+#include <thread>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace
+{
+const unsigned int DEFAULT_SLEEP_TIME = 16u;
+}
+
+GLRenderer::GLRenderer(unsigned int viewWidth, unsigned viewHeight, tbm_surface_queue_h tbmSurfaceQueue)
+: mSurface(nullptr),
+  mViewWidth(viewWidth),
+  mViewHeight(viewHeight),
+  mTbmSurfaceQueue(tbmSurfaceQueue),
+  // mGLInitCallback(NULL),
+  // mGLDrawCallback(NULL),
+  // mGLTerminateCallback(NULL),
+  mSleepTime(DEFAULT_SLEEP_TIME),
+  mMode(RENDER_MODE::RENDER_MODE_ONDEMAND),
+  mRenderOnce(false),
+  mPauseThread(true),
+  mQuitThread(false),
+  mColorDepth(Dali::NativeImageSourceQueue::COLOR_DEPTH_32),
+  // mGLInitCallback(),
+  // mGLRenderFrameCallback(),
+  // mGLTerminateCallback(),
+  // mInitCallback(false),
+  mDepth(false),
+  mStencil(false),
+  mIsEGLInitialize(false),
+  mMSAA(0)
+{
+  // bool ret = InitializeEGL();
+  // if(ret == false)
+  // {
+  //   DALI_LOG_ERROR("EGL Initilization Failed, Could not start GLRender Thread");
+  //   return;
+  // }
+}
+
+bool GLRenderer::InitializeEGL()
+{
+  DALI_LOG_ERROR("DKDK InitializeEGL()");
+
+  // TODO: Check third parameter the translucent
+  mSurface = std::unique_ptr<RenderSurfaceInterface>(CreateNativeSurface(SurfaceSize(mViewWidth, mViewHeight), mTbmSurfaceQueue, true));
+  // mSurface.get()->SetAdaptor(Dali::Adaptor::Get());
+  NativeRenderSurface* nativeSurface = dynamic_cast<NativeRenderSurface*>(mSurface.get());
+  nativeSurface->SetGLView(true);
+  nativeSurface->InitializeGraphics();
+
+  DALI_LOG_ERROR("DKDK mTbmSurfaceQueue %p, mSurface %p", mTbmSurfaceQueue, mSurface.get());
+
+  return true;
+}
+
+void GLRenderer::DeInitializeEGL()
+{
+}
+
+void GLRenderer::RegisterGLCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+  DALI_LOG_ERROR("DKDK GLRenderer::RegisterGLCallback");
+
+  if(initCallback == NULL || renderFrameCallback == NULL || terminateCallback == NULL)
+  {
+    DALI_LOG_ERROR("GLImageRender Callback is not set initCallback [%p] renderFrameCallback[%p] terminateCallback[%p]",
+                   initCallback,
+                   renderFrameCallback,
+                   terminateCallback);
+    return;
+  }
+
+  mGLInitCallback        = std::unique_ptr<CallbackBase>(initCallback);
+  mGLRenderFrameCallback = std::unique_ptr<CallbackBase>(renderFrameCallback);
+  mGLTerminateCallback   = std::unique_ptr<CallbackBase>(terminateCallback);
+}
+
+NativeRenderSurface* GLRenderer::GetNativeRenderSurface() const
+{
+  return dynamic_cast<NativeRenderSurface*>(mSurface.get());
+}
+
+void GLRenderer::SetRenderingMode(RENDER_MODE mode)
+{
+  if(mode == mMode)
+  {
+    return;
+  }
+
+  //Notify GLRender thread.
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  if(mMode == RENDER_MODE::RENDER_MODE_CONTINUOUSLY)
+  {
+    mRenderOnce = false;
+  }
+  mMode = mode;
+  mConditionalWait.Notify(updatelock);
+}
+
+void GLRenderer::RequestRender()
+{
+  if(mMode == RENDER_MODE::RENDER_MODE_CONTINUOUSLY)
+  {
+    return;
+  }
+
+  //Notify GLRender thread.
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  mRenderOnce = true;
+  mConditionalWait.Notify(updatelock);
+}
+
+void GLRenderer::Run()
+{
+  Dali::SetThreadName("DKDKGLViewRenderer");
+  DALI_LOG_ERROR("DKDK GLRenderer::Run()");
+  // DALI_LOG_ERROR("initCallback [%p] renderFrameCallback[%p] terminateCallback[%p]",
+  //                mGLInitCallback,
+  //                mGLRenderFrameCallback,
+  //                mGLTerminateCallback);
+  bool ret = InitializeEGL();
+  if(ret == false)
+  {
+    DALI_LOG_ERROR("EGL Initilization Failed, Could not start GLRender Thread");
+    return;
+  }
+
+  bool callOnce = true;
+  bool initRet  = false;
+
+  while(1)
+  {
+    {
+      Dali::ConditionalWait::ScopedLock lock(mConditionalWait);
+      while(mPauseThread == true ||
+            (mMode == RENDER_MODE::RENDER_MODE_ONDEMAND && mRenderOnce == false))
+      {
+        mConditionalWait.Wait(lock);
+      }
+    }
+
+    if(mQuitThread)
+    {
+      DALI_LOG_ERROR("Exiting GLRender thread");
+      //TODO: check callback parameter
+      CallbackBase::Execute(*mGLTerminateCallback);
+      return;
+    }
+
+    auto startTime = std::chrono::steady_clock::now();
+
+    if(callOnce)
+    {
+      //Calling GLInit callback, only once.
+      // initRet  = mGLInitCallback(mViewWidth, mViewHeight);
+      //TODO: check callback parameter
+
+      NativeRenderSurface* surface = GetNativeRenderSurface();
+
+      if(!surface)
+      {
+        return;
+      }
+      Rect<int> rect;
+      surface->PreRender(false, std::vector<Rect<int>>(), rect);
+
+      CallbackBase::Execute(*mGLInitCallback);
+
+      callOnce = false;
+      initRet  = true;
+    }
+
+    // Calling GLDraw callback, per frame depending on RenderMde set.
+    if(initRet == true)
+    {
+      NativeRenderSurface* surface = GetNativeRenderSurface();
+
+      if(!surface)
+      {
+        return;
+      }
+      // virtual bool PreRender(bool resizingSurface, const std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect) = 0;
+      Rect<int> rect;
+      surface->PreRender(false, std::vector<Rect<int>>(), rect);
+      //TODO: check callback parameter
+      CallbackBase::Execute(*mGLRenderFrameCallback);
+
+      // virtual void PostRender(bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector<Rect<int>>& damagedRects) = 0;
+
+      surface->PostRender(false, false, false, std::vector<Rect<int>>());
+    }
+
+    {
+      Dali::ConditionalWait::ScopedLock updateLock(mConditionalWait);
+      if(mRenderOnce == true)
+      {
+        mRenderOnce = false;
+      }
+    }
+
+    // RenderingBehaviorManager::RequireRender();
+
+    auto endTime     = std::chrono::steady_clock::now();
+    auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
+    if(elapsedTime < mSleepTime)
+    {
+      std::this_thread::sleep_for(mSleepTime - elapsedTime);
+    }
+  }
+  return;
+}
+
+void GLRenderer::QuitRenderThread()
+{
+  mQuitThread = true;
+  // Set to come out Render Thread out of waiting condition.
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  mMode        = RENDER_MODE::RENDER_MODE_CONTINUOUSLY;
+  mPauseThread = false;
+  mConditionalWait.Notify(updatelock);
+}
+
+void GLRenderer::PauseRenderThread(bool pause)
+{
+  //Notify GLRender thread, If actor visibility is change
+  Dali::ConditionalWait::ScopedLock updatelock(mConditionalWait);
+  mPauseThread = pause;
+  mConditionalWait.Notify(updatelock);
+}
+
+GLRenderer::~GLRenderer()
+{
+  DeInitializeEGL();
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.h b/dali-toolkit/internal/controls/gl-view/gl-surface-view-thread.h
new file mode 100644 (file)
index 0000000..da4af96
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 by Samsung Electronics, Inc.,
+ *
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/thread.h>
+#include <dali/public-api/signals/callback.h>
+#include <tbm_surface_queue.h>
+
+#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/integration-api/adaptor-framework/native-render-surface.h>
+
+// #include <tbm_surface_queue.h>
+#include <atomic>
+#include <chrono>
+#include <memory>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+typedef bool (*GLInit)(unsigned, unsigned);
+typedef void (*GLDraw)();
+typedef void (*GLTerminate)();
+
+class GLRenderer : public Dali::Thread
+{
+public:
+  enum class RENDER_MODE
+  {
+    RENDER_MODE_CONTINUOUSLY,
+    RENDER_MODE_ONDEMAND
+  };
+  GLRenderer(unsigned int viewWidth, unsigned viewHeight, tbm_surface_queue_h tbmSurfaceQueue);
+
+  virtual ~GLRenderer();
+  void RegisterGLCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+  void SetRenderingMode(RENDER_MODE mode);
+  void RequestRender();
+  void QuitRenderThread();
+  void PauseRenderThread(bool pause);
+
+protected:
+  virtual void Run();
+
+private:
+  GLRenderer(const GLRenderer& obj) = delete;
+  GLRenderer operator=(const GLRenderer& obj) = delete;
+
+  bool InitializeEGL();
+  void DeInitializeEGL();
+
+  NativeRenderSurface* GetNativeRenderSurface() const;
+
+private:
+  std::unique_ptr<Dali::RenderSurfaceInterface> mSurface; ///< The window rendering surface
+
+  unsigned mViewWidth;
+  unsigned mViewHeight;
+
+  // tbm_surface_queue_h mTbmSurfaceQueue;
+  tbm_surface_queue_h mTbmSurfaceQueue;
+
+  Dali::ConditionalWait mConditionalWait;
+  // EglData*              mEglData;
+
+  std::chrono::milliseconds mSleepTime;
+  RENDER_MODE               mMode;
+
+  bool             mRenderOnce;
+  bool             mPauseThread;
+  std::atomic_bool mQuitThread;
+
+  Dali::NativeImageSourceQueue::ColorDepth mColorDepth;
+
+  std::unique_ptr<CallbackBase> mGLInitCallback;
+  std::unique_ptr<CallbackBase> mGLRenderFrameCallback;
+  std::unique_ptr<CallbackBase> mGLTerminateCallback;
+  bool                          mInitCallback : 1;
+  bool                          mDepth : 1;
+  bool                          mStencil : 1;
+  bool                          mIsEGLInitialize : 1;
+  int                           mMSAA;
+};
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
index 1983a69f7fab359f44d4ddb10393b0bf0cbeb402..8e33264cce7bda41990b22172c509ec5c76f1ba7 100644 (file)
@@ -106,6 +106,8 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/controls/tool-bar/tool-bar-impl.cpp
    ${toolkit_src_dir}/controls/tooltip/tooltip.cpp
    ${toolkit_src_dir}/controls/video-view/video-view-impl.cpp
+   ${toolkit_src_dir}/controls/gl-view/gl-surface-view-impl.cpp
+   ${toolkit_src_dir}/controls/gl-view/gl-surface-view-thread.cpp
    ${toolkit_src_dir}/controls/web-view/web-view-impl.cpp
    ${toolkit_src_dir}/accessibility-manager/accessibility-manager-impl.cpp
 
diff --git a/dali-toolkit/public-api/controls/gl-view/gl-surface-view.cpp b/dali-toolkit/public-api/controls/gl-view/gl-surface-view.cpp
new file mode 100644 (file)
index 0000000..d862d1f
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 by Samsung Electronics, Inc.,
+ *
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ */
+
+// CLASS HEADER
+#include "gl-surface-view.h"
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/gl-surface-view-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+GLSurfaceView::GLSurfaceView()
+{
+}
+
+GLSurfaceView::GLSurfaceView(const GLSurfaceView& glSurfaceView)
+: Control(glSurfaceView)
+{
+}
+
+GLSurfaceView& GLSurfaceView::operator=(const GLSurfaceView& glSurfaceView)
+{
+  if(&glSurfaceView != this)
+  {
+    Control::operator=(glSurfaceView);
+  }
+
+  return *this;
+}
+
+GLSurfaceView::~GLSurfaceView()
+{
+}
+
+GLSurfaceView GLSurfaceView::New(unsigned int viewWidth, unsigned int viewHeight)
+{
+  return Internal::GLSurfaceView::New(viewWidth, viewHeight);
+}
+
+void GLSurfaceView::RegisterGLCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+  Dali::Toolkit::GetImpl(*this).RegisterGLCallback(initCallback, renderFrameCallback, terminateCallback);
+}
+
+void GLSurfaceView::SetRenderingMode(RENDER_MODE mode)
+{
+  Dali::Toolkit::GetImpl(*this).SetRenderingMode(mode);
+}
+
+void GLSurfaceView::RequestRender()
+{
+  Dali::Toolkit::GetImpl(*this).RequestRender();
+}
+
+GLSurfaceView::GLSurfaceView(Internal::GLSurfaceView& implementation)
+: Control(implementation)
+{
+}
+
+GLSurfaceView::GLSurfaceView(Dali::Internal::CustomActor* internal)
+: Control(internal)
+{
+  VerifyCustomActorPointer<Internal::GLSurfaceView>(internal);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/public-api/controls/gl-view/gl-surface-view.h b/dali-toolkit/public-api/controls/gl-view/gl-surface-view.h
new file mode 100644 (file)
index 0000000..3d9c5e6
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef DALI_TOOLKIT_GL_SURFACE_VIEW_H
+#define DALI_TOOLKIT_GL_SURFACE_VIEW_H
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal DALI_INTERNAL
+{
+class GLSurfaceView;
+}
+
+typedef bool (*GLInit)(unsigned, unsigned);
+typedef void (*GLDraw)();
+typedef void (*GLTerminate)();
+
+class DALI_IMPORT_API GLSurfaceView : public Dali::Toolkit::Control
+{
+public:
+  enum class RENDER_MODE
+  {
+    RENDER_MODE_CONTINUOUSLY,
+    RENDER_MODE_ONDEMAND
+  };
+  /**
+   * @brief Creates an initialized GLSurfaceView.
+   * @return A handle to a newly allocated Dali GLSurfaceView
+   * @param[in] viewWidth Framebuffer Width
+   * @param[in] viewHeight Framebuffer Height
+   * @note GLSurfaceView will not display anything
+   */
+  static GLSurfaceView New(unsigned int viewWidth, unsigned int viewHeight);
+
+  /**
+   * @brief Creates an uninitialized GLSurfaceView.
+   */
+  GLSurfaceView();
+
+  /**
+   * @brief Destructor.
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~GLSurfaceView();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] GLSurfaceView GLSurfaceView to copy. The copied GLSurfaceView will point at the same implementation
+   */
+  GLSurfaceView(const GLSurfaceView& GLSurfaceView);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] GLSurfaceView The GLSurfaceView to assign from
+   * @return The updated GLSurfaceView
+   */
+  GLSurfaceView& operator=(const GLSurfaceView& GLSurfaceView);
+
+  /**
+   * @brief sets GLInit and GLDraw callbacks
+   * GLInit is called only once after Egl initilization is completed.
+   * GLDraw is called per frame, depending on Rendering Mode set.
+   * GLTerminate is called only once, This callback can be by user for egl resource cleanup
+   * Both, user callbacks are called in GLSurfaceView thread.
+   *
+   * @param [in] GLInit callback
+   * @param [in] GLDraw callback
+   * @param [in] glTerminateCallback callback
+   */
+  void RegisterGLCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+
+  /**
+   * @brief Set the rendering mode
+   * When mode is RENDER_MODE_CONTINUOUSLY, the GLDraw callback is called repeatedly.
+   * When renderMode is RENDER_MODE_ONDEMAND, the GLDraw callback is called when requestRender() is called.
+   * Defaults to RENDER_MODE_ONDEMAND.
+   *
+   * @param [in] rendering mode.
+   */
+  void SetRenderingMode(RENDER_MODE mode);
+
+  /**
+   * @brief Request render frame on demand.
+   * This method is typically used when the render mode has been set to RENDER_MODE_ONDEMAND.
+   */
+  void RequestRender();
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Creates a handle using the Toolkit::Internal implementation.
+   *
+   * @param[in] implementation The GLSurfaceView implementation
+   */
+  DALI_INTERNAL GLSurfaceView(Internal::GLSurfaceView& implementation);
+
+  /**
+   * @brief Allows the creation of this GLSurfaceView from an Internal::CustomActor pointer.
+   *
+   * @param[in] internal A pointer to the internal CustomActor
+   */
+  DALI_INTERNAL GLSurfaceView(Dali::Internal::CustomActor* internal);
+  /// @endcond
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_GL_SURFACE_VIEW_H
index df039c8ed3a4cf1d5be1b945a5b338b0da858791..77954e243117360d41eb4b4d8f142a212e2104b7 100644 (file)
@@ -26,6 +26,7 @@ SET( public_api_src_files
   ${public_api_src_dir}/controls/text-controls/text-label.cpp
   ${public_api_src_dir}/controls/text-controls/text-field.cpp
   ${public_api_src_dir}/controls/video-view/video-view.cpp
+  ${public_api_src_dir}/controls/gl-view/gl-surface-view.cpp
   ${public_api_src_dir}/image-loader/image.cpp
   ${public_api_src_dir}/image-loader/async-image-loader.cpp
   ${public_api_src_dir}/image-loader/sync-image-loader.cpp
@@ -127,6 +128,10 @@ SET( public_api_video_view_header_files
   ${public_api_src_dir}/controls/video-view/video-view.h
 )
 
+SET( public_api_gl_surface_view_header_files
+  ${public_api_src_dir}/controls/gl-view/gl-surface-view.h
+)
+
 SET( public_api_visuals_header_files
   ${public_api_src_dir}/visuals/border-visual-properties.h
   ${public_api_src_dir}/visuals/color-visual-properties.h
@@ -160,5 +165,6 @@ SET( PUBLIC_API_HEADERS ${PUBLIC_API_HEADERS}
   ${public_api_focus_manager_header_files}
   ${public_api_text_header_files}
   ${public_api_video_view_header_files}
+  ${public_api_gl_surface_view_header_files}
   ${public_api_visuals_header_files}
 )
index 133ab593f9c7b23ef4c18809ea3d58883f4416ee..dd45360ff76226cfd8c1c880aa0c8f913c9db4ce 100644 (file)
@@ -2,7 +2,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 
 SET(PKG_LIST dali-core
              dali-adaptor
-             dali-toolkit)
+             dali-toolkit
+             libtbm)
 INCLUDE(FindPkgConfig)
 PKG_CHECK_MODULES(REQUIRED_PKGS REQUIRED ${PKG_LIST})
 
index 58a827792f159ac8c3e97dbd2364e9a846ba3c1d..d102b6789c0f07c3dda7965e9a14e4235acadb0b 100644 (file)
@@ -16,6 +16,8 @@ BuildRequires:  pkgconfig(dali2-core)
 BuildRequires:  pkgconfig(dali2-adaptor)
 BuildRequires:  gettext
 BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(libtbm)
+
 
 #############################
 # profile setup