utc-Dali-ControlWrapper.cpp
utc-Dali-DragAndDropDetector.cpp
utc-Dali-NPatchUtilities.cpp
+ utc-Dali-GlView.cpp
)
# List of test harness files (Won't get parsed for test cases)
FocusChangeSignalType mFocusChangeSignal;
ResizeSignalType mResizeSignal;
int mRotationAngle;
+ bool mVisible;
DevelWindow::VisibilityChangedSignalType mVisibilityChangedSignal;
};
mFocusChangeSignal(),
mResizeSignal(),
mRotationAngle(90), // dummy angle for test coverage
+ mVisible(true),
mVisibilityChangedSignal()
{
}
void Window::Hide()
{
GetImplementation( *this ).mVisibilityChangedSignal.Emit( *this, false );
+ GetImplementation( *this ).mVisible = false;
+}
+
+bool Window::IsVisible() const
+{
+ return GetImplementation( *this ).mVisible;
}
FocusChangeSignalType& Window::FocusChangeSignal()
Vector4 GetBackgroundColor() const;
void Raise();
void Hide();
+ bool IsVisible() const;
FocusChangeSignalType& FocusChangeSignal();
KeyEventSignalType& KeyEventSignal();
TouchEventSignalType& TouchedSignal();
--- /dev/null
+/*
+ * 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.
+ * 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 <unistd.h>
+#include <thread>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+// Positive test case for a method
+int UtcDaliGlViewNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliGlViewNew");
+ GlView view = GlView::New(GlView::ColorFormat::RGBA8888);
+ DALI_TEST_CHECK( view );
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliGlViewDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliGlViewDownCast");
+
+ GlView view = GlView::New(GlView::ColorFormat::RGB888);
+ BaseHandle handle(view);
+
+ Toolkit::GlView view2 = Toolkit::GlView::DownCast( handle );
+ DALI_TEST_CHECK( view );
+ DALI_TEST_CHECK( view2 );
+ DALI_TEST_CHECK( view == view2 );
+ END_TEST;
+}
+
+int UtcDaliGlViewCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewCopyAndAssignment");
+
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+ DALI_TEST_CHECK( view );
+
+ GlView copy( view );
+ DALI_TEST_CHECK( view == copy );
+
+ GlView assign;
+ DALI_TEST_CHECK( !assign );
+
+ assign = copy;
+ DALI_TEST_CHECK( assign == view );
+
+ END_TEST;
+}
+
+int UtcDaliGlViewMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewMoveAssignment");
+
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+ DALI_TEST_EQUALS( 1, view.GetBaseObject().ReferenceCount(), TEST_LOCATION );
+
+ GlView moved;
+ moved = std::move( view );
+ DALI_TEST_CHECK( moved );
+ DALI_TEST_EQUALS( 1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION );
+ DALI_TEST_CHECK( !view );
+
+ END_TEST;
+}
+
+int UtcDaliGlViewSetGraphicsConfigGles20N(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewSetGraphicsConfigGles20");
+ GlView view;
+ try
+ {
+ view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+ DALI_TEST_CHECK(false);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
+
+int UtcDaliGlViewSetGraphicsConfigGles30(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewSetGraphicsConfigGles30");
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+
+ try
+ {
+ view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_3_0);
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false);
+ }
+ END_TEST;
+}
+
+int UtcDaliGlViewRenderingMode(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewRenderingMode");
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+
+ view.SetRenderingMode(GlView::RenderingMode::ON_DEMAND);
+
+ GlView::RenderingMode mode = view.GetRenderingMode();
+
+ DALI_TEST_EQUALS( GlView::RenderingMode::ON_DEMAND, mode, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliGlViewOnSizeSet(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewOnSizeSet");
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+
+
+ application.GetScene().Add( view );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 size( 200.0f, 300.0f, 0.0f );
+ view.SetProperty( Actor::Property::SIZE, size );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( view.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ), size, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+// Internal callback function
+void glInit(void)
+{
+}
+
+int glRenderFrame(void)
+{
+ static unsigned int retFlag = 0;
+ return retFlag++;
+}
+
+void glTerminate(void)
+{
+}
+
+void resizeCB(Vector2 size)
+{
+}
+
+int UtcDaliGlViewRegisterGlCallbackN(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewRegisterGlCallback");
+ GlView view;
+
+ try
+ {
+ view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ DALI_TEST_CHECK(false);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
+
+int UtcDaliGlViewSetResizeCallbackN(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewSetResizeCallback");
+ GlView view;
+
+ try
+ {
+ view.SetResizeCallback(Dali::MakeCallback(resizeCB));
+ DALI_TEST_CHECK(false);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
+
+int UtcDaliGlViewRenderOnce(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewRenderOnce");
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+
+ try
+ {
+ view.RenderOnce();
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false);
+ }
+ END_TEST;
+}
+
+int UtcDaliGlViewWindowVisibilityChanged(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewWindowVisibilityChanged");
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+ application.GetScene().Add( view );
+ view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
+ view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+ view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ view.SetResizeCallback(Dali::MakeCallback(resizeCB));
+
+ application.SendNotification();
+ application.Render();
+
+ Window window = DevelWindow::Get( view );
+ window.Hide();
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(true);
+ END_TEST;
+}
+
+int UtcDaliGlViewOnScene(void)
+{
+ ToolkitTestApplication application;
+
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+
+ //Onscene
+ application.GetScene().Add( view );
+ view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
+ view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+ view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+
+ application.SendNotification();
+ application.Render();
+
+ //Offscene
+ application.GetScene().Remove(view);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(true);
+ END_TEST;
+}
+
+int UtcDaliGlViewControlVisibilityChanged(void)
+{
+ ToolkitTestApplication application;
+
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+ application.GetScene().Add( view );
+
+ application.SendNotification();
+ application.Render();
+
+ view.SetProperty( Actor::Property::VISIBLE, false );
+ application.SendNotification();
+ application.Render();
+ DALI_TEST_CHECK(view.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == false);
+
+ view.SetProperty( Actor::Property::VISIBLE, true );
+ application.SendNotification();
+ application.Render();
+ DALI_TEST_CHECK(view.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == true);
+
+ END_TEST;
+}
+
+int UtcDaliGlViewResize(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliGlViewResize");
+ GlView view = Toolkit::GlView::New(GlView::ColorFormat::RGB888);
+
+ application.GetScene().Add( view );
+ view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
+ view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ view.SetResizeCallback(Dali::MakeCallback(resizeCB));
+ view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ view.SetProperty(Actor::Property::SIZE, Vector2(360.0f, 360.0f));
+
+ application.SendNotification();
+ application.Render();
+
+ //To GlViewRenderThread can recognize Resize signal the main thread have to sleep.
+ std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(true);
+ END_TEST;
+}
#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-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>
--- /dev/null
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/gl-view/gl-view-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/devel-api/rendering/renderer-devel.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>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+Dali::Toolkit::GlView GlView::New(Dali::Toolkit::GlView::ColorFormat colorFormat)
+{
+ GlView* impl = new GlView(colorFormat);
+ Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
+ impl->Initialize();
+ return handle;
+}
+
+GlView::GlView(Dali::Toolkit::GlView::ColorFormat colorFormat)
+: Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
+ mRenderThread(nullptr),
+ mNativeImageQueue(nullptr),
+ mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
+ mColorFormat(colorFormat),
+ mDepth(false),
+ mStencil(false),
+ mMSAA(0)
+{
+}
+
+GlView::~GlView()
+{
+ if(mRenderThread)
+ {
+ mRenderThread->Stop();
+ mRenderThread->Join();
+ }
+}
+
+void GlView::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+ if(mRenderThread)
+ {
+ mRenderThread->RegisterGlCallback(initCallback, renderFrameCallback, terminateCallback);
+ }
+}
+
+void GlView::SetResizeCallback(CallbackBase* resizeCallback)
+{
+ if(mRenderThread)
+ {
+ mRenderThread->SetResizeCallback(resizeCallback);
+ }
+}
+
+bool GlView::SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version)
+{
+ // Init Graphics
+ mDepth = depth;
+ mStencil = stencil;
+ mMSAA = msaa;
+
+ int rVersion;
+
+ if(version == Dali::Toolkit::GlView::GraphicsApiVersion::GLES_VERSION_2_0)
+ {
+ rVersion = 20;
+ }
+ else
+ {
+ rVersion = 30;
+ }
+
+ if(mRenderThread)
+ {
+ return mRenderThread->SetGraphicsConfig(depth, stencil, msaa, rVersion);
+ }
+
+ return false;
+}
+
+void GlView::SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode)
+{
+ mRenderingMode = mode;
+ Renderer renderer = Self().GetRendererAt(0);
+
+ if(mRenderingMode == Dali::Toolkit::GlView::RenderingMode::ON_DEMAND)
+ {
+ renderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
+
+ if(mRenderThread)
+ {
+ mRenderThread->SetOnDemandRenderMode(true);
+ }
+ }
+ else
+ {
+ renderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
+
+ if(mRenderThread)
+ {
+ mRenderThread->SetOnDemandRenderMode(false);
+ }
+ }
+}
+
+Dali::Toolkit::GlView::RenderingMode GlView::GetRenderingMode() const
+{
+ return mRenderingMode;
+}
+
+void GlView::RenderOnce()
+{
+ if(mRenderThread)
+ {
+ mRenderThread->RenderOnce();
+ }
+}
+
+void GlView::OnInitialize()
+{
+ //Create NativeImageSourceQueue with the size of 1,1
+ mNativeImageQueue = Dali::NativeImageSourceQueue::New(1, 1, GetColorFormat(mColorFormat));
+
+ if(!mNativeImageQueue)
+ {
+ DALI_LOG_ERROR("NativeImageSourceQueue is NULL");
+ return;
+ }
+
+ AddRenderer();
+
+ Actor self = Self();
+
+ //Create a RenderThread
+ mRenderThread = std::unique_ptr<GlViewRenderThread>(new GlViewRenderThread(mNativeImageQueue));
+ if(!mRenderThread)
+ {
+ DALI_LOG_ERROR("Fail to create GlView Render Thread!!!!\n");
+ return;
+ }
+
+ //Adding VisibilityChange Signal.
+ Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &GlView::OnControlVisibilityChanged);
+}
+
+void GlView::OnSizeSet(const Vector3& targetSize)
+{
+ Control::OnSizeSet(targetSize);
+
+ if(mRenderThread)
+ {
+ if(mNativeImageQueue)
+ {
+ mRenderThread->AcquireSurface();
+ mNativeImageQueue->SetSize(static_cast<uint32_t>(targetSize.x), static_cast<uint32_t>(targetSize.y));
+ mRenderThread->SetSurfaceSize(Vector2(targetSize.x, targetSize.y));
+ mRenderThread->ReleaseSurface();
+ }
+ }
+}
+
+Shader GlView::CreateShader()
+{
+ std::string fragmentShader = std::string(SHADER_GL_VIEW_FRAG);
+
+ if(mNativeImageQueue)
+ {
+ mNativeImageQueue->ApplyNativeFragmentShader(fragmentShader);
+ }
+
+ return Shader::New(SHADER_GL_VIEW_VERT, fragmentShader);
+}
+
+void GlView::OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type)
+{
+ Actor self = Self();
+ if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+ {
+ if(mRenderThread)
+ {
+ if(visible && DevelWindow::Get(self).IsVisible())
+ {
+ mRenderThread->Resume();
+ }
+ else
+ {
+ mRenderThread->Pause();
+ }
+ }
+ }
+}
+
+void GlView::OnWindowVisibilityChanged(Window window, bool visible)
+{
+ if(mRenderThread)
+ {
+ if(visible && Self().GetProperty<bool>(Actor::Property::VISIBLE))
+ {
+ mRenderThread->Resume();
+ }
+ else
+ {
+ mRenderThread->Pause();
+ }
+ }
+}
+
+void GlView::OnSceneConnection(int depth)
+{
+ Control::OnSceneConnection(depth);
+
+ Actor self = Self();
+ Window window = DevelWindow::Get(self);
+
+ if(window)
+ {
+ DevelWindow::VisibilityChangedSignal(window).Connect(this, &GlView::OnWindowVisibilityChanged);
+ }
+
+ if(mRenderThread)
+ {
+ if(self.GetProperty<bool>(Actor::Property::VISIBLE) && window.IsVisible())
+ {
+ mRenderThread->Resume();
+ }
+ }
+}
+
+void GlView::OnSceneDisconnection()
+{
+ Control::OnSceneDisconnection();
+ if(mRenderThread)
+ {
+ mRenderThread->Pause();
+ }
+}
+
+Dali::Geometry GlView::CreateTexturedQuad()
+{
+ struct Vertex
+ {
+ Dali::Vector2 position;
+ };
+
+ static const Vertex data[] = {{Dali::Vector2(-0.5f, -0.5f)},
+ {Dali::Vector2(0.5f, -0.5f)},
+ {Dali::Vector2(-0.5f, 0.5f)},
+ {Dali::Vector2(0.5f, 0.5f)}};
+
+ uint32_t numberOfVertices = sizeof(data) / sizeof(Vertex);
+
+ Dali::VertexBuffer vertexBuffer;
+ Dali::Property::Map vertexFormat;
+ vertexFormat["aPosition"] = Dali::Property::VECTOR2;
+
+ //Create a vertex buffer for vertex positions and texture coordinates
+ vertexBuffer = Dali::VertexBuffer::New(vertexFormat);
+ vertexBuffer.SetData(data, numberOfVertices);
+
+ //Create the geometry
+ Dali::Geometry geometry = Dali::Geometry::New();
+ geometry.AddVertexBuffer(vertexBuffer);
+ geometry.SetType(Dali::Geometry::TRIANGLE_STRIP);
+
+ return geometry;
+}
+
+void GlView::AddRenderer()
+{
+ if(!mNativeImageQueue)
+ {
+ DALI_LOG_ERROR("Target Surface is NULL");
+ return;
+ }
+
+ Actor self = Self();
+ Geometry geometry = CreateTexturedQuad();
+ Shader shader = CreateShader();
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ Texture nativeTexture = Texture::New(*mNativeImageQueue);
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture(0u, nativeTexture);
+
+ renderer.SetTextures(textureSet);
+
+ self.AddRenderer(renderer);
+}
+
+Dali::NativeImageSourceQueue::ColorFormat GlView::GetColorFormat(Dali::Toolkit::GlView::ColorFormat format)
+{
+ switch(format)
+ {
+ case Toolkit::GlView::ColorFormat::RGBA8888:
+ {
+ return Dali::NativeImageSourceQueue::ColorFormat::RGBA8888;
+ }
+
+ case Toolkit::GlView::ColorFormat::RGB888:
+ default:
+ {
+ return Dali::NativeImageSourceQueue::ColorFormat::RGBX8888;
+ }
+ }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_GL_VIEW_H
+#define DALI_TOOLKIT_INTERNAL_GL_VIEW_H
+
+/*
+ * 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.
+ * 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 <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/public-api/adaptor-framework/window.h>
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/shader.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/gl-view-render-thread.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+class GlView;
+
+namespace Internal
+{
+class GlView : public Dali::Toolkit::Internal::Control
+{
+protected:
+ virtual ~GlView();
+
+public:
+ /**
+ * @copydoc Dali::Toolkit::GlView::New()
+ */
+ static Dali::Toolkit::GlView New(Dali::Toolkit::GlView::ColorFormat colorFormat);
+
+ /**
+ * Construct a new GlView.
+ */
+ GlView(Dali::Toolkit::GlView::ColorFormat colorFormat);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::RegisterGlCallback()
+ */
+ void RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::SetResizeCallback()
+ */
+ void SetResizeCallback(CallbackBase* resizeCallback);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::SetGraphisConfig()
+ */
+ bool SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::SetRenderingMode()
+ */
+ void SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::GetRenderingMode()
+ */
+ Dali::Toolkit::GlView::RenderingMode GetRenderingMode() const;
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::RenderOnce()
+ */
+ void RenderOnce();
+
+private: // From Control
+ /**
+ * @copydoc Toolkit::Control::OnInitialize()
+ */
+ virtual void OnInitialize() override;
+
+ /**
+ * @copydoc Toolkit::Control::OnSceneConnection()
+ */
+ void OnSceneConnection(int depth) override;
+
+ /**
+ * @copydoc Toolkit::Control::OnSceneDisconnection()
+ */
+ void OnSceneDisconnection() override;
+
+ /**
+ * @copydoc Toolkit::Control::OnSizeSet()
+ */
+ void OnSizeSet(const Vector3& targetSize) override;
+
+private:
+ // Undefined copy constructor and assignment operators
+ GlView(const GlView& GlView);
+ GlView& operator=(const GlView& GlView);
+
+ /**
+ * Callback when the visibility of the GlView is changed
+ */
+ void OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type);
+
+ /**
+ * Callback when the visibility of the window is changed
+ */
+ void OnWindowVisibilityChanged(Dali::Window window, bool visible);
+
+ /**
+ * Creates the geometry for texturing.
+ */
+ Dali::Geometry CreateTexturedQuad();
+
+ /**
+ * Adds renderer to Actor.
+ */
+ void AddRenderer();
+
+ /**
+ * Creates shader for rendering.
+ */
+ Dali::Shader CreateShader();
+
+ /**
+ * @brief Gets the NativeImageSourceQueue's ColorFormat with the GlView's ColorFormat.
+ * @param[in] colorFormat the color format of the GlView.
+ * @return The color format of NativeImageSourceQueue
+ */
+ Dali::NativeImageSourceQueue::ColorFormat GetColorFormat(Dali::Toolkit::GlView::ColorFormat format);
+
+private:
+ std::unique_ptr<GlViewRenderThread> mRenderThread;
+ Dali::NativeImageSourceQueuePtr mNativeImageQueue;
+ Dali::Toolkit::GlView::RenderingMode mRenderingMode;
+ Dali::Toolkit::GlView::ColorFormat mColorFormat;
+
+ bool mDepth;
+ bool mStencil;
+ int mMSAA;
+};
+
+} // namespace Internal
+
+inline Dali::Toolkit::Internal::GlView& GetImpl(Dali::Toolkit::GlView& handle)
+{
+ DALI_ASSERT_ALWAYS(handle);
+ Dali::RefObject& impl = handle.GetImplementation();
+ return static_cast<Dali::Toolkit::Internal::GlView&>(impl);
+}
+
+inline const Dali::Toolkit::Internal::GlView& GetImpl(const Dali::Toolkit::GlView& handle)
+{
+ DALI_ASSERT_ALWAYS(handle);
+ const Dali::RefObject& impl = handle.GetImplementation();
+ return static_cast<const Dali::Toolkit::Internal::GlView&>(impl);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_GL_VIEW_H
--- /dev/null
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/gl-view/gl-view-render-thread.h>
+
+//EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.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
+{
+constexpr unsigned int NANOSECONDS_PER_SECOND(1e+9);
+
+// The following values will get calculated at compile time
+constexpr float DEFAULT_FRAME_DURATION_IN_SECONDS(1.0f / 60.0f);
+constexpr uint64_t DEFAULT_FRAME_DURATION_IN_NANOSECONDS(DEFAULT_FRAME_DURATION_IN_SECONDS* NANOSECONDS_PER_SECOND);
+
+} // namespace
+
+GlViewRenderThread::GlViewRenderThread(Dali::NativeImageSourceQueuePtr queue)
+: mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
+ mSurfaceSize(1, 1),
+ mNativeImageSurface(),
+ mNativeImageQueue(queue),
+ mSurfaceSemaphore(1),
+ mGlInitCallback(nullptr),
+ mGlRenderFrameCallback(nullptr),
+ mGlTerminateCallback(nullptr),
+ mResizeCallback(nullptr),
+ mDepth(false),
+ mStencil(false),
+ mMSAA(0),
+ mGraphicsApiVersion(20),
+ mConditionalWait(),
+ mIsThreadStarted(0),
+ mIsThreadStopped(0),
+ mIsThreadPaused(0),
+ mIsRenderRequested(0),
+ mRenderingMode(0),
+ mIsSurfaceResized(0),
+ mDefaultFrameDurationNanoseconds(DEFAULT_FRAME_DURATION_IN_NANOSECONDS)
+{
+ mNativeImageSurface = Dali::NativeImageSurface::New(mNativeImageQueue);
+
+ if(!mNativeImageSurface)
+ {
+ DALI_LOG_ERROR("Creating NativeImageSurface Failed, Could not start GlView Render Thread");
+ }
+}
+
+void GlViewRenderThread::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+ if(!mGlInitCallback && !mGlRenderFrameCallback && !mGlTerminateCallback)
+ {
+ mGlInitCallback = std::unique_ptr<CallbackBase>(initCallback);
+ mGlRenderFrameCallback = std::unique_ptr<CallbackBase>(renderFrameCallback);
+ mGlTerminateCallback = std::unique_ptr<CallbackBase>(terminateCallback);
+ }
+}
+
+void GlViewRenderThread::SetResizeCallback(CallbackBase* resizeCallback)
+{
+ if(!mResizeCallback)
+ {
+ mResizeCallback = std::unique_ptr<CallbackBase>(resizeCallback);
+ }
+}
+
+bool GlViewRenderThread::SetGraphicsConfig(bool depth, bool stencil, int msaa, int version)
+{
+ mDepth = depth;
+ mStencil = stencil;
+ mMSAA = msaa;
+ mGraphicsApiVersion = version;
+
+ if(mNativeImageSurface)
+ {
+ return mNativeImageSurface->SetGraphicsConfig(mDepth, mStencil, mMSAA, mGraphicsApiVersion);
+ }
+
+ return false;
+}
+
+void GlViewRenderThread::SetOnDemandRenderMode(bool onDemand)
+{
+ ConditionalWait::ScopedLock lock(mConditionalWait);
+ mRenderingMode = static_cast<unsigned int>(onDemand);
+ DALI_LOG_RELEASE_INFO("GlViewRenderThread::SetOnDemandRenderMode(): mRenderingMode: %d\n", mRenderingMode);
+ if(!onDemand && !mIsThreadPaused)
+ {
+ mConditionalWait.Notify(lock);
+ }
+}
+
+void GlViewRenderThread::SetSurfaceSize(Dali::Vector2 size)
+{
+ //GlViewRenderThread::Run was already blocked in Internal::GlView::OnSizeSet
+ mSurfaceSize = size;
+ mIsSurfaceResized = 1;
+}
+
+void GlViewRenderThread::RenderOnce()
+{
+ //Notify GLRender thread.
+ Dali::ConditionalWait::ScopedLock lock(mConditionalWait);
+ mIsRenderRequested = 1;
+ mConditionalWait.Notify(lock);
+}
+
+void GlViewRenderThread::GetNanoSeconds(uint64_t& timeInNanoseconds)
+{
+ // Get the time of a monotonic clock since its epoch.
+ auto epoch = std::chrono::steady_clock::now().time_since_epoch();
+ auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(epoch);
+ timeInNanoseconds = static_cast<uint64_t>(duration.count());
+}
+
+void GlViewRenderThread::SleepUntil(uint64_t timeInNanoseconds)
+{
+ using Clock = std::chrono::steady_clock;
+ using TimePoint = std::chrono::time_point<Clock>;
+
+ const Clock::duration duration = std::chrono::nanoseconds(timeInNanoseconds);
+ const TimePoint timePoint(duration);
+
+ std::this_thread::sleep_until(timePoint);
+}
+
+void GlViewRenderThread::Run()
+{
+ Dali::SetThreadName("GlViewRenderer");
+ mLogFactory.InstallLogFunction();
+
+ int renderFrameResult = 0;
+
+ if(!mNativeImageSurface)
+ {
+ DALI_LOG_ERROR("NativeImageSurface is null, Could not start GlView Render Thread");
+ return;
+ }
+
+ AcquireSurface();
+ mNativeImageSurface->InitializeGraphics();
+ ReleaseSurface();
+
+ mNativeImageSurface->PreRender();
+ if(mGlInitCallback)
+ {
+ CallbackBase::Execute(*mGlInitCallback);
+ }
+
+ uint64_t timeToSleepUntil = 0;
+
+ while(RenderReady(timeToSleepUntil))
+ {
+ uint64_t currentFrameStartTime = 0;
+ GetNanoSeconds(currentFrameStartTime);
+
+ AcquireSurface();
+ mNativeImageSurface->PreRender();
+ if(mIsSurfaceResized)
+ {
+ if(mResizeCallback)
+ {
+ CallbackBase::Execute(*mResizeCallback, static_cast<int>(mSurfaceSize.x), static_cast<int>(mSurfaceSize.y));
+ }
+ mIsSurfaceResized = 0;
+ }
+
+ if(mNativeImageSurface->CanRender())
+ {
+ if(mGlRenderFrameCallback)
+ {
+ renderFrameResult = CallbackBase::ExecuteReturn<int>(*mGlRenderFrameCallback);
+ if(renderFrameResult)
+ {
+ mNativeImageSurface->PostRender();
+ }
+ }
+ }
+
+ ReleaseSurface();
+
+ if(timeToSleepUntil == 0)
+ {
+ timeToSleepUntil = currentFrameStartTime + mDefaultFrameDurationNanoseconds;
+ }
+ else
+ {
+ timeToSleepUntil += mDefaultFrameDurationNanoseconds;
+ uint64_t currentFrameEndTime = 0;
+ GetNanoSeconds(currentFrameEndTime);
+ while(currentFrameEndTime > timeToSleepUntil + mDefaultFrameDurationNanoseconds)
+ {
+ timeToSleepUntil += mDefaultFrameDurationNanoseconds;
+ }
+ }
+
+ SleepUntil(timeToSleepUntil);
+ }
+
+ if(mGlTerminateCallback)
+ {
+ CallbackBase::Execute(*mGlTerminateCallback);
+ }
+
+ mNativeImageSurface->TerminateGraphics();
+
+ return;
+}
+
+void GlViewRenderThread::Stop()
+{
+ // Set to come out Render Thread out of waiting condition.
+ Dali::ConditionalWait::ScopedLock lock(mConditionalWait);
+ mIsThreadStopped = 1;
+ mIsThreadPaused = 0;
+ mConditionalWait.Notify(lock);
+}
+
+void GlViewRenderThread::Pause()
+{
+ //Notify GLRender thread, If actor visibility is change
+ Dali::ConditionalWait::ScopedLock lock(mConditionalWait);
+ mIsThreadPaused = 1;
+ mConditionalWait.Notify(lock);
+}
+
+void GlViewRenderThread::Resume()
+{
+ Dali::ConditionalWait::ScopedLock lock(mConditionalWait);
+ if(!mIsThreadStarted)
+ {
+ Start();
+ mIsThreadStarted = 1;
+ }
+ mIsThreadPaused = 0;
+ mConditionalWait.Notify(lock);
+}
+
+bool GlViewRenderThread::RenderReady(uint64_t& timeToSleepUntil)
+{
+ ConditionalWait::ScopedLock lock(mConditionalWait);
+ while((!mIsThreadStopped && mRenderingMode && !mIsRenderRequested) || mIsThreadPaused)
+ {
+ timeToSleepUntil = 0;
+ mConditionalWait.Wait(lock);
+ }
+
+ mIsRenderRequested = 0;
+ // Keep the update-render thread alive if this thread is NOT to be destroyed
+ return !mIsThreadStopped;
+}
+
+void GlViewRenderThread::AcquireSurface()
+{
+ mSurfaceSemaphore.Acquire();
+}
+
+void GlViewRenderThread::ReleaseSurface()
+{
+ mSurfaceSemaphore.Release(1);
+}
+
+GlViewRenderThread::~GlViewRenderThread()
+{
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_GL_VIEW_THREAD_H
+#define DALI_TOOLKIT_INTERNAL_GL_VIEW_THREAD_H
+
+/*
+ * 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.
+ * 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 <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/semaphore.h>
+#include <dali/devel-api/threading/thread.h>
+#include <dali/integration-api/adaptor-framework/log-factory-interface.h>
+#include <dali/integration-api/adaptor-framework/native-image-surface.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/signals/callback.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+/**
+ * @brief GlViewRenderThread is a render thread for GlView.
+ * This invokes user's callbacks.
+ */
+class GlViewRenderThread : public Dali::Thread
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param[in] queue The NativeImageSourceQueue that GL renders onto
+ */
+ GlViewRenderThread(Dali::NativeImageSourceQueuePtr queue);
+
+ /**
+ * destructor.
+ */
+ virtual ~GlViewRenderThread();
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::RegisterGlCallback()
+ */
+ void RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::SetResizeCallback()
+ */
+ void SetResizeCallback(CallbackBase* resizeCallback);
+
+ /**
+ * @copydoc Dali::Toolkit::GlView::SetGraphicsConfig()
+ */
+ bool SetGraphicsConfig(bool depth, bool stencil, int msaa, int version);
+
+ /**
+ * Enable OnDemand Rendering Mode
+ *
+ * @param[in] onDemand the flag of OnDemand Rendering Mode. If the flag is true, the rendering mode is set OnDemand,
+ * otherwise the flag is false, rendering mode is set continuous mode.
+ */
+ void SetOnDemandRenderMode(bool onDemand);
+
+ /**
+ * Sets the surface size
+ *
+ * @param[in] size the size of the NaitveImageSurface
+ */
+ void SetSurfaceSize(Dali::Vector2 size);
+
+ /**
+ * @copydoc Dali::Toolkit::RenderOnce()
+ */
+ void RenderOnce();
+
+ /**
+ * Pauses the render thread.
+ */
+ void Pause();
+
+ /**
+ * Resumes the render thread.
+ */
+ void Resume();
+
+ /**
+ * Stops the render thread.
+ * @note Should only be called in Stop as calling this will kill the render thread.
+ */
+ void Stop();
+
+ /**
+ * Acquires the surface resource
+ */
+ void AcquireSurface();
+
+ /**
+ * Releases the surface resource
+ */
+ void ReleaseSurface();
+
+protected:
+ /**
+ * The routine that the thread will execute once it is started.
+ */
+ void Run() override;
+
+private:
+ GlViewRenderThread(const GlViewRenderThread& obj) = delete;
+ GlViewRenderThread operator=(const GlViewRenderThread& obj) = delete;
+
+ /**
+ * Called by the Render Thread which ensures a wait if required.
+ *
+ * @param[out] timeToSleepUntil The time remaining in nanoseconds to keep the thread sleeping before resuming.
+ * @return false, if the thread should stop.
+ */
+ bool RenderReady(uint64_t& timeToSleepUntil);
+
+ /**
+ * @brief Get the monotonic time since the clock's epoch.
+ * @param[out] timeInNanoseconds The time in nanoseconds since the reference point.
+ */
+ void GetNanoSeconds(uint64_t& timeInNanoseconds);
+
+ /**
+ * Blocks the execution of the current thread until specified sleep_time
+ * @param[in] timeInNanoseconds The time blocking for
+ */
+ void SleepUntil(uint64_t timeInNanoseconds);
+
+private:
+ const Dali::LogFactoryInterface& mLogFactory;
+ Dali::Vector2 mSurfaceSize; ///< The size of mNativeImageQueue
+ Dali::NativeImageSurfacePtr mNativeImageSurface;
+ Dali::NativeImageSourceQueuePtr mNativeImageQueue;
+ Semaphore<> mSurfaceSemaphore; ///< The semaphore to avoid race condition to the render target
+
+ std::unique_ptr<CallbackBase> mGlInitCallback;
+ std::unique_ptr<CallbackBase> mGlRenderFrameCallback;
+ std::unique_ptr<CallbackBase> mGlTerminateCallback;
+ std::unique_ptr<CallbackBase> mResizeCallback;
+
+ bool mDepth : 1;
+ bool mStencil : 1;
+ int mMSAA;
+ int mGraphicsApiVersion;
+
+ Dali::ConditionalWait mConditionalWait;
+ volatile unsigned int mIsThreadStarted; ///< Whether this thread has been started.
+ volatile unsigned int mIsThreadStopped; ///< Stop render thread. It means this render thread will be destroyed.
+ volatile unsigned int mIsThreadPaused; ///< Sleep render thread by pause.
+ volatile unsigned int mIsRenderRequested; ///< Request rendering once
+ volatile unsigned int mRenderingMode; ///< Rendering Mode, 0: Continuous, 1:OnDemand
+ volatile unsigned int mIsSurfaceResized; ///< Invoke ResizeCallback when NativeImageSurface is resized.
+
+ uint64_t mDefaultFrameDurationNanoseconds; ///< Default duration of a frame (used for sleeping if not enough time elapsed). Not protected by lock, but written to rarely so not worth adding a lock when reading.
+};
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_GL_SURFACE_VIEW_THREAD_H
${toolkit_src_dir}/controls/video-view/video-view-impl.cpp
${toolkit_src_dir}/controls/web-view/web-view-impl.cpp
${toolkit_src_dir}/controls/camera-view/camera-view-impl.cpp
+ ${toolkit_src_dir}/controls/gl-view/gl-view-impl.cpp
+ ${toolkit_src_dir}/controls/gl-view/gl-view-render-thread.cpp
${toolkit_src_dir}/accessibility-manager/accessibility-manager-impl.cpp
${toolkit_src_dir}/feedback/feedback-style.cpp
--- /dev/null
+uniform lowp vec4 uColor;
+varying mediump vec2 vTexCoord;
+uniform samplerExternalOES sTexture;
+
+void main()
+{
+ gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;
+}
\ No newline at end of file
--- /dev/null
+attribute mediump vec2 aPosition;
+uniform mediump mat4 uMvpMatrix;
+uniform mediump vec3 uSize;
+varying mediump vec2 vTexCoord;
+
+void main()
+{
+ vec4 position = vec4(aPosition, 0.0, 1.0) * vec4(uSize, 1.0);
+ vTexCoord = aPosition + vec2(0.5);
+ gl_Position = uMvpMatrix * position;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/controls/gl-view/gl-view.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/gl-view/gl-view-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+GlView::GlView()
+{
+}
+
+GlView::GlView(const GlView& GlView) = default;
+
+GlView::GlView(GlView&& rhs) = default;
+
+GlView& GlView::operator=(const GlView& GlView) = default;
+
+GlView& GlView::operator=(GlView&& rhs) = default;
+
+GlView::~GlView()
+{
+}
+
+GlView GlView::New(ColorFormat colorFormat)
+{
+ return Internal::GlView::New(colorFormat);
+}
+
+GlView GlView::DownCast(BaseHandle handle)
+{
+ return Control::DownCast<GlView, Internal::GlView>(handle);
+}
+
+void GlView::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+{
+ Dali::Toolkit::GetImpl(*this).RegisterGlCallback(initCallback, renderFrameCallback, terminateCallback);
+}
+
+void GlView::SetResizeCallback(CallbackBase* resizeCallback)
+{
+ Dali::Toolkit::GetImpl(*this).SetResizeCallback(resizeCallback);
+}
+
+bool GlView::SetGraphicsConfig(bool depth, bool stencil, int msaa, GraphicsApiVersion version)
+{
+ return Dali::Toolkit::GetImpl(*this).SetGraphicsConfig(depth, stencil, msaa, version);
+}
+
+void GlView::SetRenderingMode(RenderingMode mode)
+{
+ Dali::Toolkit::GetImpl(*this).SetRenderingMode(mode);
+}
+
+Dali::Toolkit::GlView::RenderingMode GlView::GetRenderingMode() const
+{
+ return Dali::Toolkit::GetImpl(*this).GetRenderingMode();
+}
+
+void GlView::RenderOnce()
+{
+ Dali::Toolkit::GetImpl(*this).RenderOnce();
+}
+
+GlView::GlView(Internal::GlView& implementation)
+: Control(implementation)
+{
+}
+
+GlView::GlView(Dali::Internal::CustomActor* internal)
+: Control(internal)
+{
+ VerifyCustomActorPointer<Internal::GlView>(internal);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_GL_VIEW_H
+#define DALI_TOOLKIT_GL_VIEW_H
+/*
+ * 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.
+ * 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-toolkit/public-api/controls/control.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal DALI_INTERNAL
+{
+class GlView;
+}
+
+/**
+ * @brief GlView is a class for rendering with GL
+ *
+ * GlView allows drawing with OpenGL.
+ * GlView creates a GL context, a GL surface and a render thread.
+ * The render thread invokes user's callbacks.
+ *
+ */
+class DALI_TOOLKIT_API GlView : public Dali::Toolkit::Control
+{
+public:
+ /**
+ * @brief Enumeration for rendering mode
+ *
+ * This Enumeration is used to choose the rendering mode.
+ * It has two options.
+ * One of them is continuous mode. It is rendered continuously.
+ * The other is on demand mode. It is rendered by application.
+ */
+ enum class RenderingMode
+ {
+ CONTINUOUS, ///< continuous mode
+ ON_DEMAND ///< on demand by application
+ };
+
+ /**
+ * @brief Enumeration for Graphics API version
+ *
+ * This Enumeration is used to set a GLES version for EGL configuration.
+ */
+ enum class GraphicsApiVersion
+ {
+ GLES_VERSION_2_0 = 0, ///< GLES version 2.0
+ GLES_VERSION_3_0, ///< GLES version 3.0
+ };
+
+ /**
+ * @brief Enumeration for color buffer format
+ *
+ * This Enumeration is used to set a color buffer format of GlView
+ */
+ enum class ColorFormat
+ {
+ RGB888, ///< 8 red bits, 8 green bits, 8 blue bits
+ RGBA8888 ///< 8 red bits, 8 green bits, 8 blue bits, alpha 8 bits
+ };
+
+ /**
+ * @brief Creates a GlView control.
+ * @param[in] colorFormat the format of the color buffer.
+ * @return A handle to a GlView control
+ */
+ static GlView New(ColorFormat colorFormat);
+
+ /**
+ * @brief Creates an uninitialized GlView.
+ */
+ GlView();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~GlView();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param[in] GlView GlView to copy. The copied GlView will point at the same implementation
+ */
+ GlView(const GlView& GlView);
+
+ /**
+ * @brief Move constructor
+ *
+ * @param[in] rhs A reference to the moved handle
+ */
+ GlView(GlView&& rhs);
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @param[in] GlView The GlView to assign from
+ * @return A reference to this
+ */
+ GlView& operator=(const GlView& GlView);
+
+ /**
+ * @brief Move assignment
+ *
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ GlView& operator=(GlView&& rhs);
+
+ /**
+ * @brief Downcasts a handle to GlView handle.
+ *
+ * If handle points to a GlView, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @param[in] handle Handle to an object
+ * @return Handle to a GlView or an uninitialized handle
+ */
+ static GlView DownCast(BaseHandle handle);
+
+ /**
+ * @brief Registers GL callback functions for GlView.
+ *
+ * @param[in] initCallback the callback function to create GL resources.
+ * @param[in] renderFrameCallback the callback function to render for the frame.
+ * @param[in] terminateCallback the callback function to clean-up GL resources.
+ *
+ * A initCallback of the following type have to be used:
+ * @code
+ * void intializeGL();
+ * @endcode
+ * This callback will be called before renderFrame callback is called once.
+ *
+ * A renderFrameCallback of the following type have to be used:
+ * @code
+ * int renderFrameGL();
+ * @endcode
+ * If the return value of this callback is not 0, the eglSwapBuffers() will be called.
+ *
+ * A terminateCallback of the following type have to be used:
+ * @code
+ * void terminateGL();
+ * @endcode
+ * This callback is called when GlView is deleted.
+ *
+ * @note Ownership of the callbacks is passed onto this class.
+ * <b>You can't call Dali APIs in your callbacks because it is invoked in GlView's own render thread.</b>
+ * And this must be called before adding GlView to the scene.
+ */
+ void RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+
+ /**
+ * @brief Sets the ResizeCallback of the GlView.
+ * When GlView is resized, ResizeCallback would be invoked.
+ * You can get the resized width and height of the GlView.
+ *
+ * @param[in] resizeCallback The ResizeCallback function
+ *
+ * A resizeCallback of the following type have to be used:
+ * @code
+ * void resizeCallback(int width, int height);
+ * @endcode
+ *
+ * @note Ownership of the callback is passed onto this class.
+ * <b>You can't call Dali APIs in your callback because it is invoked in GlView's own render thread.</b>
+ * And this must be called before adding GlView to the scene.
+ */
+ void SetResizeCallback(CallbackBase* resizeCallback);
+
+ /**
+ * @brief Sets the rendering mode.
+ *
+ * @param[in] mode the rendering mode for GlView
+ *
+ * @note The default Rendering mode is CONTINUOUS.
+ * If ON_DEMAND mode is set, it is rendered by RenderOnce()
+ */
+ void SetRenderingMode(RenderingMode mode);
+
+ /**
+ * @brief Gets the rendering mode.
+ */
+ RenderingMode GetRenderingMode() const;
+
+ /**
+ * @brief Sets egl configuration for GlView
+ *
+ * @param[in] depth the flag of depth buffer. If the value is true, 24bit depth buffer is enabled.
+ * @param[in] stencil the flag of stencil. If the value is true, 8bit stencil buffer is enabled.
+ * @param[in] msaa the expected sampling number per pixel.
+ * @param[in] version the graphics API version
+ * @return True if the config exists, false otherwise.
+ */
+ bool SetGraphicsConfig(bool depth, bool stencil, int msaa, GraphicsApiVersion version);
+
+ /**
+ * @brief Renders once more even if GL render functions are not added to idler.
+ * @note Will not work if the window is hidden or GL render functions are added to idler
+ */
+ void RenderOnce();
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ * @param[in] implementation The GlView implementation
+ */
+ DALI_INTERNAL GlView(Internal::GlView& implementation);
+
+ /**
+ * @brief Allows the creation of this GlView from an Internal::CustomActor pointer.
+ * @param[in] internal A pointer to the internal CustomActor
+ */
+ DALI_INTERNAL GlView(Dali::Internal::CustomActor* internal);
+ /// @endcond
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_GL_VIEW_H
${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/camera-view/camera-view.cpp
+ ${public_api_src_dir}/controls/gl-view/gl-view.cpp
${public_api_src_dir}/image-loader/image.cpp
${public_api_src_dir}/image-loader/image-url.cpp
${public_api_src_dir}/image-loader/async-image-loader.cpp
${public_api_src_dir}/controls/camera-view/camera-view.h
)
+SET( public_api_gl_view_header_files
+ ${public_api_src_dir}/controls/gl-view/gl-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
${public_api_video_view_header_files}
${public_api_visuals_header_files}
${public_api_camera_view_header_files}
+ ${public_api_gl_view_header_files}
)